RSS feed for blog Linkin Skype Mail Me Twitter

Stickfight

Blog Category: connections

SQuirrel SQL For IBM Connections

With the latest version Db2 (version 10.X) the native SQL client db2cc has been removed so you now need a separate SQL client for your admin work, this is a real ball ache, but something that us developers have been putting up with for ages, so I thought I would do a quick guide to install a nice SQL client for connections.

My recommendation for this is http://squirrel-sql.sourceforge.net/

why?

  • Been around for ages so well respected (even die hardened DBAs will acknowledge that your choice is not terrible)
  • FREE
  • Small footprint (just needs Java and you will already have that if you are doing connections dev/admin)
  • hellishly powerful
  • Uses IBM’s own jar files.
  • works on Win / Mac / Linux

There are tons of other options of course most, developers will be familiar with Eclipse SQL as that is the most common plug in for eclipse, where as some admins prefer Toad or IBM Data Studio

Once you have downloaded and run the install Jar you will only find one option worth mentioning, and that is to install the IBM DB2 option (just a tick box)


squSQL01.png

Everything else is just either next or picking the install directory

When you first open it you will get a screen like this


squSQL02.png

Click on the big “Drivers” button on the left hand side, and scroll down till you see “IBM DB2 App Driver” entry, you will see that like nearly all the other entries, it has a red X by it,


squSQL03.png

Now Double Click on the entry and in the pop up box, move to the “Extra Class Path” Tab


squSQL04.png

Next click on the “Add” button and go hunting for the driver Jar files, these are best to get of the DB2 server, they are:

db2jcc.jar

db2jcc_licence_cu.jar

and you will tend to find them in the directory

X:\Program Files\IBM\SQLLIB\java

where ever you have installed the db2 server

Once you have added them, change the “Class Name” drop down to

com.ibm.db2.jcc.DB2Driver


squSQL05.png

That’s you driver sorted, now make some connections

Click on the “Aliases” button then the “+” button to add a new Aliases


squSQL06.png

Select the driver you just setup, from the drop down field

Then in the URL field put the connection string for the database you want to get to in the format

jdbc:db2://XXX.XXX.XXX.XXX:50000/XXXX (port 50000 is the default port for db2)

for example

jdbc:db2://localdb2.ldc.com:50000/BLOGS

will get me the blogs database on my local server

for extra info here is the list of all the databases for the different connections Apps

Connections App: Files, DataBase: FILES

Connections App: Activities, DataBase: OPNACT

Connections App: Blogs, DataBase: BLOGS

Connections App: Communities, DataBase: SNCOMM

Connections App: Community Events, DataBase: SNCOMM

Connections App: BookMarks, DataBase: DOGEAR

Connections App: Forums, DataBase: FORUM

Connections App: HomePage , News, Search, DataBase: HOMEPAGE

Connections App: Metrics, DataBase: METRICS

Connections App: Mobile, DataBase: MOBILE

Connections App: Profiles, DataBase: PEOPLEDB

Connections App: Wiki, DataBase: WIKIS

Then just use enter the username and password (hint, you will NEVER get the lsuser account off your admin)

and click “OK”


squSQL07.png

You now have an alias that you can double click to connect to the specified database, you are going to have to create one for each of the Connections databases :( , but you can make things easier by right clicking on a alias and copying it so you only have to make changes rather than start again.


squSQL08.png

But it does seem a a pain to make everybody do this full setup, you can cheat even more by copying the SQLAliases23.xml file (it’s normally in a hidden directory in the users home drive but varies according to the operating system) and using it to replace the one on your target PC, all the aliases will then appear already setup.

Finally before this turns into a Squirrel sql manual, you can double click each of the aliases and not only see the database tree and gain access to the tables, but run SQL queries via the SQL tab at the top of the screen just under the normal menus.


squSQL09.png

Have Fun!!

NOTE: I’m not a proper Connections / Web Sphere admin, If you want proper Web Sphere and Connections admin you want the Turtle Partnership

Living Document: Connections Db Schema Versions

This page is just a living reference for thoese of us using the connections databases directly who want to make sure our code works by checking the db schemas before performing actions, you can see how to get these values in a previous post

If IBM would like to document this themselves (I know they wont as they dont want us near the dbs directly and want us to go via the APIs) I would be happy to bow out and point to their site :)

