Marketers goes where the eyeballs are. We look at "social" media, so how can we be surprised by the invasion? But I'm still disappointed when I encounter blatant gaming of the channels that supposedly are trusted sources of information from "people" like us.

L7sWA[1].jpgLet me introduce you to Anne Waterhouse. She lives in New York, and judging by her photo, she's a lovely mix of saucy and innocent (who isn't drawn by that?), and she is of modest means (just like the rest of us!). She tweets as @annewaterhouse about things that interest her nearly 2000 followers. It's good content. Funny posts from Failblog, smart content from Alltop, tech goodness from Mashable, and helpful tips from Lifehacker.

The problem is she isn't real.

I met Anne because yesterday she tweeted about a short video that my cycling buddy made. She picked it up from thought-leader Guy Kawasaki's blog. "How to make better presentations in 2:53 " she said.

Cool! Kawasaki likes Marc's video, and someone shared it on Twitter. When I looked at her Twitter page, I was surprised by the pace at which she posted. How could she consume so much web content? Who was she? Her profile revealed little. I scanned the timestamps, and I realized she had posted in each of the preceding 24 hours. Ah, she's superhuman and doesn't need sleep?

The constantly changing Twitter API now allows you to access the latest 200 tweets from a person using URLs like this: https://api.twitter.com/1/statuses/user_timeline.rss?screen_name=annewaterhouse&count=200. I grabbed her tweets and extracted the timestamps using this:

grep -i pubdate tweets.xml | sed s/".*<pubDate>"//g | sed s/"<\/pubDate>"//g > timestamps.xml

I then brought those into Excel and made histograms by day, then combined them to show all three days overlapping. This amazing woman tweeted 200 times in the past 37 hours. Check it out (or download spreadsheet):

annewaterhouse.tweets.jpg
Okay, fine, she has some automated tool that retweets the RSS feeds from her favorite sites. Some of her tweets like this one are generated by TwitterFeed.com. That doesn't mean she's not real. Is a real person behind these? Maybe she talks with her friends too? Well, no. In these 200 tweets, I used grep -v to filter out messages that didn't include a link as would come from the RSS feeds, and there was nothing left. I filtered for "@" mentions of other users and found none.

Who set this up? Is this the creation of one of the websites that she links back to? Are they trying to drive their own traffic? The idea is clearly a good one, based on the thousands of people following these garbage tweets. Is there a marketer/exploiter out there who discreetly sells this to websites? "Give me $500 for your own @annewaterhouse. I guarantee she'll share interesting content and garner a following, and this will drive traffic to your site." Does that exploiter use the metrics available from URL shortener sites that generate the links to then charge its customers advertising? "Give me two cents per click into your site." Do they go to the trouble of using so many URL shortener services to make it look less automated?

And to think my friend and I were pleased that she shared a link to his video. Well, I guarantee Guy Kawasaki is real, and he's the one whose opinion matters. Now let's stop thinking about social media and learn how to give better presentations when we're dealing with real people:


How To: Bulk download from Sharepoint

| | Comments (0)
This post goes in the "Why wasn't I able to Google that?" category. Remember this old comic?

100322_cartoon_6_a14837_p4651[1].gif
It turns out things that seem like they should be easily Googleable aren't. Maybe this post will be helpful to someone else out there.

I've been helping a small business migrate off Sharepoint and onto a local NAS device (Dlink DNS-323). They have about 4000 documents in 300 folders on Sharepoint hosted by Microsoft Online. How to do a bulk download? The Sharepoint UI (that they hated so much that they asked me if I could migrate them off it) gives no clues. I did searches for these without turning up anything good:

sharepoint "bulk download" "microsoft online"
bulk download sharepoint.microsoftonline.com
sharepoint server 2007 bulk download

Many people offer bulk upload tools, but what about bulk download? Certainly people want to change technologies now and again. I saw one discussion thread that vaguely mentioned WebDAV, but I found nothing about it in the online help, and I found very little for this Google search:

 "microsoft online services" webdav sharepoint

Finally I just gave it my best shot. If it does support WebDAV, which the web hasn't confirmed for me, then how would I go about it?

