Category: Enterprise 2.0

The idea has been around for years–using tools like blogs and wikis in a corporate setting–but now it has a catchy name: Enterprise 2.0.

Alfresco Share microblogging component released as open source

Back in February (I know, it’s been simmering on the back burner for too long), I did a couple of screencasts on Optaros Labs showing a demo of Alfresco Share (part 1, part 2). In part 2 of that screencast I showed two custom components: Status and Bookmark. Alfresco made Bookmark obsolete by releasing their own shared bookmarks module for Share, and that’s a Good Thing. I kind of expected them to release a microblog component as well, but they haven’t yet. Well, I finally got around to making ours available, so until a similar feature makes it into the product, feel free to use it in your own projects.

The component is simple: A “My Current Activity” dashlet lets you and your team give a quick blurb about what you’re working on. Another dashlet aggregates all of the status entries from your teammates. A global dashlet aggregates the entries from all Share sites. All status changes automatically show up in Alfresco’s Activity Feed as well.

My Current Activity Dashlet
My Current Activity Dashlet

Unlike Twitter, the status component lets you mark an entry as “done”. When you do that, your current status gets reset and the old entry moves to the archive. So it’s a little more task-oriented than more general purpose, free-form microblogging tools.

Deployment is pretty easy. An AMP gets deployed to your Alfresco WAR, and a ZIP gets unzipped into your Alfresco Share web application. That’s it. No configuration necessary. All of the data lives in the same structure as the other tools in your Share site.

I’ve put the code out on Google Code under a BSD license. There’s a pre-built AMP and a ZIP for download or you can checkout and build from source. There’s one Eclipse project for the repository tier and one for the Surf tier. I’ve tested this on Alfresco 3.2 Community. I’ll test it out on the Enterprise releases when I get a chance. There were some changes in the Activity Feed that I had to deal with and I’m not sure how far back those go so I may have to have version-specific releases.

Have a look and give me your feedback. If you want to dig in and make enhancements, bring ’em on.

Mozilla Ubiquity: Stop jumping around between web apps to get a task done

My friend and former colleague, Tom Pierce, stuck this on my Delicious page: Mozilla Ubiquity. The screencast really got my wheels turning. The idea is that with as many open services available today as there are we should be able to avoid the jumping around from site-to-site we do to complete what ought to be a simple task. The example they use is composing an email with a map to a restaurant and a list of restaurant reviews. Today you have to create the email then go to Google maps, find the restaurant, and then cut-and-paste a link to that map into your email. Then, if you want reviews, you have to do the same thing. Ubiquity gives you a single interface for pulling information from various sources all using friendly, text-based commands. In this example you never have to leave your web mail–as you compose the email you execute Ubiquity commands that fetch the data you need. Watch the video and you’ll get it.

After you’ve done that and your head is sufficiently spinning, think about the implications this could have in the Enterprise. Just within ECM alone you could do some really cool stuff (knowledge bases, document libraries, team collaboration, intranets) but I would also think there could be decent applications in the BI (Business Intelligence) world as well.

Call it what you want, just not “KM”

My friend and former colleague Tom Pierce has recently started blogging on Enterprise 2.0 over at EnterpriseBlend.com. One of his recent posts talks about whether or not social computing is the end of Knowledge Management (KM), that somewhat nefarious term for extracting, organizing, and sharing the knowledge from the heads of employees that ultimately forms a competitive advantage. He makes the point that KM concepts are still valid, it is just the technology that is changing. I agree that the technology is changing, and I agree there is still a need for KM, but I do think the way we approach KM now is shifting.

To me, Enterprise 2.0 is the new and preferred way to implement KM. The problem with past KM approaches was that it was too structured, too top-down. Heavy-handed, overly-rigid, formal approaches to anything rarely succeed. They usually end in rebellion, or, at best, apathy. Sharing knowledge because you are passionate about it and because you want to do it is a lot more fun, rewarding, and meaningful than doing it because it is a bullet point on your yearly review.

