Five steps you can use to figure out how anything in Alfresco Share really works

A forums user recently asked how to use the “quick share” feature from their own code. The implementation is easy to figure out, but I thought illustrating the steps you should use to dig into it would be instructive, because it is the same general pattern you would follow to learn how anything works in Alfresco.

What is Quick Share?

Quick Share makes it easy for end-users to share any document with anyone whether or not that person is a member of a site or has specific permissions on a document. Clicking the “Share” link in the document library or document details displays a dialog with a shortcut URL that will allow anyone to see a preview of the document. If that person also has access to the document, they can optionally download the document as well.

The Quick Share feature in Alfresco Share

 

How does this work behind-the-scenes? Let me show you how to figure that out. These steps can be used to demystify any Share-based functionality you need to learn more about.

Step 1: Determine the call Share makes to the repository

Share is just a front-end web application. It always talks to the repository via HTTP. Step 1 is to take advantage of that. Use Firebug or a similar browser-based client-side debugging tool to watch the network traffic between Share and the repository. If you turn that on you’ll see that when you click “Share” the browser makes a POST to:

http://localhost:8080/share/proxy/alfresco/api/internal/shared/share/workspace/SpacesStore/f70e2505-5002-42b7-a71b-2e09aca0c2d0

What comes back is JSON representing the quick share ID:

{
"sharedId": "oD9wUfV_SPS9eG-CFEpwbQ"
}

The first part of that URL, “/share/proxy/” is the Share proxy. It simply forwards the request on to the repository tier. In this case that’s a web script residing at “/alfresco/api/internal/shared/share”. The rest of the URL is the node reference of the node being shared.

As a side-note, unsharing works similarly. Share sends a DELETE to http://localhost:8080/share/proxy/alfresco/api/internal/shared/unshare/oD9wUfV_SPS9eG-CFEpwbQ

That returns JSON with the return flag:

{
"success" : true
}

So now you know how Share interacts with the repository. The next step is to dig into the repository tier implementation.

Step 2: Look at the repository web script

Now that you know the repository web script URL you can go to the web script console, http://localhost:8080/alfresco/s/index, to learn more about the web script. I find searching by URI to be easiest. Here’s the web script in the list:

web-script-index

Clicking on that link shows high-level information about the web script. Make note of this web script’s lifecycle–it is set to “internal”. That means you shouldn’t call it from your own applications or customizations. If you do, you may be creating a future maintenance headache because the web script may change without warning.

In this case, we don’t want to call the web script, we want to know what the web script is doing. Clicking on the web script ID will tell you more about how it is implemented. Here’s the URL where you’ll end up:

http://localhost:8080/alfresco/s/script/org/alfresco/repository/quickshare/share.post

This page is really helpful because it shows you the details about the web script implementation, including its views and controllers.

Web Script Implementation Details

In this case, the web script uses a Java controller implemented in the following class:
org.alfresco.repo.web.scripts.quickshare.ShareContentPost

The next step is to dig into the web script implementation.

Step 3: Read the source code for the implementation

If you search through your Alfresco source code you’ll find ShareContentPost.java. It’s a very simple web script. Here’s the line that does the work:

QuickShareDTO dto = quickShareService.shareContent(nodeRef);

Cool, so there is a QuickShareService. I’m going to make a time-saving leap here which is to assume that anything named like FooService is likely defined as a Spring bean that I can inject in my own code.

Step 4: Find the QuickShareService bean

If you’re going to write some Java code that leverages the QuickShareService you’ll probably want to see the Spring bean configuration for that bean. To find that, go into $TOMCAT_HOME/webapps/alfresco/WEB-INF/classes/alfresco and do a grep for QuickShareService. You’ll see that it is defined in quickshare-services-context.xml.

Now you have a Spring bean ID you can use as a dependency in your code.

Step 5: Understand the content model

You might choose to do this in an earlier step, but if you haven’t already, you should use the node browser in Share to see what happens to a node when it is shared just in case you need to make use of any of that information. By doing that you’ll see that a shared node has an aspect called qshare:shared. When it gets shared, the qshare:sharedId and qshare:sharedBy properties get set. In this example, the QuickShareService handles that for you–you shouldn’t have to set those manually. But it is good to know those properties are there in case you need them.