network-places_smallco.jpgMy laptop runs XP (still my favorite environment), so I used these steps:

  1. My Network Places
  2. Add Network Place
  3. Next
  4. Choose another network location
  5. Enter URL to Sharepoint site: https://smallcomicrosoftonlinecom-2.sharepoint.microsoftonline.com/Shared%20Documents/
  6. Give same credentials used to log into Sharepoint

The laptop of the person for whom I was doing this migration runs Vista, so the process is a little different there. I connected them using notes from a forum:

  1. Hit start menu and go to "Network"
  2. Hit Alt-button to get the tools-menu.
  3. Go to Tools -> Map Network Drive
  4. Click on the link on the bottom that says "Connect to a website that you can use to store your documents and pictures"
  5. Hit Next
  6. Choose "Choose a custom network location" and hit Next.
  7. Enter your url location...

Well, the instructions from here weren't a perfect fit, but on Vista, basically, enter the URL to Sharepoint, then the credentials, then maybe select the drive this will map to.

After connecting by WebDAV, I was able to access the entire Sharepoint site as a folder in Windows Explorer, and I could then open that folder and copy its entire contents to a local disk drive. I brought it to the laptop first, then I copied it onto the NAS drive.

At this point, the folks I'm helping out were able to disable Sharepoint logins for everyone but the administrator. They'll let their Sharepoint subscription lapse at the end of the month, which they're very happy about.

By the way, the DNS-323 that I wrote about and to which I gave a glowing review? It has extraordinarily frustrating user and group management through the web interface. Users can only belong to a single group. So if you want to have a group for managers who would access the /managers share, then a group for accounting who would access the /accounting share? You can't do it with the standard UI. As soon as you add the manager Adam to the accounting group, he is taken out of the manager group. I wound up having to telnet into the server to edit the undocumented, non-standard config file (/mnt/HD_a4/.systemfile/.smb.ses). I don't recommend this NAS for use outside the home.
spy-display.jpgDo you work with people who need to analyze PTspy logs on their desktop but who don't have the Spy reader available to get those logs into an easy-to-read format?

Back in the day, BEA put out an installer called LoggingUtilities_PTspy with the executable file  ALILoggingUtilities_v1-1_MP1.exe. If you still can find that installer, you can use it to install the Spy reader. The format of .spy logs hasn't changed, so that old reader works for the latest and greatest (or worst) logs.

But that installer was only for 32-bit machines. If you're working with Windows 7, then you need another approach. My recommendation is that you use the regular (and unfortunately huge) component installer, install something that includes the Spy reader, then delete the components you didn't want. The steps I used to do so follow.

Run the WebCenterInteraction_10.3.3.0.0.exe installer. At the prompts, enter the following:

--