Formal KM initiatives I saw succeed Back in the Day did so because there were a small number of people within an organization who were paid to shepherd the information as their full-time job. This might have been a corporate librarian or an SME tasked to manage and grow a community of practice, for example. What we now know and what we now have the capability to leverage practically is the power of the network fueled by ubiquitous connectivity, massive storage capacity, and ever-increasing processor speeds that can index the whole mess. Knowledge management at that kind of scale can’t and won’t wait for you to figure out what your taxonomy needs to be. And you don’t need to figure it out–The taxonomy will just be.

It’s not all about the technology. Yes, the tools are better. But Enterprise 2.0 does better at KM not just based on the technology alone. It’s because Enterprise 2.0 is the anti-KM. It’s bottom-up. It has little or no structure. It’s about forming loose and accidental connections with others. If there are potential barriers to KM success this time around, I think it is that, for some types of organizations, this organic, bottom-up approach is antithetical to their current corporate culture. If they can’t change that–and it is so difficult to do–I think they’ll lose competitive advantage and become unable to compete effectively over time. For some, they’ll realize this too late, like maybe the day after all of the Baby Boomers decide to retire and move to southern Florida.

Thoughts on social software and events

It sounds like Ringside has some work brewing around events. I haven’t updated my Ringside source code in a while so I don’t know how much of this can be played with right now but I’m anxious to take a look and you can bet I’ll report back here when I do.

The problem with today’s event sites is that they are too focused (live music, social gatherings, etc.) and too isolated (people have to sign up to use them, they are really only used for RSVP-ing, etc.). I’ve also found that finding interesting events can be tough. I think Meetup.com is a particularly bad offender–they’ve got a weird taxonomy thing going with their events. Their search doesn’t appear to be full-text indexed across meetup names or descriptions. Try to search meetup for “Alfresco”, for example. Although I know there are multiple Alfresco meetup groups out there, you won’t turn up one with a keyword search even with your search scope set to “100 miles of USA”. And when you create an event, it seems like there is a limited taxonomy for categorization. You have to decide if your meetup is about “Software” or “Technology”. Why would I pay them to host an event no one can find attended by a set of people who’s profiles I can only leverage in the context of meetup.com?

This is a sticking point for me. We all belong to different communities with different interests. And sometimes those overlap. Our social graphs shouldn’t be in silos. Neither should the events we attend. Managing your connections across networks together and exposing events to sub-sections of your connections (or across your entire network, regardless of where it is hosted) is really powerful. After all, as Bob says, it is through these events by which we form and strengthen those connections in the first place. Hopefully, this is what you’ll be able to do with Ringside.

His post got me thinking about what I might like to do with events in my own community. So here’s a list off the top of my head. Maybe Bob will comment on how/if this maps to the Ringside roadmap.

Attend/host flag & security settings. An individual ought to be able to publish an event, make public/private settings about that event, and indicate whether they are attending or hosting the event.

Event matching/de-duplication. What would be great is if there was a way to match up events. If I say I’m going to a Wilco concert, and you say you’re going to a Wilco concert, there needs to be a way to figure out if those are the same event.

In-network/same-event notification. Once you figure out two events are the same, people in the same network can discover the fact they share similar interests. The system should facilitate this kind of thing.

Targeted event promo. You should also be able to publicize an event to particular cross-sections of your graph. I might want to host a Ringside meet-up that only goes to my open source/E2.0 friends without spamming my family about it.

Interest level indication. An individual ought to be able to specify whether they are thinking about attending an event or are definitely attending an event. For example, someone might post an event they would only go to if someone else from one of their networks is also going.

Events as tags. Obviously events integrate with the rest of the model. Activity feeds certainly have to know when someone attended an event. But you should also have the ability to tag any item with an event. A photo library app needs to be able to let users tag photos that pertain to certain events, for example.

Event discovery. Events should be easily discoverable by tag/topic, full-text keyword search, by geography, and by attendee. I’d like to see a mash-up between Dopplr and an event database, for example, that knows what kind of events I like to attend and then cross references that with my travel schedule so that if I am traveling to San Francisco, and one of my favorite bands happens to be playing, the site can let me know that, including which of my friends might also be planning to attend (or would attend if they knew I was going to be in town).

Slice-and-dice RSS subscriptions. I should be able to get an RSS feed for each of the following: All events happening in a particular cross-section of my social graph, all events happening in a particular tag/topic, all events in a geography, all events in a particular date range, all events attended by a particular individual in one of my networks, or any combination of these (Live music shows happening in Dallas that my friend Jim is going to).