If you needed to learn more about the content model you could grep for that aspect ID, qshare:shared, in $TOMCAT_HOME/webapps/alfresco/WEB-INF/classes/alfresco/model to figure out where the model XML is.

Now you have everything you need to make use of this functionality in your own code. For example, if you wanted to create a rule action that automatically shared everything matching a certain criteria, you could easily do that by injecting the QuickShareService into your action and then calling the shareContent() method (see my actions tutorial).

This example covered the Alfresco Quick Share feature in the Alfresco Share web client, but you can use these steps to dig into any functionality in Alfresco Share that you need to deconstruct.

Posted in Alfresco, Alfresco Developer Series | Tagged , , | 8 Comments

I’m leaving Alfresco, remaining part of the community

After much contemplation about what’s best for the Alfresco community, the company, and my own happiness, I’ve decided to leave the company. My last day as Chief Community Officer will be Friday, June 6.

With all of the changes the company has seen over the last year or so I know there are some who will suspect that something nefarious is underfoot. I want to be really clear about this: It was my decision to leave, I’m excited about this change, and I hope you’ll be excited for me too.

If it’s all good, why leave?

Ultimately,  I’m leaving because I miss delivering content-centric solutions to clients. When I took the position three years ago, I thought that the part of my role that requires me to help flatten the learning curve for people would satisfy my creative and technical itch. It did partially, but it wasn’t enough.

Of course, there have been changes I haven’t always agreed with–until you are your own boss that will always be true. But the primary reason I’m leaving is because I need to be building stuff again.

What does this mean for the Alfresco Community?

The company remains committed to the Alfresco community and there are no major changes planned that I am aware of. I know whomever takes over my responsibilities will continue with the important work as beekeeper.

I intend to continue making contributions to the community just as I did before I joined the company. In fact, having me back in the field means more real world implementations to draw on that I can write about, speak about, and share with others.

My personal mission to take down legacy ECM with open source hasn’t changed. I think many of you are aligned with me on that mission, and this move allows us to continue the fight side-by-side.

What does this mean for Alfresco Summit?

I’m proud of what I was able to accomplish with the annual DevCon/Alfresco Summit conference. It was fun growing that so much year-over-year while maintaining the integrity and feel of the event. But I’m no event planner. And the bigger it grew the more time it required. Last year we actually made the decision to take if off my hands. I’ve been helping with programming content for Alfresco Summit 2014 but 2013 was the last one I was primarily responsible for, which makes the transition pretty seamless. (This year’s conference promises to be better than ever, and you should totally sign up if you haven’t done that yet).

What’s next?

For these next two weeks, I’m completely focused on getting everything transitioned smoothly. I’ll share more about what’s next for me after June 6, but I’m sure it will be surprising to absolutely no one.

Until then, please know that I have truly enjoyed my time serving as the leader of this wonderful community. I know there is work left to do but, man, we got so much done!

Perhaps more importantly, I have established what I hope will be life-long friendships, both in the community and inside the company, with people all over the world. The best thing about this change is that I know those will continue, regardless.

Posted in Alfresco, Alfresco Community | 24 Comments

Cool things you can do in Alfresco with cmis:item support

allyoursysbaseI’ve been taking a look at the newly-added support for cmis:item in Alfresco. As a refresher for those who may not be familiar, cmis:item is a new object type added to the CMIS 1.1 specification. Alfresco added support for CMIS 1.1 in 4.2 but did not immediately add support for cmis:item, which is optional, according to the spec. Now cmis:item support is available in Alfresco in the cloud as well as the nightly builds of 4.3.a Community Edition.

So what is cmis:item?

We’ve all written content-centric applications that have included objects that don’t have a content stream. You might use one to store some configuration information, for example, or maybe you have some other object that doesn’t naturally include a file that needs to be managed as part of it. There are a few approaches to this in Alfresco:

  1. Create your custom type as a child of sys:base (or cm:cmobject if you don’t mind your objects being subject to the file name constraint)
  2. Create your custom type as child of cm:content and simply do not set a content stream
  3. Ignore the content model altogether and use the attribute service

I’m not going to cover the third option in this post. If you want to learn more about the attribute service you should take a look at the Tech Talk Live we did in April.