Connections App: Files

BD: FILES
Table: PRODUCT
Connections v4.0 BASE: 79
Connections v4.0 CR1: 79
Connections v4.0 CR2: 79
Connections v4.0 CR3: 79
Connections v4.0 CR4: 79
Connections v4.5 BASE: 82
Connections v4.5 CR1: 82
Connections v4.5 CR2: 82
Connections v4.5 CR3: 89
Connections v4.5 CR4: 89


Connections App: Activities

BD: OPNACT
Table: OA_SCHEMA
Connections v4.0 BASE: 53
Connections v4.0 CR1: 53
Connections v4.0 CR2: 53
Connections v4.0 CR3: 53
Connections v4.0 CR4: 53
Connections v4.5 BASE: 56
Connections v4.5 CR1: 56
Connections v4.5 CR2: 56
Connections v4.5 CR3: 56
Connections v4.5 CR4: 56


Connections App: Blogs

BD: BLOGS
Table: ROLLER_PROPERTIES
Connections v4.0 BASE: 43
Connections v4.0 CR1: 43
Connections v4.0 CR2: 43
Connections v4.0 CR3: 43
Connections v4.0 CR4: 43
Connections v4.5 BASE: 51
Connections v4.5 CR1: 51
Connections v4.5 CR2: 51
Connections v4.5 CR3: 51
Connections v4.5 CR4: 51


Connections App: Communities

BD: SNCOMM
Table: SNCOMM_SCHEMA
Connections v4.0 BASE: 76
Connections v4.0 CR1: 76
Connections v4.0 CR2: 76
Connections v4.0 CR3: 76
Connections v4.0 CR4: 76
Connections v4.5 BASE: 77
Connections v4.5 CR1: 77
Connections v4.5 CR2: 77
Connections v4.5 CR3: 77
Connections v4.5 CR4: 77


Connections App: Community Events

BD: SNCOMM
Table: CA_SCHEMA
Connections v4.0 BASE: 10
Connections v4.0 CR1: 10
Connections v4.0 CR2: 10
Connections v4.0 CR3: 10
Connections v4.0 CR4: 10
Connections v4.5 BASE: 15
Connections v4.5 CR1: 15
Connections v4.5 CR2: 15
Connections v4.5 CR3: 15
Connections v4.5 CR4: 15


Connections App: BookMarks

BD: DOGEAR
Table: DOGEAR_SCHEMA
Connections v4.0 BASE: 14
Connections v4.0 CR1: 14
Connections v4.0 CR2: 14
Connections v4.0 CR3: 14
Connections v4.0 CR4: 14
Connections v4.5 BASE: 15
Connections v4.5 CR1: 15
Connections v4.5 CR2: 15
Connections v4.5 CR3: 15
Connections v4.5 CR4: 15


Connections App: Forums

BD: FORUM
Table: DF_SCHEMA
Connections v4.0 BASE: 21
Connections v4.0 CR1: 21
Connections v4.0 CR2: 21
Connections v4.0 CR3: 21
Connections v4.0 CR4: 21
Connections v4.5 BASE: 27
Connections v4.5 CR1: 27
Connections v4.5 CR2: 27
Connections v4.5 CR3: 27
Connections v4.5 CR4: 27


Connections App: HomePage , News, Search

BD: HOMEPAGE
Table: HOMEPAGE_SCHEMA
Connections v4.0 BASE : 110
Connections v4.0 CR1 : 110
Connections v4.0 CR2 : 132
Connections v4.0 CR3 : 132
Connections v4.0 CR4 : 132
Connections v4.5 BASE: 210
Connections v4.5 CR1 : 210
Connections v4.5 CR2 : 210
Connections v4.5 CR3 : 211
Connections v4.5 CR4 : 213