RSVP options. People should have the option of whether or not to track attendance to an event. Even for an event they are not hosting, they may or may not care who else is attending.

Configurable reminders. People need to be able to choose whether or not to send reminders to attendees. Attendees need to be able to opt out of receiving reminders.

Event ratings, comments, and UGC. People should be able to rate, comment on, and upload content related to an event.

Flexible event types. Events don’t have to be of any particular type. An event is really just a span of time during which something that might be potentially interesting to others is happening. “I’m going to Taco Bell for lunch tomorrow” and “I’ll be spending an hour in the Ubuntu forums Saturday” are both legitimate events that people might want to publish.

Calendar view with the same filtering capability as the “slice-and-dice RSS feeds” requirement. And the calendar ought to be widget-able so that anyone can embed it on their own site.

Standard calendar options for events including start and end time, duration, “all day event”, recurring event. I guess if the event was (or could be exported as) an iCal compliant piece of data that might be enough?

Who’s bringing what. Obviously everyone is familiar with the concept in a social gathering (You aren’t the guy who always just brings the chips, are you? Come on, make an effort, man). But this is also relevant to professional events, particularly for “un-conference” or bar camp type events where attendees are expected to present.

What about an ecommerce component? Maybe you ought to be able to sell tickets for an event. This could open up a can of worms regarding capacity, tiered pricing and availability, ticket authenticity verification, etc., but it might be cool/fun to provide something that could loosen the stranglehold a small number of vendors have on the “live event” market. Just a thought. At the very least, if an event requires a charge, you should at least be able to link to a shopping cart somewhere.

Thanks for attending the Open Source ECM event

I want to thank everyone for attending the Open Source ECM event in Dallas this morning. In case you missed it, the slides I presented on “Assembling Enterprise 2.0 Solutions with Alfresco” are available on share.acrobat.com (which is powered by Alfresco, BTW) here.

The deck covers a bit about the general components of Enterprise 2.0 solutions and how a repository like Alfresco can be central to that architecture because it is so open. I then give a brief intro to web scripts (recycled from the talk I gave at the user conference in San Jose earlier this year) and walk through Endeca and a few other client examples.

I’ve also got some Alfresco-Ringside thoughts in there that include screenshots on the Alfresco-Facebook demo app running on Ringside and a list of potential features that might be interesting to implement with an Alfresco-Ringside combination.

Finally, I’ve got some never-before seen screenshots of the yet-to-be-announced Optaros-built streamlined Alfresco web client which we will release as an open source project under the GPLv3 soon.

Fixed the Alfresco-Ringside File Upload Problem

I’ve been playing with Ringside‘s Social Application Server. In my initial post on the subject I mentioned I was having trouble with the file upload. I got that put to bed this evening. As it turns out, Facebook inserts some hidden fields into form tags (see doc) such as the Facebook user, API key, session key, and app ID. Ringside doesn’t insert those fields.

Why does this matter? When you post a multipart form (i.e., a file upload) in a Facebook app, you don’t post to the canvas URL, you post to the application directly, which in this case is an Alfresco web script. All other posts go through the canvas URL and by the time they arrive at the web script, the request has the parameters it needs to make Alfresco’s Facebook web script runtime happy. In Ringside, the file upload post lacks that context because the hidden fields are missing. Alfresco needs those hidden fields–without them, the script has no idea which Facebook app is posting the data.

The fix was easy enough. I just inserted the hidden fields into the form via the Freemarker template (adddocdialog.post.fbml.ftl). The “facebook” root object knows the user, API, and app ID because the form gets displayed as the result of a canvas post.

Here are the hidden fields I added to form in the Freemarker template:

<input type="hidden" name="fb_sig_user" value="${facebook.user}" /><input type="hidden" name="fb_sig_session_key" value="${facebook.sessionKey}" /><input type="hidden" name="fb_sig_api_key" value="${facebook.apiKey}" />

The only other change I made was to comment out the postUserAction call in adddoc.post.js. I’m not sure that’s supported yet in Ringside. If it is, there’s some other problem causing it to choke.