The second option is fine, but then you’ve got objects with content properties that will never be set. Your objects look like they want to be documents, but they really aren’t because you don’t expect them to ever have a file as part of the object. Not the end of the world, but it’s kind of lazy and potentially confusing to developers that come after you.

The first option is what most people go with, but it has a drawback. Instances of types that do not extend from cm:content or cm:folder are invisible to CMIS 1.0. Not only are those objects invisible to CMIS 1.0 but relationships that point to such objects are also invisible. Depending on how much you use CMIS in your application this could be a fairly severe limitation.

Thankfully, CMIS 1.1 addresses the issue with a new object type called cmis:item. It’s made precisely for this purpose.

What can I do with it out-of-the-box?

Even if your custom content model doesn’t need a “content-less object” you can still benefit from cmis:item support. Let me walk you through my five favorite object types that you can now work with via cmis:item support in CMIS 1.1 that were not previously available: Category, Person, Group, Rating, and Rule. I tested everything I’m showing you here using Alfresco 4.3.a Community Edition, Nightly Build (4/27/2014, (r68092-b4954) schema 7003) and Apache Chemistry OpenCMIS Workbench 0.11.0.

Category

Man, if I had a bitcoin for every person I’ve seen asking how to get the categories of a document via CMIS, I’d have a garage full of Teslas. With cmis:item support, it’s easy. Here’s how you get a list of every category in the system with a CMIS Query Language (CQL) query:

SELECT * FROM cm:category

That returns a list of cm:category objects that represent each category in the system. Note that this is a flat list. In Alfresco, categories are hierarchical. I’m not sure what the plan to address that is, to be honest.

Now suppose you have an object and you want to know the categories that have been assigned. Here is some Groovy code that does that:

(Can’t see the code? Click here)

Categories live in a property called “cm:categories”. It’s a multi-value field that contains the Alfresco node references for each category that has been assigned to a document. Once you get that list you can iterate over them and fetch the cm:category object to figure out the category’s human-readable name. That’s pretty cool and wasn’t possible before CMIS 1.1 support.

How about assigning existing categories to documents? Sure, no problem. Here’s how.

(Can’t see the code? Click here)

This is a little Groovy function that takes a full path to a document and the name of a category. Obviously it depends on your categories being uniquely-named.

First, it finds the category by name using CQL and snags its Alfresco node reference.

Next, it checks to see if the cm:generalclassifiable aspect has already been added to the document and adds it if it has not.

Finally, it gets the current list of categories from the cm:categories property and adds the new category’s node reference to it.

I started to look at creating new categories with CMIS, but it isn’t immediately obvious how that would work due to the hierarchical nature of categories. The only parent-child association supported by CMIS is the one implied by folder-document relationship. I’ll ask around and see if there’s a trick.

That’s it for categories. Let’s look at Person objects next.

Person

Here’s another frequently-asked how-to: How do I query users through CMIS? Before cmis:item support you couldn’t do it, but now you can. For example, here is how you can use CQL to find a list of the Person objects in Alfresco:

SELECT * FROM cm:person

You can qualify it further based on properties of cm:person. For example, maybe I want all users who’s first name starts with “Te” and who work for an organization that starts with “Green”. That query looks like:

SELECT * FROM cm:person where cm:firstName like 'Te%' and cm:organization like 'Green%'

Suppose you wanted to find every Alfresco Person object that has a city starting with “Dallas” and you want to set their postal code to “75070″. Ignoring cities named “Dallas” that aren’t in Texas (like Dallas, Georgia) or the fact that there are multiple zip codes in Dallas, Texas, the code would look like this:

(Can’t see the code? Click here)

That’s it for Person objects. Let’s look at Group objects.

Group

Similar to querying for Person objects, cmis:item support gives you the ability to query for groups–all you have to know is that groups are implemented as instances of cm:authorityContainer. Here’s the query:

SELECT * FROM cm:authorityContainer

Unfortunately, it doesn’t seem possible to use CMIS to actually add or remove members to or from the group. Maybe that will change at some point.

Rating

It’s easy to query for ratings:

SELECT * FROM cm:rating