Connections App: Metrics

BD: METRICS
Table: PRODUCT


Connections v4.0 CR2: 29
Connections v4.0 CR1: 29
Connections v4.0 CR2: 29
Connections v4.0 CR3: 30
Connections v4.0 CR4: 30
Connections v4.5 BASE: 34
Connections v4.5 CR1: 34
Connections v4.5 CR2: 37
Connections v4.5 CR3: 37
Connections v4.5 CR4: 37


Connections App: Mobile

BD: MOBILE
Table: ROLLER_PROPERTIES
Connections v4.0 BASE: 1
Connections v4.0 CR1: 1
Connections v4.0 CR2: 1
Connections v4.0 CR3: 1
Connections v4.0 CR4: 1
Connections v4.5 BASE: 1
Connections v4.5 CR1: 1
Connections v4.5 CR2: 1
Connections v4.5 CR3: 1
Connections v4.5 CR4: 2


Connections App: Profiles

BD: PEOPLEDB
Table: SNPROF_SCHEMA
Connections v4.0 BASE: 33
Connections v4.0 CR1: 33
Connections v4.0 CR2: 33
Connections v4.0 CR3: 33
Connections v4.0 CR4: 33
Connections v4.5 BASE: 36
Connections v4.5 CR1: 36
Connections v4.5 CR2: 36
Connections v4.5 CR3: 36
Connections v4.5 CR4: 36


Connections App: Wiki

BD: WIKIS
Table: PRODUCT
Connections v4.0 BASE: 79
Connections v4.0 CR1: 79
Connections v4.0 CR2: 79
Connections v4.0 CR3: 79
Connections v4.0 CR4: 79
Connections v4.5 BASE: 82
Connections v4.5 CR1: 89
Connections v4.5 CR2: 89
Connections v4.5 CR3: 89
Connections v4.5 CR4: 89



NOTE: All these tips are not officaliy sanctioned by IBM as they do not release DB schema info to the public, so you use them at your own risk, Also if IBM are reading this and I either have somthing wrong or you have documented this for the public, then please tell me and I will correct :-)

NOTE: I’m not a proper Connections / Web Sphere admin, If you want proper Web Sphere and Connections admin you want the Turtle Partnership

Connections Db Schema Tip2: Finding the UserID

Anyone who has had a dig around inside the back end SQL databases (or even compared a number of the ATOM feeds) for IBM Connections will have realised that ID’s are not a constant across the whole of Connections i.e. the userID that apparently created a file will not match the user ID that created a community even though you know that it was the same user that performed both actions, the reason for this is simple, IBM Connections was not build from the ground up as a cohesive whole, its a bunch of application and their databases that have been glued together, this makes it a bugger to link things together under the banner of a single user both for the more serious Developer and for Administrators trying restore/fix/edit records.

So I thought a little database relationship diagram would help make life a bit easier, the core of everything is the EMPLOYEE table in the PEOPLEDDB as that is where the global profile ID is generated for each person, you then have to find where that is mentioned in each of the applications individual member tables, from there you can use that to work out actually what that user has done in the system, thankfully most of the individual application database’s use the same sort of text identifier so they don’t cause a problem once you know they exist, the 2 exceptions are the FILES database which uses an IBM binary format (goodness know why, I’m guessing that it makes sense to use one for the files them selves and they were trying to be consistent within the FILES application) and the HOMEPAGE application in which the UNID is hidden inside a text string which you have to parse.

I will keep this diagram up to date, but please yell if you need more.

this diagram works equally well on both v4 and v4.5


ConnectionsIDS.png

NOTE: All these tips are not officaliy sanctioned by IBM as they do not release DB schema info to the public, so you use them at your own risk, Also if IBM are reading this and I either have somthing wrong or you have documented this for the public, then please tell me and I will correct :-)

NOTE: I’m not a proper Connections / Web Sphere admin, If you want proper Web Sphere and Connections admin you want the Turtle Partnership

Connections Db Tip1: getting the Connections db Schema version