Installation folder: (your choice. i'm choosing c:\apps\plumtree).

Choose components: Check ONLY Automation Service.

If you get a Dependency Warning about Microsoft Visual C++, then "Yes, launch the installer."

Configuration Manager - Port and Password: Accept the default port of 12345 and leave the password blank.

Password inconsistency: Click "Continue" to keep the blank password.

Pre-Installation Summary: Click install.

Launch Configuration Manager: Just click next.

Application Settings Confirmation: Select "No, configure later," then click next.

Install Complete: Select "No, I will restart my system myself," then click done.

--

PTSpy is now available on your machine. You don't need to reboot.

run-cmd-as-admin.jpgHowever, your computer also has three services installed that you probably don't want. To remove them, you need to run commands in a command prompt that runs with elevated administrator privileges. To get that command prompt, click the start button and type "cmd" into the search box. You'll see cmd.exe is one of the search results.
Right click on it, then select "run as administrator."

cmd-paste.jpgNow in that prompt, paste in the following commands (to paste, right-click the title bar, click edit, click paste). You can paste these all in at the same time:

@rem -- make sure all services are stopped
sc stop "oracle wci logger"
sc stop ConfigurationManager12345
sc stop ptautomationserver

@rem -- now delete them
sc delete "oracle wci logger"
sc delete ConfigurationManager12345
sc delete ptautomationserver


That should do it. You should see output like this:

C:\Windows\system32>sc delete "oracle wci logger"
[SC] DeleteService SUCCESS

C:\Windows\system32>sc delete ConfigurationManager12345
[SC] DeleteService SUCCESS

C:\Windows\system32>sc delete ptautomationserver
[SC] DeleteService SUCCESS

The install put just over 800mb of files on your machine, but most of those are not related to ptspy. You can delete about 600mb of these by deleting unnecessary files and folders.

Open the folder C:\apps\plumtree\common and delete these:

container
icu
inxight
outsidein
pthreads
wrapper

Then open the folder C:\apps\plumtree and delete these:

configmgr
descriptors
jre142
jre160
ptportal
uninstall

Now on to analyzing spy files!

What Oracle engineering should do though is put an option in the WCI installer for just the Spy logging toolkit (it won't be in WCI 10.3.3). Maybe some day...

Enjoy!


ptdell.jpgUniverse: I am resigning from Oracle.

I know the universe of interested parties shrinks every year as the sales of the WCI portal (née Plumtree) decline, Oracle promotes a different product, and old customers move on to new platforms. But! Some of you are still out there reading, and so thanks!

Fortunately for you all, I'm not going far. I'll continue working with the WCI portal for a long-time customer, Boeing, for whom I've consulted off and on, but mostly on, since 2004. So the blog entries will continue to sporadically pop into your RSS feeds.

I have three company laptops that I need to return. The newest one Oracle issued to me several months ago, and I'm sure it will be redeployed to another employee. The older ones, however, will likely be "decommissioned." Occasionally I read stories about crooks who buy old hard drives to recover their data and then engage in all sorts of nefarious crimes. I don't want my data open to that risk. Since I don't know exactly what Oracle's decommissioning process is, and since any company's processes may not be perfectly followed, I decided to take extra care to destroy the personal, customer, and corporate data that had been on the hard drives.

So here's what I'm doing tonight, and you probably should do something similar when you let go of your old laptops, whether you're disposing of an old personal machine or resigning from the job that had run its course:

  1. buddha-baby.jpgCopy any needed data off the old laptop (e.g. this photo from when kiddo was a newborn)
  2. Create a "live cd" or a bootable disk with a *nix operating system on it. I used Ubuntu (get it).
  3. Boot your old laptop from the CD. On my Dell laptop, I used F12 to get a one-time boot menu to select that I wanted to boot from CD rather than from the hard drive.
  4. Identify the partition name for your disk. I did this by going to System -> Administration -> GParted Partition Editor.
  5. Open a console.
  6. Type a command like this one at the prompt, where /dev/sda2 is my laptop partition to wipe:

    sudo shred -vfz -n 1 /dev/sda2

  7. Wait while the machine overwrites your entire disk first with random data, then with zeros.

That's it. There's not much left to find on the drive. This is a much better approach than just reformatting the drive, because reformatting merely clears the address tables for the disk but still leaves the data intact and retrievable by Dr. Evil who makes his business doing such things. Of course, you could be more fastidious than I was. Another blog gives a more detailed review of the technical issue and even more thorough ways to knock it out.

After erasing the data, I went the extra mile to installed Ubuntu. This way anyone who turns on the computer will be able to log in and see that nothing is readily available, and they'll also find it to be a generally useful machine.

Enjoy.

PS: Yes, I'm extraordinarily happy to move on from Oracle!
Publisher is an old product, but it still has legs in some organizations. I recently helped a customer set up Publisher to load balance the portion of the app used by browsing users, the readers, of published content. The discussions about how to set this up were difficult until I diagrammed the components clearly.

If you ever need to work with Publisher, an especially if you want to increase reliability of the reader component, then I hope this diagram will be helpful to you.

Enjoy!

publisher-drawing.jpg

F5 Terminology Cheat Sheet

| | Comments (0)
corporate acronyms.jpgTechnology is a land of overlapping and confusing terminology. I've been involved in plenty of confusing conversations about F5 products as they relate to WCI portal deployments, and I've worked to develop a more precise use of terms. To help a colleague sort out the mishmash, I made this list of objects we commonly discuss. Maybe you'll find it useful to?

In addition to understanding the terms, I think it's helpful to recognize areas of overlap and be careful to avoid confusion. For example, since the VMWare team thinks "virtual servers" run an operating system and the F5 team thinks "virtual servers" represent pathways through their network, I like to say "F5 virtual server" or "VMWare virtual server."

Objects
GTM (routes between LTMs)
- Wide IPs represent services. An URL is associated with the Wide IP so that users can route through here. Wide IPs can have iRules.
- Pools are configured under Wide IPs.
- Members are assigned within the pools. We create a region1 and a region2 member. These members point to the IP addresses and ports of LTM virtual servers. Normally (but not always) they are given names that match the LTM virtual servers.

LTM (routes within a region)
- Virtual servers represent services. They have IP addresses and they listen on a port. They can have iRules. When multiple host names are required for the same service, those host names can all alias to the IP of the virtual server (e.g. http://portlets and http://portlets2).
- Pools are configured under virtual servers. One pool can be used by multiple virtual servers, as we do in an environment with the imageserver pool, since we need both HTTP and SSL access to those resources. The customer usually assigns monitors to these, and the monitor applies to every member in the pool.
- Members are assigned within the pools. They are represented by the IP address of the server hosting the service and the port of that service, though the port doesn't have to be the same one used by the virtual server. Customers doesn't usually assign monitors to these, though it could be done.
- Nodes we don't talk about much. These are the IP addresses of the servers that are later combined with ports to be members.

Examples:
GTM:
- Wide IP: app-portlet.lb.cs.customer.com
- URL: http://portlet.customer.com
- Pool of Wide IP: app-portlet
- Members of Pool: 209.45.18.146 port 80, 209.40.40.147 port 80. Member names are app-portlet-reg2-80 and app-portlet-reg3-80

LTM:
- Virtual Server: Name app-portlet-reg3-80 with IP address 209.40.40.147 and port 80
- http://portlet-primary.customer.com
- Pool of Virtual Server: app-portlet-reg3-80 with monitor
- Members of Pool: 209.45.42.36:80 and 209.45.42.35:80
- Nodes of Members: 209.45.42.36 and 209.45.42.35

Training
Want to understand F5's LTM in depth, everything from the objects above to session awareness, monitor configuration, iRules, and so forth?  Then I recommend you take "BIG-IP Local Traffic Manager (LTM) Essentials," the free, self-paced, 14 hour training course at https://university.f5.com/. You can follow training modules, then log into a cloud-based LTM to do configuration exercises. Even if you're not the person managing the device for your customer, you'll be able to ask for the right things by knowing so much. And you might even know about features your F5 team isn't aware of, and you'll then be able to push them to a new level of ROI from this product.

Enjoy.

Dealing with frenemies and port conflicts

| | Comments (0)
Subtitle: How to identify which process is running on a port

Hi Folks:

I just found a surprise about a friend of mine. First I'll introduce: Gizmo5. First some background on how I met Gizmo5.

Do you know about Google Voice's offering? Google gives you a free phone number, then among other things, it lets you forward that number elsewhere. Where to forward it? One thing I wanted to do after moving to a new city (Helloooooo Austin!) was get a landline since my wife didn't get great cell reception at our new place. "A landline it is," I said, but continued to her mild displeasure, "but I want to try getting this set up without using AT&T." I searched for a good voice-over-IP phone service. I wanted something like Vonage, but I didn't want fees.

Gizmo5 is one of many free VOIP services, or SIP providers. Another I use is sipgate. Oh yeah, and there's Skype, but Skype charges a monthly fee for a phone number right? Something like that. Money was involved, so I didn't go there. Plus, I wanted to have more of a DIY solution. So the idea of these VOIP providers is they give a phone number that rings to an Internet-connected client. The easiest client is the laptop-based softphone that every SIP provider has. Here's the one from Gizmo:

gizmo5.jpg

But the Internet-connected client becomes much more interesting when the client is a simple, old-fashioned, landline style phone. This is what Vonage does.

So I bought an analog telephone adapter (ATA) from Grandstream for $45, and after a bit of configuration, I was able to plug my old landline phone into the ATA, then plug the ATA into my router, then have the ATA register itself with Gizmo5's servers to say, "when a call comes in to Bill's Gizmo5 account, let me know because I'm his phone." Then I had Google Voice forward my Google Voice number to that Gizmo5 number, and I'm in business. How cool is this? So cool that Google bought Gizmo5 and ended new registrations while they work on their integration plan. Don't worry though. You can set this up with a sipgate account too.

Anyway, I still have that Gizmo5 softclient running on my laptop from time to time. And today I fired up my WCI Automation service, and I messages like these in my PTSpy:

Automation Server cannot be initialized.
com.plumtree.openfoundation.util.XPException: Address already in use: JVM_Bind

InitForScheduler(): Unable to start communicator on port 7777
java.net.BindException: Address already in use: JVM_Bind


Hey, what's that about? I ran this command to see what was running on port 7777:

Netstat -a -n -o | GREP 7777

And the report came back:

TCP    0.0.0.0:7777           0.0.0.0:0              LISTENING       3184

So what is running behind process 3184? I checked my task manager and found it's my friend Gizmo5 now acting as my enemy:

proc-is-gizmo5jpg.jpg


Since I don't know how to change the port of Gizmo5, I hop into my serverconfig.xml and change the automation server's port, restart, and I'm back in business with a fully functioning WCI system. Gizmo5 is no longer an enemy but a friend.

PS: The business model behind free SIP providers is they charge for outgoing telephone calls. Gizmo5 is a penny per minute. Sipgate is two cents per minute. But incoming calls are free, so? Initiate those long calls from Google Voice. Google will ring your SIP provider as an incoming call, then Google rings the party you wish to speak with, and it's free.


Someone asked this question today:

What does a web proxy server placed in front of the Portal give you, in terms of security (or anything else), when there is already an SSL Accelerator (F5 BigIP) managing the portal? The end user would still access the Portal on port 80.  Either way.  What does the extra server buy you?

In hopes a larger audience might find my answer useful, here you go. First though, I'll try the "picture is worth a thousand words" approach, using a slide from a presentation I did a couple years ago:

proxymity.jpg

Now my take:

Consider this case: You have users on the public internet, and you don't want any of your app servers to be in the DMZ. So you put a proxy in the DMZ, and it can reach back through the firewall to the internal Big IP that can route traffic to the many app servers.

Why not put the Big IP itself in the DMZ and have it route from there? One reason is that it handles traffic for many more ports than you want open on the firewall (e.g. for search, directory, dr). But more importantly, Big IP needs to be able to monitor the members of its pools. So there's lots of chatter between it and the servers.

So there you've got the security angle.

Also, proxies sometimes offer additional features such as authentication. You may only have internal users, want your users to authenticate at your company proxy.

There's also improved performance when you can keep the portal in the same VLAN as the remote servers it uses to build pages. A single portal page load can generate dozens of DB queries and http requests to the remote tier. A proxy lets you keep users in the DMZ while keeping the portal near those resources.

WCI Settings Files: rules for construction

| | Comments (0)
rules.jpgThe world is full of rules. I was amused at a local Austin grocery store to find rules against something that seem pretty obvious: food trays are not sleds. Other rules though can be harder to figure out. In case you need to know some of these less obvious rules:

I'm working on an effort to restructure WCI settings files, and a piece of this required understanding the rules for putting together a valid settings file. I hope to later explain the whole project, but until then, here's a subset of what I learned.

The Loose
WCI applications read in everything in the %WCI_HOME%\settings directory on startup. A default system would have these in c:\oracle\wci or some such location. That everything is read means WCI neither cares what your file names are nor what subfolders they may be in. For example, you can move .\settings\configuration.xml to .\settings\do-not-use\disabled.xml, and it will still work just fine. The system treats all information across all files as a single settings definition.

You can also break apart the out-of-the-box XML files into new smaller files, or you can rearrange their content entirely. This explains how it is that systems run WCI 10.3.0.0 equally well for fresh installs versus upgraded installs even though each has differently structured XML files (for example, fresh installs store settings in configuration.xml that upgraded installs keep only in portal\portalconfig.xml and common\serverconfig.xml).

You can add settings in the XML files that are not required and not used by the system. For example, you can have a context or a component defined but never used.

The Strict
Within the config files, however, you'll find tightly linked context, component, and client sections. Some rules are:
  1. A context cannot be defined more than once.
  2. A component name cannot be used more than once.
  3. A component cannot have a subscribed client that is not a defined context.
  4. A client cannot subscribe to two different contexts of the same component type.
An Example
Now is a great time for an example. The following file sits on my system as %WCI_HOME%\settings\example.xml. When the system starts, this file is read into the settings definition, though nothing in it will be used by my applications. The system runs just fine, and it will continue to do so unless I uncomment any of the sections of the config file that are designed to break the four strict rules I previously listed.

Download the file so you can load it in a readable XML parser, load it on your system, or tweak it. You can also try reading it in less readable format below.

Enjoy!

<?xml version="1.0" encoding="UTF-8"?>
<OpenConfig xmlns="http://www.plumtree.com/xmlschemas/config/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <context name="example-context"/>
<!-- ERROR 1: uncomment the below client to create "context with this name already exists" error -->
<!--
    <context name="example-context"/>
    -->
    
    <!-- include the below context to illustrate that listed contexts need not be used -->
    <context name="example-context-unused"/>
    
    <component name="example-component" type="http://www.plumtree.com/config/component/types/example-type">
        <setting name="sometype:something">
            <value xsi:type="xsd:boolean">true</value>
        </setting>
        <clients>
            <client name="example-context"/>
            <!-- ERROR 2: uncomment the below client to create "context could not be opened" error -->
            <!--
            <client name="undeclared-context-breaks-system"/>
            -->
        </clients>
    </component>
    <!-- include the below component to illustrate that components need not have clients -->
    <component name="example-component-no-clients" type="http://www.plumtree.com/config/component/types/example-type">
        <setting name="sometype:something">
            <value xsi:type="xsd:boolean">true</value>
        </setting>
        <clients>
        </clients>
    </component>
    <!-- ERROR 3: uncomment the below component to create "component with this name already exists" error -->
    <!--
    <component name="example-component-no-clients" type="http://www.plumtree.com/config/component/types/example-type2">
        <setting name="sometype:something">
            <value xsi:type="xsd:boolean">true</value>
        </setting>
        <clients>
        </clients>
    </component>
    -->
    
    <!-- ERROR 4: uncomment the below component to create "context already subscribes to component of type" error -->
    <!--
    <component name="example-component-duplicate-type" type="http://www.plumtree.com/config/component/types/example-type">
        <setting name="sometype:something">
            <value xsi:type="xsd:boolean">true</value>
        </setting>
        <clients>
            <client name="example-context"/>
        </clients>
    </component>
    -->
</OpenConfig>


ALUI/WCI SSO Login Sequence and Log Files

| | Comments (0)
sequence.gifYou can't trust your web server logs to tell you how many pages your portal users view. When logging in, especially under SSO, the login sequence generates several "GET /portal/server.pt " lines. I dug into this today, and the results may be helpful as you look to infer portal usage from log files.

Yesterday I turned to IIS logs to determine some usage patterns in the portals I work with where users can enter through two different SSO systems. I started my search by looking at how many times SSOLogin.aspx occurred for each SSO system (hosted on different servers). When the results appeared material, today I wondered whether the load for the systems are different. Do the users of one SSO system have a more engaged portal session?

First I counted simply "GET /portal/server.pt" in the log files, and I though one set of users had far more pages per session than did the other. However, I then realized that gateway images were returned by my search pattern, so I added a space: "GET /portal/server.pt " This made the traffic look much more similar.

But I still didn't know how many actual pages the user sees. What happens in the login sequence?

What I found was:

* It is hard to identify actual pages per visit because the IIS log sometimes shows 3 and sometimes 4 requests per login.
* A user's login generates three lines in the IIS log with "GET /<virtualdirectory>/server.pt/ "  when the user enters the portal through http(s)://<portalhost>/
* A user's login generates four lines in the IIS log with "GET /<virtualdirectory>/server.pt/ "  when the user enters the portal through http(s)://<portalhost>/<virtualdirectory>/server.pt

The login sequence as found in IIS logs looks similar to this:

1. The unidentified user enters without specifying the <virtualdirectory>/server.pt, then redirects to the SSO login


2. The SSO-authenticated user is redirected to the portal from the WSSO login
/portal/server.pt 

3. The SSO-authenticated user is directed to the portal's SSOLogin sequence to process the SSO token and become portal-authenticated
/portal/sso/SSOLogin.aspx 

4. The portal-authenticated user runs a login sequence to determine the proper home page behavior
/portal/server.pt open=space&name=Login&dljr= 

5. The user lands on the proper home page
/portal/server.pt/community/superstuff/204 

I hope that's helpful.

Find recent content on the main index or look in the archives to find all content.