So, other than the user action post, the Alfresco Document Library Facebook app is fully-functional in Ringside.

The next step is deeper integration into the web client. I know Alfresco is moving toward more social networking features in the 3.x release, but integrating with Ringside via web scripts might be a way to get there faster with more functionality.

Alfresco and Ringside

I’ve made moderate progress getting Alfresco and Ringside integrated. If you haven’t played with it yet, Ringside Networks is an open source project that essentially gives you a standalone Facebook server. There’s actually more to it than that, but for this conversation, what matters is that Ringside supports the Facebook API and FBML without requiring a connection to Facebook.My goal is to get the Alfresco Facebook “Document Library” example (screencast) working in Ringside. What I have working now is single sign-on between Alfresco and Ringside, the main web script, the document library creation web script, and the document libraries list web script (pictured). What isn’t working so well (yet) is the file upload.

If you want to try this yourself, you’ll need:

  • A working install of Ringside Networks Social Application Server (Advanced Developer Setup instructions) which requires PHP and MySQL
  • A working install of Alfresco Community
  • The Facebook AMP (or just the web scripts from the AMP) or your own set of Facebook runtime web scripts
  • Alfresco Community SDK & Source

Alfresco has hardcoded Facebook URLs into the FacebookAuthenticatorFactory and FacebookModel classes. You need those to point to your local Ringside server instead of Facebook. I created a RingsideAuthenticatorFactory which is just a dup of FacebookAuthenticatorFactory with LOGIN_REDIRECT changed to:

"<fb:redirect url=\"http://localhost/api/login.php?api_key=%s&v=1.0%s\">"

You’ll need to override the webscripts.authenticator.facebook bean with a pointer to the new class, like so:

<bean id="webscripts.authenticator.facebook" class="com.optaros.ringside.RingsideAuthenticatorFactory" />

I took a more hackish approach to the FacebookModel. I removed Alfresco’s class from alfresco-webscript-framework.jar and replaced it with my own version that has updated getCanvasURL and getPageURL methods:

public String getCanvasURL() {
return "http://localhost/web/canvas.php/" + getCanvasPath();
}

public String getPageURL() {
return “http://localhost/web/canvas.php/” + req.getPagePath();
}

At some point, what should really happen is that all of these URLs should be pulled out into a config. Once I get everything working, maybe I’ll circle back with a better step-by-step and perhaps the changes can be submitted to Alfresco so that it is easier for people to choose whether their Facebook web scripts run against Facebook or a Ringside server.

Drupal-Alfresco Integration and Alfresco’s Move to the Front-End

Via Dries Buytaert, Rob Purdie is announcing the relaunch of Amnesty International‘s site. The new site was built using Drupal and Alfresco.

It is interesting to see how many people have commented on both posts who are craving more information about Drupal and Alfresco integration and it is no wonder. As I mentioned last year in this post, Optaros sees the two offerings as highly complementary–they aren’t (yet) competitors.

We do a lot of implementations in both Drupal and Alfresco. We think PHP plus Alfresco, or in this case, Drupal plus Alfresco is a great combination. Why? Using PHP and Alfresco together is the best-of-both-worlds: You get the speed of development that PHP brings plus the strength of an
open, enterprise repository on the back-end. In Drupal’s case, specifically, add to that the
availability of thousands of pre-built modules as well as a true site (presentation) framework which is something Alfresco currently lacks (more on that in a second). The interface between the two is best facilitated by Alfresco’s REST-based web script framework which is itself based on lightweight coding tools (JavaScript and FreeMarker).