One of the many little bundles of joy when dealing with back end SQL code on ‘living’* application such as IBM Connections, is that SQL that may have worked for one version or service pack might not work for another

To cater for this you might have to write for or at least be able to handle the diferent versions of a database, when doing this you tend not to use the actual product version ie “Connections 4.5.0.0.” but the db schema number for each database, thankfully IBM store the db schema for each database in Connections (though not with a great deal of consistency), the following is the SQL to get this for each of the databases that make up connections.

Connections App: Files

BD: FILES
Table: PRODUCT
Connection v4.5 Base Schema Number: 82

SQL to get Schema

SELECT SCHEMA_VERSION FROM "FILES"."PRODUCT";



Connections App: Activities

BD: OPNACT
Table: OA_SCHEMA
Connection v4.5 Base Schema Number: 56

SQL to get Schema

SELECT DBSCHEMAVER FROM "ACTIVITIES"."OA_SCHEMA";

Connections App: Blogs

BD: BLOGS
Table: ROLLER_PROPERTIES
Connection v4.5 Base Schema Number: 51

SQL to get Schema

SELECT DBMS_LOB.substr(VALUE, 3000) FROM "BLOGS"."ROLLER_PROPERTIES" where NAME = 'database.schema.version';

Notes: The rotten sods have stored it as a “Clob” data format (basically Binary) so the SQL is a bit more complex.


Connections App: Communities

BD: SNCOMM
Table: SNCOMM_SCHEMA
Connection v4.5 Base Schema Number: 77

SQL to get Schema

SELECT DBSCHEMAVER FROM "SNCOMM"."SNCOMM_SCHEMA";

Connections App: Community Events

BD: SNCOMM
Table: CA_SCHEMA
Connection v4.5 Base Schema Number: 15

SQL to get Schema

SELECT DBSCHEMAVER FROM "CALENDAR"."CA_SCHEMA";

Connections App: BookMarks

BD: DOGEAR
Table: DOGEAR_SCHEMA
Connection v4.5 Base Schema Number: 15

SQL to get Schema

SELECT DBSCHEMAVER FROM "DOGEAR"."DOGEAR_SCHEMA";

Connections App: Forums

BD: FORUM
Table: DF_SCHEMA
Connection v4.5 Base Schema Number: 27

SQL to get Schema

SELECT DBSCHEMAVER FROM "FORUM"."DF_SCHEMA";

Connections App: HomePage , News, Search

BD: HOMEPAGE
Table: HOMEPAGE_SCHEMA
Connection v4.5 Base Schema Number: 210

SQL to get Schema

SELECT DBSCHEMAVER FROM "HOMEPAGE"."HOMEPAGE_SCHEMA";

Connections App: Metrics

BD: METRICS
Table: PRODUCT
Connection v4.5 Base Schema Number: 34

SQL to get Schema

SELECT SCHEMA_VERSION FROM "METRICS"."PRODUCT";

Connections App: Mobile

BD: MOBILE
Table: ROLLER_PROPERTIES
Connection v4.5 Base Schema Number: 1

SQL to get Schema

SELECT VALUE FROM "MOBILE"."ROLLER_PROPERTIES" where NAME = 'database.schema.version';

Connections App: Profiles

BD: PEOPLEDB
Table: SNPROF_SCHEMA
Connection v4.5 Base Schema Number: 36

SQL to get Schema

SELECT DBSCHEMAVER FROM "EMPINST"."SNPROF_SCHEMA";

Connections App: Wiki

BD: WIKIS
Table: PRODUCT
Connection v4.5 Base Schema Number: 82

SQL to get Schema

SELECT SCHEMA_VERSION FROM "WIKIS"."PRODUCT";


*By living I mean ‘the feckers keep changing them’

NOTE: All these tips are not officaliy sanctioned by IBM as they do not release DB schema info to the public, so you use them at your own risk, Also if IBM are reading this and I either have somthing wrong or you have documented this for the public, then please tell me and I will correct :-)

