Monday, October 28, 2013

Registry Services by the DASHboard light

Quite excited about the prospects of our most recent work on getting Registry Services data (IT resource management) into DASH, the dashboarding component of Jazz for Service Management.

I wrote an entry on the Jazz for Service Management blog:

https://www.ibm.com/developerworks/community/blogs/69ec672c-dd6b-443d-add8-bb9a9a490eba/entry/you_can_see_registry_by_the_dashboard_light?lang=en

The possibilities of integration with datasets from other systems management products offering OSLC interfaces make it really cool.

And there is even a video-recording.

Registry Services data on JazzSM DASH UI

Friday, September 20, 2013

Registry Services on the glass

glassAnother entry related to my current project, Jazz for Service Management. I am quite thrilled about having mixed jQuery and rdfQuery to interact with our OSLC server directly from a web-browser. Look’ma, only 2-tiers:

https://www.ibm.com/developerworks/community/blogs/69ec672c-dd6b-443d-add8-bb9a9a490eba/tags/rsotg?lang=en

Wednesday, September 18, 2013

Renewing expired certificates for wsadmin invocations against WebSphere Application Server

We have a verification lab with about a dozen machines and on a periodic basis we hit a problem where wsadmin cannot connect to an instance of WebSphere Application Server due to a certificate expiration.

Note: This being a closed test environment, this kind of problem can be minimized or avoided altogether by creating the profile in Advanced mode through the Profile Management Tool and choosing longer expiration period than the default one-year period chosen when creating the profile using the manageprofiles command-line tool.

The connection error message returned by wsadmin will not be all that helpful because essentially it does not know why its connection request was refused, but the server logs ($profile/logs/server1/ServerOut.log or TextLog_<timestamp>.log depending on your troubleshooting settings) will contain a very telling message like this:

[9/18/13 10:22:53:664 EDT] 0000001c WSX509TrustMa E   CWPKI0022E: SSL HANDSHAKE FAILURE:  A signer with SubjectDN "CN=hostname, OU=hostNode01Cell, OU=hostNode01, O=IBM, C=US" was sent from target host:port "unknown:0".  The signer may need to be added to local trust store "$profile/AppSrv01/config/cells/hostNode01Cell/nodes/hostNode01/trust.p12" located in SSL configuration alias "NodeDefaultSSLSettings" loaded from SSL configuration file "security.xml".  The extended error message from the SSL handshake exception is: "PKIX path validation failed: java.security.cert.CertPathValidatorException: The certificate expired at Wed Aug 21 21:54:27 EDT 2013; internal cause is:        java.security.cert.CertificateExpiredException: NotAfter: Wed Aug 21 21:
54:27 EDT 2013".

It took me a little while to figure out the keystore used by wsadmin, which turned out to be:

$profile/etc/key.p12

Listing the certificates in the file quickly showed the offending certificate (keep in mind that the default keystore password in WAS is WebAS) :

bash-2.04# keytool -list -storetype PKCS12 -keystore ./profiles/AppSrv01/etc/key.p12 –storepass <password> -v
Keystore type: PKCS12
Keystore provider: IBMJCE
Your keystore contains 1 entry
Alias name: default
Creation date: Aug 22, 2012
Entry type: keyEntry
Certificate chain length: 2
Certificate[1]:
Owner: CN=hostname, OU=hostNode01Cell, OU=hostNode01, O=IBM, C=US
Issuer: CN=hostname, OU=Root Certificate, OU=hostNode01Cell, OU=hostNode01, O=IBM, C=US
Serial number: 2623bc78cd3b
Valid from: 8/21/12 9:54 PM until: 8/21/13 9:54 PM
Certificate fingerprints:
         MD5:  D2:FB:3F:8A:53:6F:19:B2:6C:77:AB:00:AC:40:EC:0B
         SHA1: 64:76:8F:7F:2A:0A:6A:F0:C9:21:86:FF:90:5B:C5:FA:FF:64:61:B4
Certificate[2]:
Owner: CN=hostname, OU=Root Certificate, OU=hostNode01Cell, OU=hostNode01, O=IBM, C=US
Issuer: CN=hostname, OU=Root Certificate, OU=hostNode01Cell, OU=hostNode01, O=IBM, C=US
Serial number: 2622d2d16331
Valid from: 8/21/12 9:54 PM until: 8/18/27 9:54 PM
Certificate fingerprints:
         MD5:  C2:CB:AB:C3:3A:6C:D2:77:6A:87:DA:D7:21:2E:DC:E4
         SHA1: 0C:09:CD:37:96:F8:FE:91:18:92:5A:93:05:AB:15:D6:6D:36:A1:AA