If you’ve been following this blog and the Alfresco Community Conferences, you know that Alfresco is making a move to the front-end. Clearly, Alfresco sees the lack of a Drupal-like front-end as a short-coming, and they are working hard to address this in their coming releases. Here are examples of what’s coming down the pike that may ultimately position Alfresco more directly against Drupal in the future:

  • Web scripts are being split out from the repository process. In the Community head it is now possible to run web scripts in a process separate from that of the core Alfresco repository process. And web scripts running in that standalone process can remotely invoke web scripts running in the Alfresco repository, even if the two are running on separate physical hosts. This will likely form the foundation of Alfresco’s dynamic web site approach: Web scripts running outside of the context of Alfresco, in a plain old servlet container, say, can take advantage of the web script framework, even if they never make a single call to Alfresco.
  • Alfresco is building a WYSIWYG, browser-based site builder tool. The Alfresco Dynamic Website (ADW) will allow you to assemble web sites and web pages by selecting modules (built with web scripts) from a module library and arranging them on the page.
  • Alfresco is moving their web clients from JSF to web script-based web sites. The new Alfresco client will be based on web scripts with the eventual goal being to build it and manage it as if it were any other normal, dynamic web site. The client will be a reference site which you can use to build your own dynamic sites.
  • Alfresco is trying to generate developer excitement around web scripts. Alfresco’s push in the developer community to get people excited about web scripts is no coincidence. If they can get the community to help develop a compelling library of web script-based modules, and if they can create a productive front-end development framework that can plug in those modules, Alfresco will be much more attractive to clients who benefit from a front-end presentation framework and pre-built components than it is today.
  • Alfresco is marketing heavily around community and Enterprise 2.0. As you may have seen at the Community Conference and other Meet-ups, Alfresco is driving towards more community, social networking, and general “Enterprise 2.0” features and functionality. This is usually mentioned in the context of being a Sharepoint Killer but it could also mean a blurring of the differences between Drupal and Alfresco as well.

I’m not saying that when the 3.0 release of Alfresco comes out it is going to be on par with Drupal. But I do think it is interesting to watch what’s happening as Drupal and PHP solutions look for more robust back-ends while Alfresco moves toward better front-end site development and module frameworks.

Running Alfresco web scripts as Liferay portlets

I’ve seen a lot of Liferay and Alfresco forum posts from people having trouble getting Alfresco running within a Liferay portal. Once that’s done, people usually want to invoke Alfresco web scripts as portlets without requiring a separate single sign-on (SSO) infrastructure. Some people have pointed to the Alfresco wiki (Deploying 2.1 WAR Liferay 4.3). That is a helpful reference but it isn’t the full story. Here are some notes that may help.

1. Download the Liferay 4.3.6 + Tomcat 5.5 JDK5 bundle. I had mixed results with the latest release 4.4.2. You may be tempted to try to download the WAR-only distribution and configure it in your existing Tomcat instance. In this case, save yourself the time and headache and get the bundle. Fool with the WAR distribution later.

2. Unpack the Liferay distribution and fire it up. Make sure you can log in as the test@liferay.com (password: test) user to validate that all is well with the Liferay install.

2a. Create a test user. (“Create Account” on the Liferay login screen). Remember the email address. This will matter shortly. For this discussion I’ll assume Foo User with a screen name of fuser and an email address of fuser@foo.com. Make sure you create a home directory. In this example, we’ll call it “fuser”.

2b. Verify that you can log in as your test user.

3. Shut down the server.

4. Download Alfresco 2.1.2 Enterprise, WAR only. Alfresco 2.1.1 has a known issue (AWC-1686) with the way authentication is handled for web scripts in the context of Liferay so make sure you are using 2.1.2.

5. Expand the Alfresco 2.1.2 WAR into the Tomcat webapps/alfresco directory (which you’ll have to create the first time). If you are tweaking the install (such as pointing to a specific MySQL database, using something other than MySQL, pointing to a different data directory, etc.) make sure you have copied your good set of extensions into Tomcat’s shared/classes/alfresco/extension directory.

6. Copy the MySQL connector into Tomcat’s common/lib directory.

7. Start Tomcat. When it comes up, you’ll have Liferay running and you’ll have Alfresco running, but Liferay doesn’t yet know about Alfresco. Verify that you can log in to Alfresco as admin.

7a. While you are here, create a test user account. You need to create a user account that has an email address that matches the test user account you created in Liferay. In this example you created Foo User with a screen name of fuser and an email address of fuser@foo.com so you need to create an Alfresco user with the same settings. You’ll log in to Alfresco as fuser. You’ll log in to Liferay as fuser@foo.com.

7b. Verify that you can log in to Alfresco as fuser.

8. Shut down Tomcat.