But it’s hard to do anything useful with those objects because, at least in this nightly release, you can’t follow the relationships from or two a rating. As a sidenote, you can get the count and total for a specific node’s ratings by getting the value of the cm:likesRatingSchemeCount and cm:likesRatingSchemeTotal properties respectively. But that’s not related to cmis:item support.

Rule

Rules are a powerful feature in Alfresco that help you automate document handling. Here’s how to use a query to get a list of rules in your repository:

SELECT * FROM rule:rule

Rules are so handy you might end up with a bunch of them. What if you wanted to find all of the rules that matched a certain criteria (title, for example) so that you could enable them and tell them to run on sub-folders? Here is a little Groovy that does that:

(Can’t see the code? Click here)

First the code uses a join to find the rule based on a title. The property that holds a rule’s title is defined in an aspect and that requires a join when writing CQL.

Then the code simply iterates over the result set and updates the rule:applyToChildren and rule:disabled properties. You could also set the rule’s type, description, and whether or not it runs asynchronously. It does not appear to be possible to change the actions or the filter criteria for a rule through CMIS at this time.

What about custom types?

Custom types? Sure, no problem. Suppose I have a type called sc:client that extends sys:base and has two properties, sc:clientName and sc:clientId. Alfresco automatically makes that type accessible via CMIS. It’s easy to create a new instance and set the value of those two properties. Here’s the groovy code to do it:

(Can’t see the code? Click here)

Did you notice I created the object in a folder? In Alfresco, everything lives in a folder, even things that aren’t documents. In CMIS parlance, you would say that Alfresco does not support “unfiled” objects.

The custom object can be queried as you would expect, including where clauses that use the custom property values, like this:

SELECT * FROM sc:client where sc:clientId = '56789'

In CMIS 1.0 you could not use CMIS to work with associations (“relationships”) between objects that did not inherit from either cm:content (cmis:document) or cm:folder (cmis:folder). In CMIS 1.1 that changed. You can create relationships between documents and folders and items. Unfortunately, in the latest nightly build this does not appear to be implemented. Hopefully that goes in soon!

Summary

The new cmis:item type in CMIS 1.1 is a nice addition to the specification that is useful when you are working with objects that are not documents and do not have a content stream. I showed you some out-of-the-box types you can work with via cmis:item but you can also leverage cmis:item with your custom types as well.

Support for cmis:item requires CMIS 1.1 and either Alfresco in the cloud or a recent nightly build of Alfresco 4.3.

Posted in Alfresco, Alfresco API, Alfresco Developer Series, CMIS | Tagged , , | 19 Comments

Nominate an Alfresco community star

Every year I select a handful of “community stars”. These are people who have gone above-and-beyond during the previous year in the Alfresco community. Community stars get a free conference pass to Alfresco Summit and bragging rights for the coming year.

To select community stars the community team and I look at things like:

  • Forum, IRC, and Stackoverflow helpfulness
  • Significant contributions to the product in terms of bug reports, fixes, or other code or documentation contributions
  • Meetup activity
  • Evangelism in social channels
  • Authors of particularly helpful books, blog posts, wiki pages, screencasts, tutorials, or add-ons

The community team has some visibility into the people making a consistent difference in these areas, but we can’t be everywhere all of the time. Every year it is inevitable that we miss one or two deserving individuals.

So I need your help.

If you know of someone who deserves to go to Alfresco Summit for their work in the community, please submit this form. I need their name, contact info, and why you think they should be identified as an Alfresco community star. It should take you less than 5 minutes.

Thanks ahead of time for helping me give our community stars the recognition they deserve!

Posted in Alfresco, Alfresco Community, Alfresco Summit | 8 Comments

Quick Hack: Creating default folder structures in Alfresco Share sites

Someone recently asked how to create Alfresco Share sites with a default folder structure. Currently, out-of-the-box, when you create an Alfresco Share site, the document library is empty. This person instead wanted to define a set of folders that would be created in the document library when a new Alfresco Share site is created.

Although this exact functionality is not available out-of-the-box, there is something similar. It’s called a “space template”. Space templates have been in the product since the early days but haven’t yet been exposed to Alfresco Share. In the old Alfrexsco Explorer client you could specify a space template when you created a new folder, and the resulting folder would have the same set of folders and documents that were present in the template.

