Blug2013

Well my first Blug is over and I have to say I am very impressed, Theo Heselmans is a genius and the fact that there was actual IBM backing, both in terms of people and in terms of money made a real difference, apparently Blug is now the largest lotus user group in the world.

The feel was very professional as well as relaxed, I made more contacts and had more serious conversations then even at Connect 2013 and shock of shock there were even times when I exchanged business cards with people when both of us REALLY wanted to rather than it being one sided or for politesses sake.

Both the food and drink for the event were amazing and seemed to be none time based (at Connect and other conferences its always “how much can we get down out throats within the time limit”)

The venue was awesome, the Faculty Club in Leuven

for some reason I have yet to grasp I did not take any pictures of the bleeding inside (face palm)

The first proper day of blug started with a apparently amazing keynote where notes 9 would be released, I say amazing because I was skulking in the speaker room as all my clients had noticed I was busy and so were having melt downs but even here Blug did us proud as the network was nice and fast even when Notes 9 was released and 200+ people pounded the hell out of the network.

I did have time in between sessions, client needs and hard core social interaction to not only have squint at the freebie bag, which unbelievably had some things in it I wanted to keep (this has not happened since the last Ilug) but also kept the bag its self (a note to all conference organisers, unless you are giving us a brand name back pack that’s better than our current one a book bag is the way to go as we can use it later),

The session I did with Martin Vereecken, Mark Leusink and Matt White went down very well with it filling the room

All credit to the amazing slide deck goes to Martin!

Talking of sessions all the content I saw was brill, absolutely no fillers or restrictions, which produced many near perfect sessions.

Lastly the town of Leuven was spellbinding