9. Now you need to configure Alfresco as a Liferay plug-in. This involves adding four files to Alfresco’s WEB-INF directory: liferay-display.xml, liferay-plugin-package.xml, liferay-portlet.xml, and portlet.xml. Why aren’t these available in the Alfresco source or on the wiki? Apparently someone tried to address this at some point because there is a link on the wiki but it is broken. Until that’s addressed, I’ve put them here.

10. Remove the portlet-api-lib.jar file from Alfresco’s WEB-INF/lib directory.

11. Re-package alfresco.war. It is now ready to hand over to Liferay.

12. Start Tomcat.

13. Find your Liferay deploy directory. If you are running out-of-the-box on Linux, Liferay’s “deploy” directory is called liferay/deploy and it resides in the home directory of the user who started Tomcat. I’m running it as root so my Liferay deploy directory is /root/liferay/deploy.

14. Copy the alfresco.war you just created into the deploy directory. Watch the log. You should see Liferay working on the WAR. He’s finding the plug-in config files and essentially deploying the Alfresco portlets.

15. Now log in to Liferay using the Liferay admin account (test@liferay.com). Go to a page, then use the global navigation dropdown to select “Add Content”. The list of portlets should appear and you should see the “Alfresco” category. If you don’t, look at the log because something is amiss. Add the My Spaces portlet to the page. You may see an error at this point but ignore it. The problem is you probably don’t have a user in Alfresco that has an email address of “test@liferay.com”, which is the currently-logged in user.

16. Log out.

17. Log in as your test user that exists in both Alfresco and Liferay (fuser@foo.com).

18. Go to the page. You should see the “My Spaces” portlet. You should be able to upload content, create spaces, etc.

Exposing your own web scripts as portlets

All Alfresco web scripts are automatically exposed as JSR-168 portlets, including the ones you create. To add your web scripts as portlets, first make sure you have authentication set to “user” and transaction set to “required” in your web script’s descriptor. Then, update portlet.xml, liferay-portlet.xml, and liferay-display.xml. Follow the pattern that’s in those files already and you’ll be fine. For example, if you deploy the Hello World web script from my web script tutorial, you need to add a new portlet to portlet.xml with a “scriptUrl” like: /alfresco/168s/someco/helloworld?name=jeff. Then you update liferay-portlet.xml and liferay-display.xml with the new portlet name or portlet ID.

Single sign-on with no single sign-on?

The web script runtime has a JSR-168 authenticator. So when your web scripts get invoked by the portlet, the current credentials are passed in. That’s why your web script can run without requiring an additional sign in. Prior to this being put in place, people had to implement Yale CAS (or an equivalent) to get SSO between Liferay and Alfresco web scripts.

What’s not covered in these instructions is that you’ll probably want to (1) configure both Alfresco and Liferay to authenticate against LDAP and (2) change the configuration of either Alfresco or Liferay to use the same credential (either username or email address) for both systems so that if you do have users logging in to both, they don’t have to remember that one requires the full email address but the other doesn’t.

Troubleshooting

If you see one of the Alfresco portlets displaying “Data is not currently available” or somesuch, try hitting
Alfresco in another tab. Log in, then log out. Then go back to the
portal and open the page again. It should work now. I’m not sure what’s going on there. I think it may have to do with me switching back-and-forth between Liferay instances (4.3.2 versus 4.4.2) so maybe you won’t see it.

Open issues

You may see an error like this:

21:22:15,965 WARN [BaseDeployer:1038] Unable to format /usr/local/bin/liferay-4.3.6/temp/20080408212212978/WEB-INF/faces-config-jbpm.xml: Error on line 5 of document file:///usr/local/bin/liferay-4.3.6/temp/20080408212212978/WEB-INF/faces-config-jbpm.xml : A ‘)’ is required in the declaration of element type “application”. Nested exception: A ‘)’ is required in the declaration of element type “application”.

I haven’t chased that down yet. I’ll update this post with a comment when I find out. I’m sure fixing that will also fix the problem that you’ll see if you try to start an advanced workflow from a piece of content displayed in the My Spaces portlet.

I was also seeing an error when trying to use the “Add Content” link in the straight Alfresco client. I think it is JSF-related. Again, I’ll update this post with a comment when it is resolved (or when I find a Jira ticket).