With a little bit of work using the out-of-the-box extension points we can get Alfresco to use space templates when creating new sites in Share. I’ve created this as an add-on and the code lives on GitHub. I thought it might be instructive to review how it works here.

Approach

The first thing to realize is that a space template isn’t special. It’s just a folder that happens to live in Data Dictionary/Space Templates. In fact, there aren’t any API calls specific to space templates. If you go looking for a createFolderFromTemplate() method on a Folder object you’ll be disappointed. When the Alfresco Explorer client creates a folder from a template, it simply finds the template folder and copies its contents into the newly-created folder.

On the Alfresco Share side, a site isn’t that special either. It’s just a special type of folder. The document library that sits within a Share site is also just a folder, albeit a specially-named folder with an aspect. Normally, the document library folder does not get created until the first user actually opens the site and navigates to the document library.

So all we really need to do is write some code that gets called when a site is created, looks up the space template, and then creates the document library folder with the contents of the space template.

What’s the best way for the code to know which space template to use? One way would be to use a specially-named space template for all Share sites. But using a single space template for all Share sites seems limiting. Alfresco Share already has a mechanism for selecting the “type” of site to create–it’s called a preset. So a better approach is to use the preset’s ID to determine which space template to use.

Code

We need to run some code when a site is created. One way to do this is with a behavior. The behavior is Java code that will be bound to the onCreateNode policy for nodes that are instances of st:site. The init() method does that:

// Create behaviors
this.onCreateNode = new JavaBehaviour(this, "onCreateNode", NotificationFrequency.TRANSACTION_COMMIT);

// Bind behaviors to node policies
this.policyComponent.bindClassBehaviour(QName.createQName(NamespaceService.ALFRESCO_URI, "onCreateNode"), TYPE_SITE, this.onCreateNode);

So any time a node is create that is an instance of st:site, the onCreateNode() method in this class will get called.

The first thing the onCreateNode() method needs to do is find the space template. To keep things simple, I’m going to assume that the space template is named the same thing as the site preset ID, so all I need to do is grab that preset ID and do a Lucene search to find the template:

NodeRef siteFolder = childAssocRef.getChildRef();

if (!nodeService.exists(siteFolder)) {
logger.debug("Site folder doesn't exist yet");
return;
}

//grab the site preset value
String sitePreset = (String) nodeService.getProperty(siteFolder, PROP_SITE_PRESET);

//see if there is a folder in the Space Templates folder of the same name
String query = "+PATH:\"/app:company_home/app:dictionary/app:space_templates/*\" +@cm\\:name:\"" + sitePreset + "\"";
ResultSet rs = searchService.query(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, SearchService.LANGUAGE_LUCENE, query);

If there aren’t any space templates the method can return, otherwise, the space template should be copied into the site folder as the new document library folder:

documentLibrary = fileFolderService.copy(spaceTemplate, siteFolder, "documentLibrary").getNodeRef();

//add the site container aspect, set the descriptions, set the component ID
Map<QName, Serializable> props = new HashMap<QName, Serializable>();
props.put(ContentModel.PROP_DESCRIPTION, "Document Library");
props.put(PROP_SITE_COMPONENT_ID, "documentLibrary");
nodeService.addAspect(documentLibrary, ASPECT_SITE_CONTAINER, props);

I used the fileFolderService to perform the copy, then I set the properties and aspect on the new document library folder with the values that Alfresco Share expects a document library to have.

I’ve left out some insignificant code bits here and there–you can look at the source if you need to. The project was bootstrapped using the Alfresco Maven SDK and includes a unit test that makes sure the behavior works as expected.

Result

The project creates an AMP file. If you’ve checked out the source you can build the AMP using mvn install. Then you can install the AMP into the Alfresco WAR by placing the AMP in the amps directory and run apply_amps.sh. Alternatively, you can use mvn alfresco:install. After installing the AMP into the Alfresco WAR you can test it out.

Out-of-the-box Alfresco Share has a single site type called “Collaboration Site”. The preset ID for that type of site is “site-dashboard”. You might have additional site types configured in your installation. To set up the template for the default collaboration site, navigate to Data Dictionary/Space Templates and create a folder called “site-dashboard”. Then add whatever folders and documents you want to that folder. Now, anytime a “Collaboration Site” gets created in Alresco Share, the document library will automatically be created with the same folders and documents you’ve set up in your space template.

