Wednesday, April 21, 2010

Linux Shell script to find the process listening on a given port

port=$1
procinfo=$(netstat --numeric-ports -nlp 2> /dev/null grep ^tcp grep -w ${port} tail -n 1 awk '{print $7}')
case "${procinfo}" in
"")
echo "No process listening on port ${port}"
;;
"-")
echo "Process is running on ${port}, but current user does not have rights to see process information."
;;
*)
echo "${procinfo} is running on port ${port}"
ps -uwep ${procinfo%%/*}
;;
esac

Wednesday, February 10, 2010

Ctrl-S hanged vi editor

This has been the standard almost since the beginning of time.

Ctrl S is the XOFF character, uses for flow control on serial links that do not have hardware flow control. It doesn't freeze the output...
Receipt of the XON character (Ctrl Q) disables the flow control, and commands output to continue.

Saturday, August 15, 2009

MTOM/XOP and performance improvements in CXF

Message Transmission Optimization Mechanism (MTOM) is a core feature of web service engine. CXF supports MTOM with XOP.

Brief description about MTOM/XOP in SOAP:

In standard SOAP messages, binary objects are base64-encoded and included in the message body. This increases their size by 33%, which for very large binary objects can significantly impact transmission time. The SOAP Message Transmission Optimization Mechanism (MTOM) and XML-binary Optimized Packaging (XOP) specifications, define a method for optimizing the transmission of large base64Binary data objects within SOAP messages:

XOP is used as the referencing mechanism in the serialised XML infoset. In theory, the abstract MTOM model could be used with a different referencing mechanism and/or different container format, over a different transport protocol instead of HTTP. In practice, MTOM is usually used with XOP, MIME and HTTP.

In MTOM, an Optimized MIME Multipart/Related Serialization of SOAP Messages is defined that summarises that the serialized XML infoset will include XML-binary Optimized Packaging (XOP) in place of the binary data, and the binary data (along with the serialized XML infoset with XOP placeholders) will be represented together in a MIME container.

Performance issue description: In CXF 2.0.7, MTOM performance was poor. In the initial set of tests I had done, For a 12 MB of data, it was taking around 1.2-1.4 seconds. Pretty Slow compared to other WS stacks MTOM performance.

Sharing approach: We intergrated CXF in Pramati Java EE 1.5 application server. I delved into this, firstly removed all in and out application server's (web container streams). removed out CXF Interceptors to finally come to the one which composes and decomposes MTOM SOAP message, to finally arrive at MimeBodyPartInputStream, PushbackInputStream.

MimeBodyPartInputStream doesn't implements read(byte[]) method, hence it delegates it to parent InputStream class. InputStream's read(byte[]) runs over a loop, eventually delegating to PushBackInputStream, which reads a single byte and performs boundary matching over that Byte.

A simple test program which takes the time taken by the MimeBodyPartInputStream to read from a loaded buffer shows that MimeBodyPartInputStream takes ~1200-1400 ms to read a 12MB buffer. On the other hand, an InputStream takes around ~100-150ms to do so. Yes, that's obvious as we all understand that MimeBodyPartInputStream has the logic of detecting a probable boundary and it performs multiple if checks to do so, also it calls read and unread over PushBackInputStream. But again considering number of the reads and unreads also, the time of MimeBodyPartInputStream looked poor.

An alternative implementation of MimeBodyPartInputStream which added dynamic buffer creation, buffer used for forward-backward index movement, and implements read(byte[] buffer, int off, int len) helped me to solve the performance problem. The functionality of reading the buffer, matching the process boundary is now performed by it.

The performance counters after the changes were (12 MB of data):

1. ~1578 ms (current CXF MBPIS)
2. ~172 ms (just read raw 12MB data)
3. ~188 ms (new CXF MBPIS)

They look more encouraging, sensible and charming :)

So next time you use MTOM feature in any CXF releases 2.0.10 or 2.1.4 after, you will get better performance.

In case you want to see the changes, they are below,

Index: trunk/rt/core/src/main/java/org/apache/cxf/attachment/MimeBodyPartInputStream.java
===================================================================
diff -u -N -r651669 -r718620
--- trunk/rt/core/src/main/java/org/apache/cxf/attachment/MimeBodyPartInputStream.java  
(.../branches/2.0.x-fixes/rt/core/src/main/java/org/apache/cxf/attachment/MimeBodyPartInputStream.java)  (revision 651669)
+++ trunk/rt/core/src/main/java/org/apache/cxf/attachment/MimeBodyPartInputStream.java  
(.../trunk/rt/core/src/main/java/org/apache/cxf/attachment/MimeBodyPartInputStream.java)  (revision 718620)
@@ -28,15 +28,159 @@
     PushbackInputStream inStream;
 
     boolean boundaryFound;
-
+    int pbAmount;
     byte[] boundary;
+    byte[] boundaryBuffer;
 
-    public MimeBodyPartInputStream(PushbackInputStream inStreamParam, byte[] boundaryParam) {
+    public MimeBodyPartInputStream(PushbackInputStream inStreamParam, 
+                                   byte[] boundaryParam,
+                                   int pbsize) {
         super();
         this.inStream = inStreamParam;
         this.boundary = boundaryParam;
+        this.pbAmount = pbsize;
     }
 
+    public int read(byte buf[], int origOff, int origLen) throws IOException {
+        byte b[] = buf;
+        int off = origOff;
+        int len = origLen;
+        if (boundaryFound) {
+            return -1;
+        }
+        if ((off < 0) || (off > b.length) || (len < 0) 
+            || ((off + len) > b.length) || ((off + len) < 0)) {
+
+            throw new IndexOutOfBoundsException();
+        }
+        if (len == 0) {
+            return 0;
+        }
+        boolean bufferCreated = false;
+        if (len < boundary.length * 2) {
+            //buffer is too short to detect boundaries with it.  We'll need to create a larger buffer   
+            bufferCreated = true;
+            if (boundaryBuffer == null) {
+                boundaryBuffer = new byte[boundary.length * 2];
+            }
+            b = boundaryBuffer;
+            off = 0;
+            len = boundaryBuffer.length;
+        }
+        if (len > pbAmount) {
+            len = pbAmount;  //can only pushback that much so make sure we can
+        }
+        if (len > 0) {
+            len = inStream.read(b, off, len);
+        }
+        int i = processBuffer(b, off, len);
+        if (bufferCreated && i > 0) {
+            // read more than we need, push it back
+            if (origLen >= i) {
+                System.arraycopy(b, 0, buf, origOff, i);
+            } else {
+                System.arraycopy(b, 0, buf, origOff, origLen);
+                inStream.unread(b, origLen, i - origLen);
+                i = origLen;
+            }
+        } else if (i == 0 && boundaryFound) {
+            return -1;
+        }
+        return i;
+    }
+
+    //Has Data after encountering CRLF
+    private boolean hasData(byte[] b, int initialPointer, int pointer, int off, int len)
+        throws IOException {
+        if (pointer < (off + len)) {
+            return true;
+        } else {
+            inStream.unread(b, initialPointer, (off + len) - initialPointer);
+            return false;
+        }
+    }
+
+    protected int processBuffer(byte[] buffer, int off, int len) throws IOException {
+        for (int i = off; i < (off + len); i++) {
+            boolean needUnread0d0a = false;
+            int value = buffer[i];
+            int initialI = i;
+            if (value == 13) {
+                if (!hasData(buffer, initialI, initialI + 1, off, len)) {
+                    return initialI - off;
+                }
+                value = buffer[initialI + 1];
+                if (value != 10) {
+                    continue;
+                } else {  //if it comes here then 13, 10 are values and will try to match boundaries
+                    if (!hasData(buffer, initialI, initialI + 2, off, len)) {
+                        return initialI - off;
+                    }
+                    value = buffer[initialI + 2];
+                    if ((byte) value != boundary[0]) {
+                        i++;
+                        continue;
+                    } else { //13, 10, boundaries first value matched
+                        needUnread0d0a = true;
+                        i += 2; //i after this points to boundary[0] element
+                    }
+                }
+            } else if (value != boundary[0]) {
+                continue;
+            }
+
+            int boundaryIndex = 0;
+            while ((boundaryIndex < boundary.length) && (value == boundary[boundaryIndex])) {
+                if (!hasData(buffer, initialI, i + 1, off, len)) {
+                    return initialI - off;
+                }                
+                value = buffer[++i];
+                boundaryIndex++;
+            }
+            if (boundaryIndex == boundary.length) {
+                // read the end of line character
+                if (initialI != off) {
+                    i = 1000000000;
+                }
+                if (!hasData(buffer, initialI, i + 1, off, len)) {
+                    return initialI - off;
+                }
+                boundaryFound = true;
+                int j = i + 1;
+                if (j < len && buffer[j] == 45 && value == 45) {
+                    // Last mime boundary should have a succeeding "--"
+                    // as we are on it, read the terminating CRLF
+                    i += 2;
+                    //last mime boundary
+                }
+
+                //boundary matched (may or may not be last mime boundary)
+                int processed = initialI - off;
+                if ((len - (i + 2)) > 0) {
+                    inStream.unread(buffer, i + 2, len - (i + 2));
+                }
+                return processed;
+            }
+
+            // Boundary not found. Restoring bytes skipped.
+            // write first skipped byte, push back the rest
+            if (value != -1) { //pushing back first byte of boundary
+                // Stream might have ended
+                i--;
+            }
+            if (needUnread0d0a) { //Pushing all,  returning 13
+                i = i - boundaryIndex;
+                i--; //for 10
+                value = 13;
+            } else {
+                i = i - boundaryIndex;
+                i++;
+                value = boundary[0];
+            }
+        }
+        return len;
+    }
+
     public int read() throws IOException {
         boolean needUnread0d0a = false;
         if (boundaryFound) {
@@ -77,8 +221,9 @@
         if (boundaryIndex == boundary.length) {
             // boundary found
             boundaryFound = true;
+            int dashNext = inStream.read();
             // read the end of line character
-            if (inStream.read() == 45 && value == 45) {
+            if (dashNext == 45 && value == 45) {
                 // Last mime boundary should have a succeeding "--"
                 // as we are on it, read the terminating CRLF
                 inStream.read();

Monday, July 06, 2009

Examples of WS-Security using CXF and WSS4J

If you are searching for some simple examples to understand and write WS-Security stuff (UsernameToken, Timestamp, Signature or Encryption) actions. I filed a jira task on JIRA, made some examples and Dan committed them in the svn. You can get them in CXF 2.2.3 distribution.
You can check the following (all included Timestamp action):

To get more detailed description about how it all works you can read this Configuring CXF for WS-Security... . I hope your initial queries, doubts while creating and understanding startup examples of WS-Security using CXF and WSS4J will be answered there :)

Monday, May 18, 2009

Specifying WS-SecurityPolicy, RM, Policy in a WSDL file

WS-Policy provides a way for the provider of a web service to convey conditions under which it provides the service. A invoker might use this policy to decide whether to use or not to use the service.WS-Policy just gives basic assertion support like, <wsp:all></wsp:all>, <wsp:exactlyone></wsp:exactlyone>to express one set of policy or alternatives too. Any conditions/requirements as assertions under <wsp:all></wsp:all>become mandatory,where as assertions inside <wsp:exactlyone></wsp:exactlyone>are considered as alternatives to each other.You can read more about various combinations/interactions/alternative in OASIS WS-PolicySpecification[1].


  • You can specify these WS-Poilcy assertions either inside input , output,fault, operation, port, or in binding wsdl elements.
  • You can either put them directly as child elements of them, or else you can refer them using <wsp:PolicyReference> element.

Policy can be attached as described by WS-PolicyAttached [4] at following levels:

  • Service Level: {Applied at <wsdl:Service>} - A policy associated with a service policy subject applies to any message exchange using any of the endpoints offered by that service.

  • Endpoint Level: {Applied at <wsdl:port> or <wsdl:portType> or <wsdl:binding>} - Since <wsdl:portType> can be used with multiple Bindings, hence it is RECOMMENDED to specify only abstract policy (binding independent) at this <wsdl:portType>. I prefer to use the other two options <wsdl:port> or <wsdl:binding> to apply endpoint policy. Policies associated with an endpoint policy subject apply to any message exchange made using that endpoint.

  • Operation Level: {Applied at <wsdl:portType/wsdl:operation> or <wsdl:binding/wsdl:operation>} - Policies associated with an operation policy subject apply to the message exchange described by that operation. Again, it is RECOMMENDED to specify only abstract policy at <wsdl:portType/wsdl:operation>, hence <wsdl:binding/wsdl:operation> is a prefered place to specify operation level policies.

  • Message Level: {Applied at <wsdl:message> or <wsdl:portType/wsdl:operation/wsdl:input> or <wsdl:portType/wsdl:operation/wsdl:output> or <wsdl:portType/wsdl:operation/wsdl:fault> or <wsdl:binding/wsdl:operation/wsdl:input> or <wsdl:binding/wsdl:operation/wsdl:output> or <wsdl:binding/wsdl:operation/wsdl:fault>} - Policies associated with a message policy subject apply to that message (i.e. input, output or fault message).

WS-Security Policy [2], WS-RM [3] assertions are build on top of WS-Policy for specifying security or reliable messaging requirements/constraints for aservice. For example, specifying security requirements for outgoing message, I can write as,

<wsp:Policy wsu:Id="Output_Policy">
<wsp:ExactlyOne>
<wsp:All>
<sp:SignedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
<sp:Body/>
</sp:SignedParts>
<sp:EncryptedParts xmlns:sp="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy">
<wsu:Timestamp/>
</sp:EncryptedParts>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>


and I can refer this policy as,

<wsdl:binding name="WebTransactionServiceSoapBinding"
type="tns:CreditCard">
<soap:binding style="document"
transport="http://schemas.xmlsoap.org/soap/http"/>
<!--wsp:PolicyReference URI="#Endpoint_Policy"/-->
<wsdl:operation name="purchase">
<soap:operation soapAction="" style="document"/>
<wsdl:input name="purchase">
<!--wsp:PolicyReference URI="#Input_Policy"/-->
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="purchaseResponse">
<wsp:PolicyReference URI="#Output_Policy"/>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>

or specifying RM assertions as Embedded instead of referred can be,

<wsdl:service name="CartSLSBBeanService">
<wsdl:port binding="ns1:CartSLSBBeanServiceSoapBinding"
name="CartSLSBBeanPort">
<wswa:UsingAddressing
xmlns:wswa="http://www.w3.org/2005/02/addressing/wsdl"/>
<soap:address location=" http://localhost:8181/cart/cart"/>
<wsp:Policy xmlns:wsp="http://www.w3.org/2006/07/ws-policy"
xmlns:wsu="
http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="RM">
<wsam:Addressing
xmlns:wsam=http://www.w3.org/2007/02/addressing/metadata>
<wsrmp:RMAssertion
xmlns:wsrmp=http://schemas.xmlsoap.org/ws/2005/02/rm/policy>
<wsrmp:BaseRetransmissionInterval Milliseconds="10000"/>
</wsrmp:RMAssertion>
</wsp:Policy>
</wsdl:port>
</wsdl:service>

You can read more about WS-SecurityPolicy[2] and WS RM[3] so as to understand what these assertions actually specify.I hope this helps
[1]. http://www.w3.org/TR/ws-policy/
[2]. http://docs.oasis-open.org/ws-sx/ws-securitypolicy/v1.2/ws-securitypolicy.html
[3].http://docs.oasis-open.org/ws-rx/wsrmp/200608/wsrmp-1.1-spec-cd-04.html
[4]. http://www.w3.org/TR/ws-policy-attach/

Monday, May 11, 2009

Understanding WS-Trust and configuration in CXF

Apache CXF is a high-performance, extensible, Intuitive & Easy to Use open source services framework. CXF helps you build and develop services using frontend programming APIs, like JAX-WS. CXF supports a variety of web service standards including SOAP, the Basic Profile, WSDL, WS-Addressing, WS-Policy, WS-ReliableMessaging, and WS-Security.

Apache CXF 2.2 is the third major release of CXF project. I found this release very interesting as it supports WS-SecurityPolicy and Partially supports WS-Trust. WS-Trust specifically deals with the issuing, renewing, and validating of security tokens, as well as with ways to establish, assess the presence of, and broker trust relationships between participants in a secure message exchange.

WS-SecurityPolicy is a very helpful and easier way of specifying your security requirements in an interoperable way. You can access a secured web service hosted on MS server by just pointing to the wsdl containing embedded WS-SecurityPolicy or a WS-Policy reference to a separate WS-SecurityPolicy file.

In CXF-2.2, WS-Trust is supported on client side, that means that now you can access a web services hosted by any WS vendor who requires you to produce tokens for authentication and authorization. For example, if I host a web service in Metro and configures a Metro STS (Secure Token Service - which provides tokens to clients). My CXF client will talk to Metro STS to acquire a token, once acquired CXF client can then produce this token to the Metro Service as an authentication and authorization token. An STS itself is a web service - a web service that issues security tokens.

Daniel Kulp has done a great job in making WS-Trust support up and working. In future release of CXF, we will come up with full support for WS-Trust. Any one who is interested can join the development I have filed a jira task for it.

How WS-Trust works: Basically on client side, ws-policy engine while parsing and understanding service wsdl, from <issuedtoken><issuer>... <issuer>assertion it learns that the service requires a security token to be produced. gives the WS-Addressing address of the STS service and WS-MEX (Metadata Exchange) address for getting the WSDL location of STS. STS may confirm the authenticity of the client who is requesting for the token. Based on the satisfactory confirmation of the authentication of the client, <issuedtoken> may have an assertion <requestsecuritytokentemplate> in which the service may specify what kind of RST request a client should make to STS, a service may specify it's particular requirements for the Token to be produced to it, the requirements can be KeySize, KeyType, TokenType, etc.

STS issues a RSTR (RequestSecurityTokenResponse) which contains requestedToken and proofkey. A proof key indicates proof of possession of the token associated with the requested security token. There are two types of proof keys: symmetric or asymmetric. A service can specify the proof key in the <keytype> element of <requestsecuritytokentemplate>.

In case of Symmetric key, STS creates and distributes the Symmetric key to both service and client. STS gives the key to the client in the <requestedprooftoken> element. STS gives the exact copy of the key to the service in the <keyinfo> element of the <subjectconfirmation> element in the issued SAML assertion in the RSTR response to the client. Client then forward the issued SAML assertion to the service.

In case of Public Key, client doesn't want to trust STS for issuing the secret key as proof of possession. In the RST (RequestSecurityToken) message client supplies RSA key or X.509 public key to STS. STS just embeds the RSA key or X.509 public key certificate in the <keyinfo> element of the <subjectconfirmation> element in the issued SAML assertion in the RSTR response to the client. Client then forward the issued SAML assertion to the service.

In case of No Proof Key, the issued token in <requestedsecuritytoken> itself works as proof of possession.

After getting RSTR, client composes the web service request as requested by WSDL requirements of the service. It embeds the SAML assertion into the request message to the service. Service and client uses the proof key for authentication and authorization of messages afterwards.

Configuring CXF for WS-Trust

Since currently only Client side support is provided in CXF 2.2 version (as I have discussed at the start of this blog entry), all we require to do is to configure a STSClient java class, org.apache.cxf.ws.security.trust.STSClient with the properties to wsdl location, service name, endpoint name. STSClient will look into wsdl, request for an issue, validate, renewal of the required token from STS and will put into the context of WS call so that finally the ws-request can be send with the required token, proof token and SAML assertion. Usually, you configure STS client in either of below two ways,

You can configure STSClient using code-first by creating a new instance of STSClient and calling setter methods of STSClient and finally setting a property "ws-security.sts.client" oof RequestContext() method on port instance as,

((BindingProvider)port).getRequestContext().put("ws-security.sts.client", stsinstance);

or, else you can configure spring bean as,

<jaxws:client name="{http://cxf.apache.org/}MyService">

<jaxws:properties>

<entry key="ws-security.sts.client">

<!-- direct STSClient config and creation -->

<bean class="org.apache.cxf.ws.security.trust.STSClient">

<constructor-arg ref="cxf"/>

<property name="wsdlLocation" value="target/wsdl/trust.wsdl"/>

<property name="serviceName" value="{http://cxf.apache.org/securitytokenservice}SecurityTokenService"/>

<property name="endpointName" value=""{http://cxf.apache.org/securitytokenservice}SecurityTokenEndpoint"/>

<property name="properties">

<map>

<entry key="ws-security.username" value="joe"/>

<entry key="ws-security.callback-handler" value="interop.client.KeystorePasswordCallback"/>

<entry key="ws-security.signature.properties" value="etc/alice.properties"/>

<entry key="ws-security.encryption.properties" value="etc/bob.properties"/> </map>

</property>

</bean>

</entry>

</jaxws:properties>

</jaxws:client>

Wednesday, January 21, 2009

Sample Annotation

A Novice Program for writing own Annotation. Annotations are not rocket science, they just have retention policy (runtime, source, class) and target (field, method, class, type, parameter) and finally can be looked using Reflection API.

MyAnnotation.java
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(value = RetentionPolicy.RUNTIME)

@Target(value = { ElementType.FIELD })

public abstract @interface MyAnnotation {
boolean enabled() default true;
String input() default "";
String output() default "";
int value() default -1;

}

Usage.java
import java.lang.reflect.Field;
public class Usage {
@MyAnnotation(input = "Hello")

public int a;
public void myMethod() {

Class<? extends Usage> c = this.getClass(); Field f = null;
try {
f = c.getField("a");
} catch (SecurityException e) { e.printStackTrace();
} catch (NoSuchFieldException e) { e.printStackTrace();
}
MyAnnotation ma = (MyAnnotation) f.getAnnotation(MyAnnotation.class);
System.out.println(ma.input());
}
public static void main(String args[]) {

Usage u = new Usage(); u.myMethod(); }
}

Sunday, September 21, 2008

Configuring CXF for Web Service Security using WSS4J

In case you directly want to see samples, you can go to Examples of WS-Security.....
You can read to below to understand bits, assuming you have a sample WS application using CXF. To secure that WS application you need to do following,

Create KeyStores and TrustStores
OpenSSL and Java SE 6 keytool creates X509v3 certificates, whereas Java SE 5 or earlier keytool creates X509v1 certificate. If you already have keystores and truststores and you are not sure about version of them, you can verify the version of your X509 certificate using this blog entry I blogged sometime back. Lets create new keystores and truststores with new X509 private and public key pair.
a) Creating Client Public and Private Key in Client keystore and Server Public and Private key in Server Keystore
keytool -genkey -alias clientX509v1 -keypass keypassword -storetype jks -storepass storepassword -validity 3650 -keyAlg RSA -keystore client-keystore.jks
keytool -genkey -alias serverX509v1 -keypass keypassword -storetype jks -storepass storepassword -validity 3650 -keyAlg RSA -keystore server-keystore.jks
b) Exporting clients public key to an external file and servers public key to an external file
keytool -export -alias clientX509v1 -file client-certfile.csr -keystore client-keystore.jks -storepass storepassword -keyAlg RSA
keytool -export -alias serverX509v1 -file server-certfile.csr -keystore server-keystore.jks -storepass storepassword -keyAlg RSA
c) Import the clients public certificate from the external file to server trust store and servers public certificate to the client trust store
keytool -import -noprompt -alias clientX509v1 -file client-certfile.csr -storepass storepassword -keystore server-truststore.jks -storetype JKS
keytool -import -noprompt -alias serverX509v1 -file server-certfile.csr -storepass storepassword -keystore client-truststore.jks -storetype JKS
Now we have required keystores and truststores with X509V1 certificates.

Configure CXF Bus:
Now we need to configure In and Out configuration of the server and client on CXF using spring. WSS4J provides security implementation for CXF, for security to be applied on XML content, CXF required SAAJ Interceptor which creates the SOAP document over which WSS4J works.

On Client

<jaxws:client
name="{http://apache.org/hello_world_soap_http}TimestampSignEncrypt";
createdFromAPI="true">
<jaxws:features>
<bean class="org.apache.cxf.feature.LoggingFeature"/>
</jaxws:features>

<jaxws:outInterceptors>
<bean class="org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor"/>
<ref bean="TimestampSignEncrypt_Request"/>
</jaxws:outInterceptors>

<jaxws:inInterceptors>
<ref bean="TimestampSignEncrypt_Response"/>
<bean class="org.apache.cxf.binding.soap.saaj.SAAJInInterceptor"/>
</jaxws:inInterceptors>

</jaxws:client>

On Server

<jaxws:endpoint
name="{http://apache.org/hello_world_soap_http}TimestampSignEncrypt";
createdFromAPI="true">

<jaxws:features>
<bean class="org.apache.cxf.feature.LoggingFeature"/>
</jaxws:features>

<jaxws:outInterceptors>
<bean class="org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor"/>
<ref bean="TimestampSignEncrypt_Response"/>
</jaxws:outInterceptors>

<jaxws:inInterceptors>
<ref bean="TimestampSignEncrypt_Request"/>
<bean class="org.apache.cxf.binding.soap.saaj.SAAJInInterceptor"/>
</jaxws:inInterceptors>

</jaxws:endpoint>

Above is the CXF Bus configuration on server and client to configure WSS4J, Log an SAAJ interceptors for both in and out configuration.

Provide Security Configuration
Now, we need to write Security configurations on server and client for in and out interceptors.
In this example, I have written all commonly used Actions; using Timestamp, Encrypting method argument, and sigining Timestamp and/or body. The order in which they are written is the order in which these actions are performed. Also, we need to configure user (signature) and encryption user accordingly on server and client. Also, crypto configurations needs to pass about keystore and truststore related information; by signaturePropFile and encryptionPropFile properties.

Below is the security related server side configuration configured in WSS4JInInterceptor and WSS4JOutInterceptor

For Server side outgoing response to Client

<bean class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor" id="TimestampSignEncrypt_Response">

<constructor-arg>
<map>
<entry key="action" value="Timestamp Signature Encrypt"/>
<entry key="user" value="service"/>
<entry key="signaturePropFile"
value="server_decrypt.properties"/>
<entry key="encryptionPropFile"
value="server_sign.properties"/>
<!--entry key="signatureKeyIdentifier" value="DirectReference"/-->
<!--entry key="encryptionKeyIdentifier" value="IssuerSerial" /-->
<entry key="passwordCallbackClass"
value="com.xyz.ws.security.KeystorePasswordCallback"/>
<entry key="signatureParts"
value="{Element}{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd}Timestamp;{Element}{http://schemas.xmlsoap.org/soap/envelope/}Body"/>
<entry key="encryptionParts"
value="{Element}{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd}Timestamp;{Element}{http://www.w3.org/2000/09/xmldsig#}Signature;{Content}{http://schemas.xmlsoap.org/soap/envelope/}Body"/>
<!--entry key="encryptionKeyTransportAlgorithm"
value="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/-->
<!--entry key="encryptionSymAlgorithm"
value="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/-->
</map>

</constructor-arg>
</bean>

For Server side incoming request from client

<bean class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor" id="TimestampSignEncrypt_Request">

<constructor-arg>
<map>
<entry key="action" value="Timestamp Signature Encrypt"/>
<entry key="signaturePropFile" value="server_sign.properties"/>
<entry key="decryptionPropFile" value="server_decrypt.properties"/>
<entry key="passwordCallbackClass"
value="com.xyz.ws.security.KeystorePasswordCallback"/>
</map>
</constructor-arg>

</bean>

Below is the client side security related configuration configured in WSS4JInInterceptor and WSS4JOutInterceptor

For Client side outgoing request to Server

<bean class="org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor" id="TimestampSignEncrypt_Request">

<constructor-arg>
<map>
<entry key="action" value="Timestamp Signature Encrypt"/>
<entry key="user" value="client"/>
<entry key="encryptionUser" value="service"/>
<entry key="signatureKeyIdentifier" value="DirectReference"/>
<entry key="signaturePropFile" value="client_sign.properties"/>
<entry key="encryptionPropFile" value="client_encrypt.properties"/>
<entry key="encryptionKeyIdentifier" value="IssuerSerial" />
<entry key="passwordCallbackClass"
value="com.xyz.ws.security.KeystorePasswordCallback"/>
<entry key="signatureParts"
value="{Element}{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd}Timestamp;{Element}{http://schemas.xmlsoap.org/soap/envelope/}Body"/>
<entry key="encryptionParts"
value="{Element}{http://www.w3.org/2000/09/xmldsig#}Signature;{Content}{http://schemas.xmlsoap.org/soap/envelope/}Body"/>
<!--entry key="encryptionKeyTransportAlgorithm"
value="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/-->
<!--entry key="encryptionSymAlgorithm"
value="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/-->
</map>
</constructor-arg>

</bean>

For Client Side Incoming Response from Server:

<bean class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor"
id="TimestampSignEncrypt_Response">

<constructor-arg>
<map>
<entry key="action" value="Timestamp Signature Encrypt"/>
<entry key="signaturePropFile" value="client_encrypt.properties"/>

<entry key="decryptionPropFile" value="client_sign.properties"/>
<entry key="passwordCallbackClass"
value="com.xyz.ws.security.KeystorePasswordCallback"/>
</map>
</constructor-arg>

</bean>

Contents of crypto configuration files:
You require to give information about the keystore or truststore containing X509 private or public key, keystore password and alias name for the public-private key pair.

For encryption , you require to configure public key of the receiver, hence client/server truststore contains public certificate of server/client alias which is serverx509v1/clientx509v1 respectively.

For Signature, you require to use the private key stored in client/server keystore and hence alias clientx509v1/serverx509v1 respectively.

client_encrypt.properties
org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
org.apache.ws.security.crypto.merlin.keystore.type=jks
org.apache.ws.security.crypto.merlin.keystore.password=storepassword
org.apache.ws.security.crypto.merlin.keystore.alias=serverx509v1
org.apache.ws.security.crypto.merlin.file=keystore/client-truststore.jks

client_sign.properties
org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin org.apache.ws.security.crypto.merlin.keystore.type=jks org.apache.ws.security.crypto.merlin.keystore.password=storepassword
org.apache.ws.security.crypto.merlin.keystore.alias=clientx509v1 org.apache.ws.security.crypto.merlin.file=keystore/client-keystore.jks

server_decrypt.properties
org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin org.apache.ws.security.crypto.merlin.keystore.type=jks org.apache.ws.security.crypto.merlin.keystore.password=storepassword org.apache.ws.security.crypto.merlin.keystore.alias=serverx509v1 org.apache.ws.security.crypto.merlin.file=keystore/server-keystore.jks

server_sign.properties
org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin org.apache.ws.security.crypto.merlin.keystore.type=jks org.apache.ws.security.crypto.merlin.keystore.password=storepassword
org.apache.ws.security.crypto.merlin.keystore.alias=clientx509v1 org.apache.ws.security.crypto.merlin.file=keystore/aerver-truststore.jks

Install Bouncy Castle Security Provider
Just check the lib folder of CXF binary distribution as in CXF 2.2 onwards, CXF is having bouncy castle jar, hence no requirement to download this jar if your CXF distribution already have one.

(or else) Download the latest Bouncy Castle provider (bcprov-jdkXX-xxx.jar) for your JDK, then put it in JAVA_HOME/jre/lib/ext.Edit JAVA_HOME/jre/lib/security/java.security. Find the list of security providers:Add the Bouncy Castle provider to the list as,
security.provider.10=org.bouncycastle.jce.provider.BouncyCastleProvider {assuming 9 entries are there}

Install JCE Unlimited Strength Jurisdiction Policy Files
Due to import control restrictions for some countries, the Java CryptographyExtension (JCE) policy files shipped with the J2SE DevelopmentKit and the J2SE Runtime Environment allow strong but limited cryptography to be used. These files are located at
/lib/security/local_policy.jar
/lib/security/US_export_policy.jar
An unlimited strength version of these files indicating no restrictions on cryptographic strengths is available on the JDK web site for those living in eligible countries.
Unlimited strength Jurisdiction Policy Files may be downloaded from the JavaSoft's web site.Here is the web address:http://java.sun.com/javase/downloads/index.jsp#docs
(At the end of the page under "Other Downloads" section).
Open the readme.txt and follow the instructions:Basically replace two existing jar for the two new ones((US_export_policy.jar and local_policy.jar )

Run your example by passing configuration files we just made

CXF can discover XML configuration files which you have written. For both web service clients and servers, the default location that CXF will look for a configuration for is "/cxf.xml" on the class path.Pass your server and client config files to the Java call to the server and client class as argument
If you wish to override this location, you can specify a command line property: -Dcxf.config.file=some_other_config.xml. This custom configuration file is also expected to be on the class path.
To use a url as the configuration location, specify as follows: -Dcxf.config.file.url=config_file_url
-Dcxf.config.file.url=client.xml
-Dcxf.config.file.url=server.xml

You may get an exception like below:

Caused by: java.io.IOException: exception decrypting data - java.security.Invali dKeyException: Illegal key size at org.bouncycastle.jce.provider.JDKPKCS12KeyStore.cryptData(Unknown Sou rce) at org.bouncycastle.jce.provider.JDKPKCS12KeyStore.engineLoad(Unknown So urce) at java.security.KeyStore.load(KeyStore.java:1185) at org.apache.ws.security.components.crypto.AbstractCrypto.load(Abstract Crypto.java:168) ... 38 more

Don't worry, you just require to put in unlimited strength JCE files in your jdk/jre. Read and follow steps in #Install JCE Unlimited Strength Jurisdiction Policy Files header just above. They will get resolved once you follow steps.

You may get java.security.UnrecoverableKeyException: Cannot recover key - It happens when your storepassword and keypassword are different. Though I think that is a valid case, but as a workaround you can make both passwords the same. Generate the keystores once again, export the certificates and import them into truststore once again. All commands except below two remains the same.

keytool -genkey -alias clientX509v1 -keypass storepassword -storetype jks -storepass storepassword -validity 3650 -keyAlg RSA -keystore client-keystore.jks
keytool -genkey -alias serverX509v1 -keypass storepassword -storetype jks -storepass storepassword -validity 3650 -keyAlg RSA -keystore server-keystore.jks

I hope now you would have seen secured in and out SOAP messages from client and server. :)
Do please let me know if you face some errors, exceptions and also your comments.

Wednesday, May 28, 2008

XML Schema Validation and importing different encoding schema

Following is a simple code which shows importing an different encoding xml schema into a different encoding xml schema. In the following example Book.xsd imports Age.xsd which has UTF-16 encoding. Following example also shows XML Schema Validation

XMLValidationSample.java
import java.io.IOException;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
import org.xml.sax.SAXException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.SAXParseException;
import javax.xml.parsers.ParserConfigurationException;
public class XMLValidationSample {
public static void main(String args[]) {
try{
String book = "Book.xsd", first = "first.xsd", last = "last.xsd", age = "age.xsd";
String[] schemas = {book, first, last, age};
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setNamespaceAware( true);
factory.setValidating( true);
SAXParser parser = factory.newSAXParser();
parser.setProperty( "http://java.sun.com/xml/jaxp/properties/schemaLanguage",
"http://www.w3.org/2001/XMLSchema");
parser.setProperty( "http://java.sun.com/xml/jaxp/properties/schemaSource",
schemas);
XMLReader reader = parser.getXMLReader();
reader.parse( new InputSource( "Book.xml"));
}catch (SAXException e) {
Exception x = e.getException ();
((x == null) ? e : x).printStackTrace (); }
catch (IOException e) {
e.printStackTrace (); }
catch(ParserConfigurationException e){
e.printStackTrace (); }
}
}
Book.xml

<?xml version="1.0" encoding="UTF-8"?>
<my:book xmlns:my="http://www.person.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation= "http://www.person.com Book.xsd">

<person>
<firstd><first>Johnthan</first></firstd>
<lastd><last>Schewatz</last></lastd>
<aged><age>38</age></aged>
</person>

<person>
<firstd><first>Bill</first></firstd>
<lastd><last>Gates</last></lastd>
<aged><age>46</age></aged>
</person>

<person>
<firstd><first>Steve</first></firstd>
<lastd><last>Jobs</last></lastd>
<aged><age>40</age></aged>
</person>

</my:book>


Book.xsd

<?xml version="1.0" encoding="UTF-8" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.person.com" xmlns="http://www.person.com" xmlns:f="http://www.first.com" xmlns:l="http://www.last.com" xmlns:a="http://www.age.com" elementFormDefault="unqualified">
<xsd:import namespace="http://www.first.com" schemaLocation="first.xsd"/>

<xsd:import namespace="http://www.last.com" schemaLocation="last.xsd"/>
<xsd:import namespace="http://www.age.com" schemaLocation="age.xsd"/>
<xsd:element name="book">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="person" type="persontype" maxOccurs="unbounded"/> </xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:complexType name="persontype">
<xsd:sequence>
<xsd:element name="firstd" type="f:firstType"/>
<xsd:element name="lastd" type="l:lastType"/>
<xsd:element name="aged" type="a:ageType"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>

first.xsd

<?xml version="1.0" encoding="UTF-8" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.first.com" xmlns="http://www.first.com" elementFormDefault="unqualified">
<xsd:complexType name="firstType">
<xsd:sequence>
<xsd:element name ="first" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>

last.xsd

<?xml version="1.0" encoding="UTF-8" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.last.com" xmlns="http://www.last.com" elementFormDefault="unqualified">
<xsd:complexType name="lastType">
<xsd:sequence>
<xsd:element name ="last" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>

age.xsd

<?xml version="1.0" encoding="UTF-16" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.age.com" xmlns="http://www.age.com" elementFormDefault="unqualified">
<xsd:complexType name="ageType">
<xsd:sequence>
<xsd:element name ="age" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>

Wednesday, March 19, 2008

how to find out the version of X.509 certificate? (v1, v2 or v3)

At times, we require to find out the version of given X.509 certificate, whether it is v1, v2 or v3 type certificate. A key differentiator between version v1 and v3 is that v3 certificate have extensions, which v1 doesn't have. But, at times, it's difficult to know whether any extensions are there or not, or if information like Email Address are there, can you consider them as extension or not?

OpenSSL and Java SE 6 utility tool 'keytool' [1] from Sun Microsystem creates X509v3 certificates, whereas Java SE 5 or earlier keytool creates X509v1 certificate. Keytool can import and export v1, v2 and v3 certificates from keystores.

If you don't remember, or else you received certificates from some other source, then you can figure out using following,
Programming Approach: Use X509Certificate[2] interface to get access to extensions and version number.
try { // Load the keystore
File file = new File("mykeystore.jks");
FileInputStream is = new FileInputStream(file);
KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
// List the aliases
Enumeration enum = keystore.aliases();
for (; enum.hasMoreElements(); ) {
String alias = (String)enum.nextElement();
java.security.cert.Certificate cert = keystore.getCertificate(alias);
if (cert instanceof X509Certificate) {
X509Certificate x509cert = (X509Certificate)cert;
// Get Version no {X509CertInfo class gives version num starting from zero, hence if you get '2', it 's actually X.509 v3 certificate}
x509cert.getVersion();
// Get subject
Principal principal = x509cert.getSubjectDN();
String subjectDn = principal.getName();
// Get issuer
principal = x509cert.getIssuerDN();
String issuerDn = principal.getName();
}
}
} catch (java.security.cert.CertificateException e) {
} catch (NoSuchAlgorithmException e) {
} catch (FileNotFoundException e) { // Keystore does not exist
} catch (KeyStoreException e) {
} catch (IOException e) {
}

Use OpenSSL: Download and install OpenSSL [3] pre built binaries for Windows.


  • Export the certificate to .CER format from the keytool -export command: keytool -export -alias myalias -file MYCERT.cer -keystore mykeystore -storepass mystorepassword
  • Convert CER format to PEM format using openssl command: x509 -inform der -in MYCERT.cer -out MYCERT.pem
  • Check the version using openssl command: x509 -in MYCERT.pem -inform PEM -text
You can see following information along with Validity, Subject, Subject Public Key Info and Certificate:
Certificate:
Data:
Version: 1 or 2 or 3
Serial Number: .....
Signature Algorithm: .....

Till now, you must have figured out what's the version of the X.509 certificate you are using. :)

[1]. http://java.sun.com/javase/6/docs/technotes/tools/solaris/keytool.html
[2]. http://java.sun.com/j2se/1.4.2/docs/api/java/security/cert/X509Certificate.html
[3]. http://www.openssl.org/related/binaries.html

Thursday, July 05, 2007

Java EE 6, EJB 3.1, and JPA 2.0

JSR 316 for Java EE 6 is in place.
It has updates for: Servlet 3.0, EJB 3.1, JPA 2.0, JSF 2.0, JAX-WS...
and new JSRs Web Beans, JAX-RS (Restful Webservices), Work Manager and Timer
(Java Persistence API) JPA 2.0 forked from JRS 220 to a new instance JSR 317, new (Enterprise JavaBeans) EJB 3.1 is now filed as JSR 318.

Expected from the new version of JPA 2.0 is an API for "criteria" queries and the ability to have hierarchies of Embeddables.

Rod has written a good writeup about this.

Monday, November 13, 2006

Discover like never before

Two main components of service discovery are:
  1. Discovery Architecture, and,
  2. Service matching mechanism.

Service discovery in pervasive computing environments requires a decentralized design approach where a node should not depend on some other node(s) to advertise/register services. Each service should be autonomous and be able to advertise its presence. Moreover, the discovery should also adapt itself to reflect the changes in the vicinity.

A good idea is to multiplex service broadcasting and ior transmission from server to new clients.

service request broadcast has three disadvantages:
  • Broadcast scales poorly with increasing network diameter and network size.
  • It utilizes resources and computation power on all nodes of the network including nodes that do not even have the service or nodes that may not even fall in thr route of the desired services.
  • It ulilizes significant network bandwidth, and creates a large load on the network.

Tuesday, August 22, 2006

Synchronous Communication and Concerns

Synchronous communication is a most straighforward way of communication. It is easiest to understand and incarnate. Most of the basic programs are based on it, from RPC to TP and Object Monitors.
But it has a few overheads which literally kills its advantages specially in certain distributed and enterprise communication models.

  • It requires both parties to be online, it requires both parties to under go connection overhead.
  • It requires both parties to maintain session of communication.
  • To maintain session, both parties have to consume CPU resources for whole of 'live' time.
  • Fault detection gets difficult as it is difficult to detect where the fault occured, is it at A, between A and B request communication, at B, or between B and A response communication.
  • Fault Tolerance can be achieved by incarnating multiple service entities, but it requires to maintain their sessions also, it also requires have pools of them, and all this assuming it is stateless. If the service is statefull it gets more difficult.
  • As seen from Fault Tolerance and session points, it is not a scalable approach.

Tuesday, July 04, 2006

Service Discovery and Broadcast

Two main components of service discovery are:Discovery Architecture and Service matching mechanism.

Service request broadcast has three disadvantages:


  • Broadcast scales poorly with increasing network diameter and network size.
  • It utilizes resources and computation power on all nodes of the network including nodes that do not even have the service or nodes that may not even fall in the route of the desired services.
  • It ulilizes significant network bandwidth, and creates a large load on the network.

Clearly, service discovery in pervasive computing environments requires a decentralized design approach where a node should not depend on some other node(s) to advertise/register services. Each service should be autonomous and be able to advertise its presence. Moreover, the discovery should also adapt itself to reflect the changes in the vicinity.

Wednesday, May 31, 2006

Software Defined Radio's Chapter

Will soon put contents here... watch out for this space.

Monday, May 15, 2006

A Revisit to MRPs (Multicast Routing Protocols)

In general, there are three types of routing mechanism in MANET. Proactive (table driven) protocols use a traditional, distributed, shortest-path and maintain routes at all times. They impose a high overhead. Reactive (on-demand) protocols are initiated by the source. They have lower traffc compared with proactive protocols, but impose delay in route determination. Hybrid protocols are an adaptive way of combining proactive and reactive protocols.

DVMRP (Distance Vector Multicasting Routing Protocol) builds a source-based tree. AODV (Ad-hoc On-Demand Distance Vector Routing Protocol) builds a corebased tree. CAMP (Core Assisted Mesh Protocol) builds a mesh interconnection of hosts.

Friday, May 12, 2006

Message Broker - It's just to FIRE

Need for a Information flow graph that works over epidemic message brokership on MH entities, which would result in dynamic group creation, subscription of receipients along the path on graph.

I just found good number of reads, namely,
  • In message broker space. Known to only two JMS and CNS, excited to discover CEA (Cambridge Event Architecture), HERMES, SIENA, JEDI, ELVIN

  • In tuple spaces, LINDA, LIME (2 very well known), IBM Tspaces, Java Spaces, L2imbo

  • In Pervasive spaces, CALAIS, Gaia, Nexus, Solar and One.World
I believe in Power of CORBA, do you? I will make you believe in this.

Tuesday, May 09, 2006

The Nature of Real Time CORBA - complete coverage

Real time CORBA developers require to give strict attention to the allocation and to the predictability of execution entities. Real Time CORBA has scrapped of a few things from normal CORBA in order to support real time systems.RT CORBA does not currently address dynamic scheduling. Real time CORBA does not define IDL for an activity. Instead of worrying about delimiting an activity, it deals with invocations of IDL defined operations.

A traditional CORBA program flow is like: An operation invocation consists of a Request and a Reply. It is initiated by some client computational context (e.g. a thread) and passes through a client-role ORB, a transport protocol (TCP in the case of GIOP), a server-role ORB (possibly involving queuing) to a server application. Thereafter the operation passes through the same entities in reverse order, back to the client.

RT CORBA uses four components namely,
  • Scheduling support from OS
  • Real Time ORB
  • Transport medium
  • Application
to respect three criteria of end to end predictability namely,
  • Respective thread priorities between client and server for resolving resource contention
  • Bounding the duration of thread priority inversions during end-to-end processings
  • bouding the latencies of operation invocations

Thread Priorities: Real-Time CORBA defines a universal, platform independent priority scheme called Real-Time CORBA Priority. It is introduced to overcome the heterogeneity of different Operating System provided priority schemes, and allows Real-Time CORBA applications to make prioritized CORBA invocations in a consistent fashion between nodes with different priority schemes. Real-Time CORBA defines a NativePriority type to represent the priority scheme that is ‘native’ to a particular Operating System. Priority values specified in terms of the Real-Time CORBA Priority scheme must be mapped into the native priority scheme of a given scheduler before they can be applied to the underlying schedulable entities. Real-Time CORBA defines a Real-Time CORBA Current interface to provide access to the CORBA priority of a thread.
A Real-Time operating system (RTOS) sufficient to use for implementing a Real-Time ORB compliant with this specification, will have some discrete representation of a thread priority.

Priority Models: Real-time CORBA defines two models at which a server handles a clients request:

  • A model in which server respects priorities of inivocations set by clients. Server ORB maps this Real-time CORBA priority to Native OS priority. Requests coming from a non Real-time ORB are handled according to server priorities
  • Server handles the inovocations according to the Real-time priorities set by the server side
Thread Pools: Thread pools provides, preallocation of threads (helps in reducing priority inversion), partitioning of threads, bounding of thread usage, buffering of additional requests.

Other cool features:
  • Real-time CORBA provides clients to obtain a non multiplexed connection, which will not be shared with other client-server communications.
  • Allows applications to set a timeout on the invocation in order the bound the time the client is blocked and waiting for the response.
  • Server side thread configuration.
  • Configuration of priority models set by clients or server. A new Real-time CORBA POA policy would be created on aboves.
and finally, RTORB interface defines operations to create, destroy other constituents of Real-time ORB. There is a single instance of RTCORBA::RTORB per instance of CORBA::ORB. The object reference for the RTORB is obtained by calling ORB::resolve_initial_references with the ObjectId “RTORB”.

Saturday, April 22, 2006

Data dissemination completed

It's been like the worst times, digesting them all and not finalizing them, I should make this moment, a moment to compose all in one.

There should be a ThreshValue on mobile nodes, configurable to the signal strength(interested in backchannel bandwidth), for controlling the push or pull behavior.

Push mode is bandwidth preserving in any environment, whether it's wired/wireless, I only difference is that it matters the most in wireless. But, at the end of day it depends on what's at application layer.

Let's try to classify this,
  • 1. Parameterised service mode, (prime communication mode i.e. unicast pull)

  • 2. Subscription mode, (service data broadcasts i.e. multicast push, if any by service to subscribers, broadcast items with highest count on Longest Wait First.)

  • 3. Regular housekeeping communications, (handoff communication)

  • 4. Parameterised housekeeping data transfer (code mobility, execution state transfer)

  • 5. Parameterised service mode with multicast pull (aggregation of same request over a time span, hard to realize usability in practical cases, depends on usability, it's a intermediate stage between switching from 1 to 2)



I assume above all would be the communication modes, which all are required to be supported by the framework. Push characteristics of Message brokers can be used very effectively in 2 and 3. Ofcourse, In all cases, Message brokers would be used for data stroage for data availability.

An extremly good approach I feel is to broadcase hash-index of to-be multicast push items to subscribers to defer their unicast pull.

A important point to note here is, Heat adversely effects the reliability of the digital circuits and increases costs for cooling especially in servers. In order to access the desired data, a client has to be in active mode, waiting for the data to appear on the multicast. Enabling reliable communication on the message broker could be helpful in the sense of truly providing the intermittent devices asynchronous access to data. An broadcast indexing would make things even much better. The only low point is that in MANET, we don't have any super devices, all are peers, hence to save clients heat and effectively utilize Back Chaneel bandwidth, we require memory at the serving peer (so called server in Client Server environment).