NOTE: I’m not a proper Connections / Web Sphere admin, If you want proper Web Sphere and Connections admin you want the Turtle Partnership

Connections aide memoire 02: Backing Up Websphere Config

As a connections developer you will be fiddling with you local Websphere configuration, and down that road madness lays, so before you touch anything the make the whole thing go BANG! (and quite frankly that can be anything, you need to know how to backup and restore the config.

To do this first go to the bin directory of your deployment manager, in my test server’s case that is (yours will most likely be very similar except for it being on “E”)

E:\IBM\WebSphere\AppServer\profiles\Dmgr01\bin>


and just enter “backupconfig” giving the location of a new zip file you want created for everything to be stored in and wait for the stream of little dots to finish,

backupconfig e:\preLDAPchange.zip


On a web sphere server with a ‘medium’ Connections installation on it, This will give you a Zip file of about 775Meg so make sure you have the space (on a side note go have a look inside the zip it’s fascinating, like some sort of config abattoir)

hopefully you wont want it but say your change broke everything and you need to put it all back as it was, you run the ‘restoreconfig’ comand, as follows using the Zip file you created

restoreconfig e:\preLDAPchange.zip


Again, just wait for it to be done, and things should start working again.

Of course its all fully documented on the IBM website if you know to look Here And Here

NOTE: I’m not a proper Web Sphere admin, If you want proper Web Sphere and Connections admin you want the Turtle Partnership

Connections aide memoire 01: Changing XML config

Now that we are all “connections developers” according to IBM, sooner or later you will need to starting dealing with Web sphere in a serious fashion, this is no simple task, as Web Sphere admin as far more complex that developing for Web sphere and the documentation makes massive assumptions, so I will be doing a series of simple and essential tips for developers so make your life a bit easier, starting off will be changing XML config on connections.

Most of the connections config resides in a file called “LotusConnections-config.xml”, now there are copies of this file all over the place, to change them you check them all out, make the change in one place then check them back in, this not only keeps the changes consistent over your connections installation but it validates your changes and keeps a backup.

To do this first go to the bin directory of your deployment manager, in my test server’s case that is (yours will most likely be very similar except for it being on “E”)

E:\IBM\WebSphere\AppServer\profiles\Dmgr01\bin>


Then enter the wasadmin console with

wsadmin -lang jython


Next run the Connections Config jpython file

execfile("connectionsConfig.py")


Once that is done (after a load of output to the screen) you need to check out the config files, you need to provide a location to check the files out to (just create a directory somewhere safe) and the name of the web sphere cell you want to get the files from (see below on how to get that)

LCConfigService.checkOutConfig("E:\working","WIN-L5H5FQ2LKP1Cell01")


If you don’t know the name of the cell you are working on (hell I never know) you can find out by typing the following.

AdminControl.getCell()


You can now alter the files in the directory to suit what ever changes you want to make, the best way though is to use the “updateConfig” command which makes sure that you don’t make any bad types and screw your config up.

LCConfigService.updateConfig("profiles.directory.service.extension.enabled","false")


Once you are happy with your changes, you can check them them back in with the following (you will most likely need to restart the connections apps for the changes to take effect

LCConfigService.checkInConfig()


NOTE: I’m not a proper Web Sphere admin, If you want proper Web Sphere and Connections admin you want the Turtle Partnership

Adding a member to IBM 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.

Getting The User ID From IBM Connections - Addendum 1

As a little add on from This post on getting The User Id from IBM Connections, we discovered another little wrinkle, and that is the single sign on name that you get from @username in domino is not necessary the same as the what IBM connections is wanting in the ?Name= search parameter in its profile search, as we all should know the domino full name is not always the FirstName + ” ” + Last name then we tend to expect, so I just do a little lookup before running the function in the previous blog post

That is

String userid = convertSSOnametoFullName( userNab, agentContext.getEffectiveUserName().toString());
userid = getUserID( adminUserName, adminPassword, baseURL, ProfileNameSearch, userid);


The top function is below, the second function is here

private String convertSSOnametoFullName(  String NabNsf, String SSOUser) throws NotesException {
    System.out.println("convertSSOnametoFullName 0.1 " + SSOUser + NabNsf);
    
        String FullName = "";
        
        Session session = getSession();
        Database db = session.getDatabase(null, NabNsf);
        View view = db.getView("($VIMPeople)");
        DocumentCollection dc = view.getAllDocumentsByKey(SSOUser, true);
        //if we get more that 1 result then its a bad name to search and for security reasons we will return nothing
        if( dc.getCount() == 1) {
            Document nabdocument = dc.getFirstDocument();
            FullName = nabdocument.getItemValueString("FirstName") + " " + nabdocument.getItemValueString("LastName"); 
        } else if (dc.getCount() == 0){
            //we cant find that person in this address book so I going to return the name they put in as opposed to a blank, in case its a valid name in another address book
            FullName = SSOUser;
        }

        System.out.println("end convertSSOnametoFullName 0.1 " + FullName + " " + dc.getCount());
    return FullName; 
}

Getting The User ID From IBM Connections

IBM Connections has an evil setting that disables emails from being seen on the system, this is meant as a security setting, but it not only hides the email from the front end but from all the atom feeds, suddenly you don’t have a unique key to reference users on functions.

Well that’s not exactly true, you have a internal ID that IBM functions will accept instead e.g “A7B2C512-27E5-596C-8625-7AD4000843Z3”, the only problem is how in the heck do you GET HOLD OF IT?

If you are within a community you can get it from member lists and such but how about when you want to just want to get a name that is on the system, say to add it to a community, the only way I have found is to search for it and no you cant search for it by email as that is disabled.

You have to search for it by name which while not exactly precise does the job but even that is not an ultra easy function, here is a little function to do it for you.

    private String getUserID( String adminUserName, String adminPassword, String baseURL, String ProfileSearchURL, String SearchUser) throws NotesException {
        String Unid = "";
        try {
            // example values for the passed parameters.
            adminUserName = "administrator"; 
            adminPassword = "password"; 
            baseURL = "https://www.myconnectionsSite.com"; 
            ProfileSearchURL = "/profiles/atom/search.do?name="; //sthis is what connections 4 uses 
            SearchUser = "John Smith";
            
            //build our search string
            String searchString = baseURL + ProfileSearchURL + URLEncoder.encode(SearchUser, "UTF-8");
            
            Abdera abdera = new Abdera();
            AbderaClient client = new AbderaClient(abdera);
            //ensure we can handle SSL requests
            AbderaClient.registerTrustManager();
            //logon to connections
            client.addCredentials(baseURL, null, null, new UsernamePasswordCredentials(adminUserName,adminPassword));
            
            //make the call
            ClientResponse resp = client.get(searchString );
                        
            XPath xpath = abdera.getXPath();
                       
            //get the xml back an navigate to the root of the document
            org.apache.abdera.model.Document doc = resp.getDocument();
            Feed feed = (Feed) doc.getRoot();          
             
            //if there is more than 1 returned entry then the user name is none unique and we cant trust our response
            if (xpath.numericValueOf("count(/a:feed/a:entry)", feed).intValue() > 1) {
                System.out.println("Ack we have more than 1 user with that name I cant be certain I have got the right one");
            } else {
                //as there is only one entry we can navigate straight down to the contributer sectnio which contains the user id
                Object contrubuternode = xpath.selectSingleNode("/a:feed/a:entry/a:contributor", feed );
                //because of the "snx" part we cant get the value without passing xpath our namespaces from the feed so it knows what "snx" means
                String snxUserid = xpath.valueOf("snx:userid", (Base) contrubuternode, feed.getNamespaces());
                
                Unid = snxUserid;   
            }

        } catch (ClassCastException e) {
            System.out.println("no user found or some other garbage return");
            e.printStackTrace();
            Unid = ""; 
        } catch (Exception e) {
            e.printStackTrace();
        }
        
        return Unid;
    } 
Latest Blogs