This was not a mind-blowing, deeply-technical extension to Alfresco. Hopefully, it shows you that, with even a few lines of code, you can easily add useful functionality to Alfresco.

Posted in Alfresco, General | Tagged , , | 17 Comments

Alfresco Summit 2014 Save-the-date & Call-for-papers

I am pleased to announce that Alfresco Summit 2014 will be held this year in San Francisco and London. Similar to last year, we’ll have an optional “Day 0″ which will include training and a hack-a-thon and then the main conference will start on the following day. This year, the main conference lasts only two days, regardless of the tracks you are interested in.

San Francisco
Hyatt Regency San Francisco
September 23, 24, & 25

London
Hilton London Metropole
October 7, 8, & 9

San Francisco and London are two of my favorite cities so I’m looking forward to spending time in each one.

The Program At-a-Glance

The business tracks were popular last year so we’re going to do those again. Laurence Hart is heading up the business tracks this year. I expect the business sessions, two tracks full of non-technical presentations from customers as well as a few sessions from Alfresco product management, will be well-attended.

I’m taking the technical tracks again, which is always fun. Several of you said you had too many tough choices last year so we’re moving from four technical tracks down to three. So that’s two full days of technical content for both beginners and experts delivered by Alfresco engineering, partners, and other community members.

The solutions track will work the same way as it did last year with Joe Tong and Peggy responsible for selecting content that showcases entire solutions built for the Alfresco platform. And the ever-popular lightning talks that Richard Esplin puts together every year will also be on the agenda.

Another change we made in response to your feedback is that we’ve reduced the sessions from 50 minutes to 40 minutes, which effectively doubles the time between sessions. This will give you more time to network in the “hallway track” and to browse the booths in the exhibit hall.

We Need Your Great Content!

I’ll fill you in on the killer keynotes, the can’t-miss party, and other details later. None of that really matters without one key ingredient: Outstanding content. This is where you come in. Every year we get some great responses to our call-for-papers. I expect this year to be no different.

You should submit a proposal to speak at Alfresco Summit. Your colleagues want to hear:

  • What have you been doing with Alfresco that others could learn from?
  • What was the good, the bad, and the ugly from your last project?
  • What are those tips and tricks that would have saved you days or weeks had you only known beforehand?

This kind of information is invaluable to the broader community.

Before I tell you how to submit your idea for a topic, let me give you some hints on what I think makes a great Alfresco Summit topic abstract.

Think about what everyone else is going to propose, then pick something different

A good abstract is one that shows us you’ve got a unique or innovative topic. At the same time, the topic can’t be so niche or specialized that it’s only interesting to a handful of people. If your talk is one of ten just like it, you’re odds aren’t very good. Think new and different.

Related to this, try to avoid topics an Alfrescan is likely to propose. For example, a talk on the latest features of Alfresco One is something that the Alfresco One product managers will present.

Explain who will attend your session and what they will take away

When you are writing your abstract, figure out who will want to attend. This might be job titles or even specific individuals. With those people in mind, ask yourself what is it that they are trying to get out of your talk. A good abstract explains who will attend, why they are interested, and what they will take away from your talk.

Be descriptive, but succinct

When you write your abstract, be descriptive but be succinct. I want to know why this is going to be an interesting talk and why you are the best person to give it, but I don’t need your life story. This year some of the fields have character limits to keep length reasonable.

Don’t Wait, Submit Today!

To have your topic considered you must submit a complete form by the end of April regardless of whether you are submitting for a business talk, a technical talk, or a lightning talk. Solution talks will be handled separately through Joe and Peggy.

The form itself is pretty simple: You’ll tell us who you are, what you are presenting, and what Alfresco products the talk is related to.

If you are selected to present a full session you will receive a free conference pass. We won’t pay for your travel expenses, but you’ll save on registration. You’re in it for the glory anyway, right?

I look forward to another bumper crop of great topic ideas. If you have any questions, please don’t hesitate to let me know.

Posted in Alfresco, Alfresco Summit | Tagged , , , | 3 Comments

Alfresco freenode IRC chat room transcripts now logged, searchable