You will note that [Matt White](https://twitter.com/mattwhite) and I skulked out of the conference to go fetch the gift of chocolate that is required of everybody who visits Belgium, by the end of the conference EVERYBODY had done this task.

Lessons other IBM conferences should learn

– Having a steady but not extreme flow of wine and beer in the sponsor area makes people come to it all the time and makes them more relaxed so they talk to the sponsors, no need to over do it so they get pissed but just grease the conversation wheels
– Sugar and caffeine on hand at all times give people energy and makes the more enthusiastic
– Allow ALL forms of content and presentation just make sure the quality is high.

Notes9 release Oops

As a firm insider on the IBM community I often forget how impenetrable IBM stuff is from the outside, I got this contact from a friend who no longer makes his living from IBM/Lotus products but still likes to keep up to date, they are less than impressed…

..quick rant to you … not at you at all.

Who do you know high up in Lotus/IBM that listen to their public? I find the product release and websites around the Notes/Domino product HORRENDOUS. Download 9 (yep, just found out it’s been released after searching many pages down in Google despite being a PARTNER!), get the release notes – click on the What’s new, takes you to Lotus site, click on the link there, takes you to IBM, click on Notes 9 stuff, takes you BACK to the readme file I started at – do I know what’s new yet? Yep, that nothing has changed when it comes to taking care of customers or the paying public – IBM/Lotus – go and talk to Atlassian, they know how to grow community, build awesome products and take care of customers and evangelists alike.

Try it out – search Google to find anything about the product being launched and fail badly.
When you download, you can get to the release notes – I’ll save you the time – http://infolib.lotus.com/resources/domino/Notes/9.0/Readme/readme.html – now tell me what’s new?

Gladly share this with whomever you wish as high as you can – they are a bunch of absolute rubbish.
And if they want suggestions of how to do it better rather than just a rant, I’ve got a LOT of suggestions but I’m not making them if none will be implemented (like me contacting XXXXX XXXXX directly to get the forums sorted out and it NEVER happening, so I stopped sending any feedback on any beta testing)

what can I tell him?

Blug2013 day0

So my first Blug begins, travelling up in a full car with both Matt White and Jullian Woodwood, with thanks to the kindly Tim Clark from TC Soft Consulting for driving us all that way (and letting me kip on his floor).

This conference is a rare thing, a well run conference organised by Theo Heselmans who seems to be a master at the art as well as of getting money out of sponsors, as a speaker I am being treated amazingly, and the venue is jaw dropping, more on that next entry.

First night was the speaker dinner, in which nice food and amazing beer was served. but my main enjoyment was the company, packed with the smartest of the IBM community, I learnt more and made more contacts there than I have done in the last year put together, this included:

  • The new wrappers for the IBM Domino java interfaces , which IBM should have done ages ago but is awesome that the community has taken it on.
  • The discovery from Mikkel Flindt Heisterberg at http://lekkimworld.com/ that the problem with log4j that I simply could not fix in domino CAN’T be fixed (god I feel better knowing that)
  • Tons of what other people are up to from marketing to breaking into new markets.

additional fun was provided by the caricature painter, who managed to make me look better on paper than I have ever done so in real life.

One final thing, the night before the trip was as normal devoted to building the LDC freebies, so if you want one come pester either Matt White, Jullian Woodwood or me

catch you tomorrow

Adding a member to connections communities programmatically

Sometimes I get the feeling the powers at be are not giving the IBM developers quite the time they need to document stuff, IBM Connections is the best example of it I know, take this sterling example of how to add a member programmatically and even if they have slightly better versions such as this they are not a patch on the notes ones, so every time I hit one and end up solving it my self I thought I would do a proper guide

Note: all of my documentation assumes the worst case scenario that I can think off which in this case is to have the “emails not visible” setting on, which means the Atom feeds will NOT accept email address as parameters, if you need to get the userid for Atom is this is the case you can get it with this function

The Atom ‘add user’ and search functions detailed later CAN take an email address, but as IBM always give you best case scenarios, I’m giving you a worst case one.

Oh, shout out to Mikkel Flindt Heisterberg at http://lekkimworld.com/ who is the connections god, and pointed me in the right direction when I was having a head bashing moment on a custom names space issue for this.

Right so we want to add a user to a restricted community in IBM connections and we want to do this via the atoms feeds, the minimum XML I have found that you need to add a new user to a community is this

<entry xmlns="http://www.w3.org/2005/Atom" xmlns:snx="http://www.ibm.com/xmlns/prod/sn">                                   
    <contributor>                                                             
        <snx:userid xmlns:snx="http://www.ibm.com/xmlns/prod/sn">A5B8C712-27E5-596C-8625-7AC4000743C3</snx:userid>                                     
    </contributor>                                                                                                                               
</entry> 

It assumes you are adding them as a member, you submit this to the community member list url, which will be a bit like this
http://www.connectionssite.com/communities/service/atom/community/members?communityUuid=XXXXXXXXXXXX
where XXXXXXXXXXXX is the community ID which will be a string like this “c1l2a2e6-2e72-4a25-9a2f-l76e046a0d53”.
OK then we need a function to do this

 private String addUserAsAMemberofThisCommunity(String CommunityUnid, String adminUserName, String adminPassword, String baseURL, String memberlistURL, String UserIDtoAdd) throws NotesException {
        //Example parameters
        CommunityUnid = "c1l2a2e6-2e72-4a25-9a2f-l76e046a0d53"; 
        adminUserName = "Admin";
        adminPassword = "password";
        baseURL = "http://www.myconnections.com";
        memberlistURL = "/communities/service/atom/community/members?communityUuid="; 
        UserIDtoAdd = "A7B2C512-27E5-596C-8625-7AD4000843Z3";
        String ErrorReturn = "";
        try {
            //just incase some has passed the default user name for an Anonymous user
            if (!UserIDtoAdd.equals("Anonymous")) {
                Abdera abdera = new Abdera();
                AbderaClient client = new AbderaClient(abdera);
                AbderaClient.registerTrustManager();
                client.addCredentials(baseURL, null, null, new UsernamePasswordCredentials(adminUserName, adminPassword));
                Entry entry = abdera.newEntry();
                //thanks to Mikkel Flindt Heisterberg for telling me about this as i was doing it wrong
                javax.xml.namespace.QName contributornamespace = new QName("http://www.w3.org/2005/Atom", "contributor", "");
                javax.xml.namespace.QName useridnamespace = new QName("http://www.ibm.com/xmlns/prod/sn", "userid", "snx");
                ExtensibleElement contributorElement = entry.addExtension(contributornamespace);
                ExtensibleElement useridElement = contributorElement.addExtension(useridnamespace);
                useridElement.setText(UserIDtoAdd);
                ClientResponse response = client.post(baseURL + memberlistURL + CommunityUnid, entry);
                if (response.getStatus() != HttpURLConnection.HTTP_UNAUTHORIZED) {
                    ErrorReturn = "The User Id you are useing is noth athorised to do this";
                } else if (response.getStatus() != HttpURLConnection.HTTP_MOVED_TEMP) {
                        ErrorReturn = "You are most likly using a none ssl url to do this and connections wants a ssl link";
                } else if (response.getStatus() != HttpURLConnection.HTTP_CREATED && response.getStatus() != HttpURLConnection.HTTP_CONFLICT) {
                    ErrorReturn = "We could not add the user to the community automatically, it returned a status of: " + response.getStatus();
                }
            }
        } catch (ClassCastException e) {
            ErrorReturn = "Unknown Error: most likly the web service failed to respond";
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ErrorReturn;
    }

Well that works just fine, job done right?
yeahhhhh…..not quite
In Connections, if a restricted community is a subgroup of another community, you have to add the user to all the sub communities before you can add them to this one (RUDE WORD)
so we have to work out how to see if a community has a parent community, which we can do with this happy function

 private String getParentLink(String CommunityUnid, String baseURL, String adminUserName, String adminPassword, String communityInstance) throws NotesException {
        //Example parameters
        CommunityUnid = "c1l2a2e6-2e72-4a25-9a2f-l76e046a0d53"; 
        adminUserName = "Admin";
        adminPassword = "password";
        baseURL = "http://www.myconnections.com";
        communityInstance = "/communities/service/atom/community/instance?communityUuid="; 
        String parentLink = "";
        try {
            URL feedUrl = new URL(baseURL + communityInstance + CommunityUnid);
            Abdera abdera = new Abdera();
            Parser parser = abdera.getParser();
            XPath xpath = abdera.getXPath();
            AbderaClient client = new AbderaClient(abdera);
            AbderaClient.registerTrustManager();
            client.addCredentials(baseURL, null, null, new UsernamePasswordCredentials(adminUserName, adminPassword));
            ClientResponse resp = client.get(baseURL + communityInstance + CommunityUnid);
            org.apache.abdera.model.Document<Feed> doc = resp.getDocument();
            //this is not a normal entry based document it is a FOMEntry, so we have to caste it to that
            FOMEntry feed = (FOMEntry) doc.getRoot();
            //and we are not after a atom item we are after a link in the xml document this link is identified by its 'rel' attibute
            if (null != feed.getLink("http://www.ibm.com/xmlns/prod/sn/parentcommunity") || feed.getLink("http://www.ibm.com/xmlns/prod/sn/parentcommunity").getHref().toString().equals("")) {
                parentLink = feed.getLink("http://www.ibm.com/xmlns/prod/sn/parentcommunity").getHref().toString();
                HashMap restrictedParm = getURLParameters(parentLink);
                parentLink = restrictedParm.get("communityUuid").toString();
            }
        } catch (Exception e) {
            //e.printStackTrace();
        }
        return parentLink;
    }

We can then gather this all together into one function that will do the check for nested communities and add the user to all of them in the right order

 private String addtoAllSubCommunites(String CommunityUnid, String adminUserName, String adminPassword, String baseURL, String memberlistURL, String UserIDtoAdd, String communityInstance) throws NotesException {
        //Example parameters
        CommunityUnid = "c1l2a2e6-2e72-4a25-9a2f-l76e046a0d53"; 
        adminUserName = "Admin";
        adminPassword = "password";
        baseURL = "http://www.myconnections.com";
        memberlistURL = "/communities/service/atom/community/members?communityUuid="; 
        UserIDtoAdd = "A7B2C512-27E5-596C-8625-7AD4000843Z3";
        communityInstance = "/communities/service/atom/community/instance?communityUuid="; 
        String ErrorReturn = "";
        try {
            List communityList = new ArrayList();
            communityList.add(CommunityUnid);
            //lets see if this community is a member of another community
            String parentCommunityUnid = getParentLink(CommunityUnid, baseURL, adminUserName, adminPassword, communityInstance);
            if (parentCommunityUnid.equals("")) {
                ErrorReturn = addUserAsAMemberofThisCommunity(CommunityUnid, adminUserName, adminPassword, baseURL, memberlistURL, UserIDtoAdd);
            } else {
                //in case there are multiple nested communities, lets recurse down and get them all
                while (!parentCommunityUnid.equals("")) {
                    communityList.add(parentCommunityUnid);
                    parentCommunityUnid = getParentLink(parentCommunityUnid, baseURL, adminUserName, adminPassword, communityInstance);
                }
                //reverse the list of parent communities as we have to add the from the root upwards
                Collections.reverse(communityList);
                //now we can finaly add the user as a member of all the communities in the right order
                for (int i = 0; i < communityList.size(); i++) {
                    String tempparunid = communityList.get(i).toString();
                    ErrorReturn = addUserAsAMemberofThisCommunity(tempparunid, adminUserName, adminPassword, baseURL, memberlistURL, UserIDtoAdd);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ErrorReturn;
    }

There you go, I don’t know about you but it seems a lot of work just to add a user.
hope it helps.