One can (nay, should) use the keytool command-line to recreate the certificate above, but this being a closed test environment where we do not test SSL functionality, and since we did not have any new certificates added to either wsadmin or server keystores since we installed that test system, I did the unthinkable, that is, overwrite the wsadmin keystore with the server keystore.

cp $profile/config/cells/hostNode01Cell/nodes/hostNode01/key.p12 $profile/etc/key.p12

Note: The last step was a very specific decision for a test environment running WebSphere Application Server. **DO NOT** take the last step on a production environment or where company policies do not allow for it, and only after carefully examining the two keystores to ensure all their fields (sans expiration date) are exact matches.

Thursday, May 30, 2013

I am on GitHub…bookmarks, linked data, and more to come.

While writing more extensively for the System Management Connect blog,  I ended up creating some source code examples, which quickly evolved into interesting side projects.

At the same time, formatting these examples into blog editors became a major hassle with ephemeral results. Blog editors are definitely not geared for handling the heavy syntax of source code (yes, yes, good luck with “pre” tags) and even when you achieve good results, they are completely botched months later when the website hosting the blogs makes even the most minute change to their CSS stylesheets.

I am now sharing the code examples in a new GitHub account, at https://github.com/nastacio.

My first project, unimaginatively titled “lctodel”, was developed a couple of years ago and copies bookmarks from a Lotus Connections account to a del.icio.us account (I know, I know, where is the bridge to bit.ly?) .

The second project is still unimaginatively, but less cryptically, dubbed dw.article.rdf. It contains a web-based project that showcases Javascript interactions with my current project (Jazz for Service Management) and is based on jQuery and RDFQuery. I started writing about that exercise here.

Back to GitHub itself, I think more and more it has become a necessity for software developers to organize and publicize their hobbies outside their professional work. In my role I often interview candidates for development positions within the company and I cannot overstate the importance we give to a well-executed technical online presence.

Thursday, April 25, 2013

Iterating through response pages queried from Registry Services using Java

This entry is related to my current project, Jazz for Service Management. Instead of reposting it here, here is a link to the original in the developerWorks website:

Iterating through response pages queried from Registry Services using Java.

Tuesday, February 12, 2013

Base 64 Encoding with Java without Apache Commons

I cannot take credit for this very useful hack, which I saw in concept several years ago. Any project dealing with web development will eventually find itself needing to pass on base authentication headers, which must be encoded in Base64 format.

Apache Commons Base64 is widely adopted as the de-facto Java standard for that kind of encoding, but for various reasons, I prefer to avoid adding new dependencies unless absolutely necessary or beneficial.

In that sense, here is the technique, with the key aspects highlighted in bold:

---

package com.blogspot.sourcepatch;

import java.util.prefs.AbstractPreferences;
import java.util.prefs.BackingStoreException;

public class Base64 {

    private static final Base64 instance = new Base64();
    private static final Base64Encoder encoder = instance.new Base64Encoder();

    /**
     * @return the base64String
     */
    public static String encode(String s) {
        encoder.putByteArray("akey", s.getBytes());
        String result = encoder.getBase64String();
        return result;
    }

    public class Base64Encoder extends AbstractPreferences {

        private String base64String = null;

        public Base64Encoder() {
            super(null, "");
        }

        protected Base64Encoder(AbstractPreferences parent, String name) {
            super(parent, name);
        }

        @Override
        protected void putSpi(String key, String value) {
            base64String = value;
        }

        /**
         * @return the base64String
         */
        public String getBase64String() {
            return base64String;
        }

        @Override
        protected String getSpi(String key) {
            return null;
        }

        @Override
        protected void removeSpi(String key) {
        }

        @Override
        protected void removeNodeSpi() throws BackingStoreException {
        }

        @Override
        protected String[] keysSpi() throws BackingStoreException {
            return null;
        }

        @Override
        protected String[] childrenNamesSpi() throws BackingStoreException {
            return null;
        }

        @Override
        protected AbstractPreferences childSpi(String name) {
            return null;
        }

        protected void syncSpi() throws BackingStoreException {
        }

        @Override
        protected void flushSpi() throws BackingStoreException {
        }

    }

}