I told you about the #alfresco chatroom on IRC a couple of years ago when Richard Esplin and I took it over and started promoting its use. Since then it has grown tremendously with somewhere between 30 and 40 people hanging out and discussing various Alfresco-related (and some unrelated) topics.

Richard recently rolled out some new features that I hope will help keep the momentum going.

First, the chatroom is now logged. The last 90 days of messages are available at chat.alfresco.com. That page also includes an embedded web chat client for people who don’t have their own desktop client or for quick questions.

Second, there’s a new member of the chatroom named alfbot. The bot’s primary purpose is to facilitate logging, but it gives us some additional functionality which is pretty handy. Here are a few examples:

  • If you want your message to be excluded from the log you can start your message with [nolog]. Your handle will appear in the log but your message will be redacted.
  • If you need to tell someone something but they aren’t currently logged in, you can say “alfbot later tell jpotts You finally decided to log in, eh?”. Then, when alfbot sees jpotts log in your message will be added to the chat.
  • If you want to know when the last time someone was in the chat room you can say, “alfbot seen resplin” and that would tell you when Richard was last on.
  • If you want to tell alfbot something and you don’t want to type “alfbot” at the start of your message, you can use a tilde as an alias, like this: “~later tell jpotts You finally decided to log in, eh?”.

People that hang out in #alfresco frequently will want their own desktop IRC client. There are many available. On Linux, I’ve used Pidgin and liked it. On my Mac I use Adium. On Windows there is HexChat, which I haven’t used.

Regardless of which client you use, just point it to irc.freenode.net, then join us in #alfresco.

Thanks to Richard and the IT team for getting this in place and to Ian Crew for making the pages on chat.alfresco.com look pretty.

Posted in Alfresco, Alfresco Community | Tagged , | 7 Comments

Alfresco Tech Talk Live Re-Cap: Content hashes, cloud dashlets, & MongoDB

If you didn’t catch Alfresco Tech Talk Live today you missed one heck of a session. We had a motley crew of panelists showing off their creations from November’s Alfresco Summit Hack-a-Thon. Here’s the recording:

Three of the hack-a-thon teams gave demos. We heard from:

  • Axel Faust (Prodyna) and Martin Cosgrave. They showed us a solution they created for a hash-based content store. Content is given a hash as it is added to the repository, then if subsequent content is added, it simply points to that file on disk rather than duplicating it. They also used a hash to create a cache for Alfresco Share. Axel and Martin’s project is hosted on GitHub.
  • Will Abson (Alfresco) showed us a couple of cool things. One was an integration between on-premise Alfresco Share and Alfresco in the cloud. It included, a dashlet like My Sites that lists your sites on Alfresco in the Cloud as well as a search modification that allows you to do a single search against on-premise and Alfresco in the cloud. The project is on GitHub. He also showed an admin console add-on called the Alfresco Cloud API Explorer that lets you run HTTP GETs against the public Alfresco API.
  • Derek Hulley (Alfresco) showed a proof-of-concept he’s been working on. His POC is aimed at replacing the relational back-end that Alfresco uses to store metadata with MongoDB. It isn’t complete yet, but he was able to show that you could add aspects to a node and those aspects and property values were persisted in MongoDB.Derek’s project is on GitHub.

Nathan McMinn (Alfresco), Richard McKnight (Alfresco), Ben Kahn (Red Hat), and Alexey Ermakov (VIDEL) were also on our panel and participated in the discussion but we ran out of time for their demos. We’ll circle back with them another time.

We also have three brief announcements:

Thanks to all panelists and viewers who participated!

Posted in Alfresco, Alfresco Community, Alfresco Summit | Tagged | Leave a comment

Why I took the Alfresco Certified Administrator exam

Alfresco_Certified_Administrator_CMYKLast week I took (and passed!) the Alfresco Certified Administrator (ACA) exam. I don’t administer an Alfresco server every day as part of my job, so why would I do such a thing? Lots of reasons. Let me give you a few…

Reason 1: I wanted to see how hard the exam really is

If you review the information about Alfresco certification you’ll see that the certification isn’t one of those trivial “thanks for participating” certificates you get at the end of a training course after a simple were-you-listening-at-all kind of exam. The blueprint says you don’t have to take the training but you must have the knowledge and competency necessary to run a production installation. I wanted to see if this really was the case.

