Determing what cluster a user is on?

Version 1
    This document was generated from CDN thread

    Created by: Chris Bomba on 19-08-2010 08:21:21 PM
    I have three differente Unity Connection clusters and I have a problem with training users to go to the right home server to access their CiscoPCA user page.  Since CUC doesn't support any redirects on user logins that is a problem.  I want to create a simple page that will allow a user to enter either their user ID or last name and I would query the directory to see which cluster the user is on and return a link or just automatically redirect the users to the login page so they can log into their home server. 
     
    I am not a developer, I am the engineer who put the clusters in but if I get a good start I think I could do the research to figure it out.  Please let me know if anyone can help with this.
     
    Chris

    Subject: RE: Determing what cluster a user is on?
    Replied by: David Wanagel on 19-08-2010 08:21:21 PM
    The CUPI interface allows access to users and one of the fields on the user is their location URI.  If you use that URI you will get the information on that user's location and one of the fields on the location is the SmtpDomain that should effectively be the user's home server.
     
    Note, there appears to be a bug in the user location URI field right now.  It comes back like this:
     
    /vmrest/locations/aff78b0e-6c7f-4c9f-8a39-d7cc754bfbeb
     
    But should actually be
     
    /vmrest/locations/connectionlocations/aff78b0e-6c7f-4c9f-8a39-d7cc754bfbeb
     
    Until we get that fixed you will need to manually insert "connectionlocations/" after "locations/" in the URI returned by Connection.
     
    -Dave

    Subject: RE: Determing what cluster a user is on?
    Replied by: Chris Bomba on 19-08-2010 08:21:21 PM
    That worked.  I am using Perl to query the API then parse the XML to get the LocationURI.  I then add the "/connectionlocations" and query again.  This time I parse the XML for SmtpDomain and HostAddress fields. 
     
    I have one problem though.  When I do a query for the users by lastname and I get multiple users I don't know how to parse that.  Here is what is returned.  I need to be able to grab the FirstName, LastName, DtmfAccessId, and LocationURI.  That way I can then search for each of those LocationURIs and get the SmtpDomain for each.  I can then send that information back to the webpage for the user to confirm (User1 BasicUser @ 8918881266)
     
    $VAR1 = {
              'GlobalUser' => [
                              {
                                'FirstName' => 'User1',
                                'LocationObjectId' => '6f3b0448-2a3e-4379-ba2d-dc67d467461e',
                                'LastName' => 'BasicUser',
                                'DisplayName' => 'User1 BasicUser',
                                'ListInDirectory' => 'true',
                                'PartitionObjectId' => '6e7f4992-322d-4f71-84ca-98722f02a4ff',
                                'VoiceFileURI' => '/vmrest/voicefiles/e5dc2a35-0967-4dd3-ad3e-a4d9fe6a6898.wav',
                                'DtmfAccessId' => '8918881266',
                                'LocationURI' => '/vmrest/locations/6f3b0448-2a3e-4379-ba2d-dc67d467461e',
                                'URI' => '/vmrest/globalusers/19430e88-266b-4310-8d3d-c57027d8f9da',
                                'DtmfNameFirstLast' => '2474786743726622',
                                'ObjectId' => '19430e88-266b-4310-8d3d-c57027d8f9da',
                                'Alias' => 'U1BasicUser',
                                'VoiceName' => 'e5dc2a35-0967-4dd3-ad3e-a4d9fe6a6898.wav',
                                'PartitionURI' => '/vmrest/partitions/6e7f4992-322d-4f71-84ca-98722f02a4ff',
                                'DtmfNameLastFirst' => '2662224747867437',
                                'XferString' => {},
                                'IsTemplate' => 'false'
                              },
                              {
                                'FirstName' => 'User2',
                                'LocationObjectId' => '6f3b0448-2a3e-4379-ba2d-dc67d467461e',
                                'City' => 'Berkeley',
                                'LastName' => 'BasicUser',
                                'DisplayName' => 'User2 BasicUser',
                                'ListInDirectory' => 'true',
                                'PartitionObjectId' => '6e7f4992-322d-4f71-84ca-98722f02a4ff',
                                'VoiceFileURI' => '/vmrest/voicefiles/e0a93e4f-bf54-4b28-b177-2f43ca483b8b.wav',
                                'DtmfAccessId' => '8918888410',
                                'LocationURI' => '/vmrest/locations/6f3b0448-2a3e-4379-ba2d-dc67d467461e',
                                'URI' => '/vmrest/globalusers/d71ba767-10ef-4489-889f-89a66fc19242',
                                'DtmfNameFirstLast' => '2474786743726622',
                                'ObjectId' => 'd71ba767-10ef-4489-889f-89a66fc19242',
                                'Alias' => 'BRK8410',
                                'VoiceName' => 'e0a93e4f-bf54-4b28-b177-2f43ca483b8b.wav',
                                'PartitionURI' => '/vmrest/partitions/6e7f4992-322d-4f71-84ca-98722f02a4ff',
                                'DtmfNameLastFirst' => '2662224747867437',
                                'XferString' => {},
                                'IsTemplate' => 'false'
                              },
                              {
                                'FirstName' => 'User3',
                                'LocationObjectId' => '6f3b0448-2a3e-4379-ba2d-dc67d467461e',
                                'LastName' => 'BasicUser',
                                'DisplayName' => 'User3 BasicUser',
                                'ListInDirectory' => 'true',
                                'PartitionObjectId' => '6e7f4992-322d-4f71-84ca-98722f02a4ff',
                                'DtmfAccessId' => '8918885499',
                                'LocationURI' => '/vmrest/locations/6f3b0448-2a3e-4379-ba2d-dc67d467461e',
                                'URI' => '/vmrest/globalusers/af1eb688-c883-423b-8fc7-c664c572058f',
                                'DtmfNameFirstLast' => '2474786743726622',
                                'ObjectId' => 'af1eb688-c883-423b-8fc7-c664c572058f',
                                'Alias' => 'PTB5499',
                                'DtmfNameLastFirst' => '2662224747867437',
                                'XferString' => {},
                                'PartitionURI' => '/vmrest/partitions/6e7f4992-322d-4f71-84ca-98722f02a4ff',
                                'IsTemplate' => 'false'
                              }
                            ]
            };

    Subject: RE: Determing what cluster a user is on?
    Replied by: Matthew Penning on 19-08-2010 08:21:21 PM
    Hi Chris - I'm not sure exactly what you're asking. Looks like you get back a list of the users that match the last name okay, and it appears they end up in an array in Perl that you ought to be able to access by index (no?)
     
    - Matt

    Subject: RE: Determing what cluster a user is on?
    Replied by: Chris Bomba on 19-08-2010 08:21:21 PM
    Hi Chris - I'm not sure exactly what you're asking. Looks like you get back a list of the users that match the last name okay, and it appears they end up in an array in Perl that you ought to be able to access by index (no?)
     
    - Matt



     
    Yes, I get the above returned as an array.  The following code prints out my previous post.

    1# read XML file
    2my $user = XMLin($page, ForceArray => 1, KeyAttr => {GlobalUsers => 'GlobalUser'});
    3
    4# print Data
    5print Dumper($user);



     
     
    If I try to then print the array I get the following:
    1#print array
    2print $user ->{GlobalUser} ->[0];



     
    I get this:   HASH(0x25320e4)
     
    If I try this:
    1#print array
    2print $user ->{GlobalUser};



     
    I get this:   ARRAY(0x259e98c)
     
    I would like to write a loop to collect the display name and extension as well as the location information then do a query for each of those users to return to the webpage so they user can select the correct account.

    Subject: RE: Determing what cluster a user is on?
    Replied by: Chris Bomba on 19-08-2010 08:21:22 PM
    I made some progress but I am still stuck.
     
    I am trying to get the array working correctly:
    1# read XML file
    2my $user = XMLin($page, ForceArray => 1, KeyAttr => {GlobalUsers => 'GlobalUser'});
    3
    4my @array = Dumper($user->{GlobalUser});
    5 
    6print @array


     
    The above code prints the whole array and by changing the last line to print @array[0] it still prints the whole array.  The problem I have now is with the foreach statement.

     
     1my $count = 1;
     2 
     3 # print Data
     4 foreach my $list(@array)
     5     {
     6     print "<tr><td>$count</td><td>$list</td></tr>";
     7     $count++;
     8     }
     9 print "</table>";


     
    The above code returns the whole array in one table cell.  I would expect to see three cells with a lot of information in each one.

    Subject: RE: New Message from Chris Bomba in Cisco Unity Connection Provisioning Int
    Replied by: Matthew Penning on 19-08-2010 08:21:22 PM
    Hi Chris - I asked around since I don't do much Perl myself, and here's
    what I heard back on it:
    He mentions printing @array and @array[0].

    Sigil invariance is something introduced in Perl6, which I do not
    believe he is using.

    The correct way to access a value in an array would be $array[0]. Since
    the item would be a scalar, not a list.

    For instance...

    my @arr = ([1,2], [3,4], [5,6]); // an array with 3 array refs

    for my $list (@arr) { // $list would hold an array ref

    my @innerArray = @$list; // deref

    }


    ________________________________

    From: Cisco Developer Community Forums
    [mailto:cdicuser@developer.cisco.com]
    Sent: Tuesday, January 05, 2010 7:03 AM
    To: cdicuser@developer.cisco.com
    Subject: New Message from Chris Bomba in Cisco Unity Connection
    Provisioning Interface (CUPI) - CUPI Questions: RE: Determing what
    cluster a user is on?


    Chris Bomba has created a new message in the forum "CUPI Questions":
    --------------------------------------------------------------
    I made some progress but I am still stuck.

    I am trying to get the array working correctly:

    1# read XML file
    2my $user = XMLin($page, ForceArray => 1, KeyAttr => {GlobalUsers =>
    'GlobalUser'});
    3
    4my @array = Dumper($user->{GlobalUser});
    5
    6print @array



    The above code prints the whole array and by changing the last line to
    print @array[0] only gives me the first response.  The problem I have
    now is with the foreach statement.


    1my $count = 1;
    2
    3# print Data
    4foreach my $list(@array)
    5    {
    6    print "<tr><td>$count</td><td>$list</td></tr>";
    7    $count++;
    8    }
    9print "</table>";



    The above code returns the whole array in one table cell.  I would
    expect to see three cells with a lot of information in each one.
    --
    To respond to this post, please click the following link:
    <http://developer.cisco.com/web/cupi/forums/-/message_boards/message/187
    6428>
    or simply reply to this email.

    Subject: RE: New Message from Chris Bomba in Cisco Unity Connection Provisioning Int
    Replied by: Timothy Trinh on 19-08-2010 08:21:22 PM
    Based on the data structure that has been posted from the 'Dumper($user)' command, you should be able to extract the information from it with the following loop:
     

    foreach my $hrUser (@{$user->{GlobalUser}}) {
        print "First Name   = [" . $hrUser->{FirstName} . "]\n";
        print "Last Name    = [" . $hrUser->{LastName} . "]\n";
        print "Display Name = [" . $hrUser->{DisplayName} . "]\n";
        print "Location URI = [" . $hrUser->{LocationURI} . "]\n\n";
    }

     
    I hope this helps. 
     
    -Timothy

    Subject: RE: New Message from Chris Bomba in Cisco Unity Connection Provisioning Int
    Replied by: Chris Bomba on 19-08-2010 08:21:22 PM
    Thank you for the response.  When I use this loop, I get the following:
     
    First Name   = [ARRAY(0x1ff4b84)]
    Last Name    = [ARRAY(0x1ff4bd4)]
    Display Name = [ARRAY(0x1ff4aa4)]
    Location URI = [ARRAY(0x1ff4c44)]
    First Name   = [ARRAY(0x1ff49e4)]
    Last Name    = [ARRAY(0x1ff4a34)]
    Display Name = [ARRAY(0x1ff4eb4)]
    Location URI = [ARRAY(0x1ff4ad4)]
    First Name   = [ARRAY(0x1ff5144)]
    Last Name    = [ARRAY(0x1ff5194)]
    Display Name = [ARRAY(0x1ff50d4)]
    Location URI = [ARRAY(0x1ff5204)]

    Subject: RE: New Message from Chris Bomba in Cisco Unity Connection Provisioning Int
    Replied by: Matthew Penning on 19-08-2010 08:21:22 PM
    Hi Chris - I think the problem is ForceArray is set in your call - that results in each attribute being stuck in an array.
     
    Here's a really tiny working example:
     
    #!/usr/bin/perl -w
    use strict;

    use XML::Simple;
    use Data:umper;

    my $xs = new XML::Simple(KeyAttr=>[]);
    my $data = $xs->XMLin("<GlobalUsers><GlobalUser><Alias>User1</Alias></GlobalUser><GlobalUser><Alias>User2</Alias></GlobalUser></GlobalUsers>");

    print "Output from dumper:\n";
    print Dumper($data);

    print "\n\nOutput from iterating:\n";

    my $u;
    foreach $u (@{$data->{GlobalUser}})
    {
        print $u->{Alias}, "\n";
        print "\n";
    }

    exit;

    Subject: RE: New Message from Chris Bomba in Cisco Unity Connection Provisioning Int
    Replied by: Chris Bomba on 19-08-2010 08:21:22 PM
    That worked.  Here was the final code.  I can now search by lastname and if there are multiple records returned I will show all records.
     
     1 #Retrieve the page
     2$mechanize->get("$url/vmrest/globalusers?query=(lastname startswith $lastname)");
     3
     4# Assign the page content to $page
     5my $page = $mechanize->content;
     6
     7# read XML file
     8my $user = XMLin($page, KeyAttr => {GlobalUsers =>'GlobalUser'});
     9
    10my $u;
    11my $locationuri;
    12my $displayname;
    13my $dtmfaccessid;
    14foreach $u (@{$user->{GlobalUser}})
    15    {
    16
    17# Assign the LocationURI value to variable
    18$locationuri = $u->{LocationURI};
    19
    20# Assign the DisplayName value to variable
    21$displayname = $u->{DisplayName};
    22
    23# Assign the DtmfAccessId value to variable
    24$dtmfaccessid = $u->{DtmfAccessId};
    25
    26# replace /vmrest/locations with /vmwrest/locations/connectionlocations
    27$locationuri =~ s/vmrest\/locations\//vmrest\/locations\/connectionlocations\//;
    28
    29# Retrieve the page
    30$mechanize->get("$url$locationuri");
    31
    32# Assign the page content to $page2
    33my $page2 = $mechanize->content;
    34
    35# read XML file
    36my $location = XMLin($page2);
    37
    38# Assign the HostAddress value to variable
    39my $hostaddress = $location->{HostAddress};
    40
    41# Assign the Redirect URL value to variable
    42my $redirect = "https://$hostaddress/ciscopca";
    43
    44print "<center>For $displayname  @ $dtmfaccessid -> <a href=\"$redirect\">Click here to be redirected</a></center> <br>";
    45}


    Subject: RE: New Message from Chris Bomba in Cisco Unity Connection Provisioning Int
    Replied by: Chris Bomba on 19-08-2010 08:21:22 PM
    Okay, one last question.  After I fixed the looping through array questions I broke something else.  Now when I search by last name and it only returns one value I get the following error.
     
    Not an ARRAY reference at line 37.
     
    Line 37 corresponds to:
     
    foreach $u (@{$user->{GlobalUser}})
     
    How do you check to see if the result is an array at all first, then if it is process it with the above code but if it isn't, then process it like I am doing with the Alias?

    Subject: RE: New Message from Chris Bomba in Cisco Unity Connection Provisioning Int
    Replied by: Timothy Trinh on 19-08-2010 08:21:22 PM
    You can check whether a variable is an array reference or not by using the "ref" built-in function. Here's an example:
     
    if ( ref($user->{GlobalUser}) eq 'ARRAY' ) {
        print "\$user->{GlobalUsers} is an array reference.\n\n";
    }
     
    Yes, you are working with an array reference because you noticed that you have to cast it back as an array in the foreach loop with @ character (i.e. @{$user->{GlobalUser}}). 
     
    By the way, you may want to consider looking into using the XML::LibXML Perl module. It'll allow you to interact with XML data directly. I believe that module should already be available on Linux and Mac with its Perl package. As for Windows, with the ActiveState Perl, you'll need to download that module from http://theoryx5.uwinnipeg.ca/ppms/package.xml repository using PPM (Perl Package Manager).
     
    I hope this helps.
     
    -Timothy