I can’t reveal what’s on the exam, but I will say I was impressed with its thoroughness and depth. The exam really does cover just about every part of the platform that an administrator has to know about to be successful.

Every certification exam I have ever taken has had questions that I’ve wanted to argue with and this one is no exception, but the test seemed like it was constructed to genuinely test my competency rather than to trip me up with confusing or easy-to-misread questions.

So I’d say the difficulty level is appropriate and the coverage is such that I would feel pretty comfortable letting anyone who had passed that exam (and who exhibited other requisite strengths) put their hands on my server.

Reason 2: I wanted to keep up with my friends

I took and passed the Alfresco Recognized Developer exam as soon as it was available. That was back in February of 2011. Then I joined Alfresco, got busy, and never bothered with the ACA or Alfresco Certified Engineer (ACE) exams when they eventually replaced the Recognized Developer Program.

Honestly, it’s been nagging at me. Seeing those badges in the forums. Watching the congratulatory tweets as others passed their exams. Knowing that we’re going to start doing more to publicize people who hold the certs. I finally said, “What am I waiting for? It’s kind of ridiculous that the guy leading the community doesn’t participate in the certification program!” and then I scheduled the test.

Reason 3: I wanted something that would vouch for my abilities to people who don’t know me

On any given day I am answering questions in the forums or IRC, writing a technical how-to, recording a screencast, or giving a technical talk about Alfresco at an event. A lot of people know I’ve been doing these things for 8 years (!) with a good chunk of that spent actually implementing solutions for clients but not everyone does. A certification is a way of saying, “This person has been around the block a bit with this technology”. It doesn’t mean everything I say is always correct. But it does add a certain amount of objective credibility to what I say.

It’s this last point that should make a difference to you. Whether you work for a partner who implements Alfresco One for customers, or you are an independent consultant who does work on Community Edition, or you support Alfresco in your internal IT shop, a certification distinguishes you from the person whose boss just stopped by to let them know they should start learning about the new open source ECM platform their company is migrating to from Documentum, and that could make a difference when you try to land your next deal or when you hit the boss up for a raise.

I don’t know for sure whether or not an Alfresco certification will get you hired or promoted more quickly or guarantee you a higher billing rate, but it sure can’t hurt. And if it isn’t happening already, I’m sure companies will start making it part of their job requirements and RFP templates.

So what are you waiting for? Look at the blueprint, figure out where your gaps are, take some training if you need it, and then go get certified.

Posted in Alfresco | Tagged , | 6 Comments

Updated tutorial: Creating custom advanced workflows in Alfresco

I have published a major revision of my “Creating custom advanced workflows in Alfresco” tutorial. Major changes include:

  • The tutorial now uses the Alfresco Maven SDK to instantiate the projects and to produce and install AMPs.
  • The tutorial no longer refers to jBPM, except to give brief historical context as to why the platforms includes both jBPM and Activiti.
  • The tutorial no longer includes any references to the old Alfresco Explorer client, except where it pertains to using the Alfresco Workflow Console, which is only available as part of the Alfresco Explorer Client.
  • Significant wordsmithing and re-organization to improve style and clarity.

I have tested the steps and the code against Alfresco 4.2.e Community Edition and version 5.14 of the Activiti Process Designer for Eclipse.

By the end of the tutorial, you will know how to:

  • Create, deploy, and run business processes using Activiti embedded within Alfresco.
  • Configure Alfresco Share to display custom forms when starting Activiti workflows or managing workflow tasks.
  • Use the Alfresco Workflow Console to deploy process definitions, start workflows, and delete workflows.
  • Add business logic to your process definitions using JavaScript and Java.
  • Assign workflow tasks to users and groups.
  • Add timers to your process definitions to take an action automatically after a specific time period.

The tutorial assumes you already know how to use the Alfresco Maven SDK. If you have never used it, take a look at this tutorial. The workflow tutorial also assumes you have worked through the Custom Content Types, Custom Actions, and Intro to Web Scripts tutorials.

The source code and the tutorial itself reside in GitHub. If you find problems or want to make improvements, please fork the project, make the change, and send me a pull request.

Posted in Alfresco, Alfresco Tutorials | Tagged , , , , | 16 Comments