Moving the blog

After almost 8 months of intermittent work and experiments, It’s finally official: the blog is being moved to a new self-hosted, completely independent location.
From now on the CodeVomit blog will be available at www.codevomit.xyz/bootlog, inside a brand new shining application built by me: Bootlog.

The site is currently in “open beta”, meaning that it is under active development. It may have bugs and be subject to obvious improvements. If you experience issues or have ideas about simple improvements, I guess you can just leave a comment. If you really want to piss me off, you can even open an issue on GitHub.

If you are curious about the reasons that made me switch from WordPress to a different application, you can read A brief history of MiBECoM, an excerpt from one of my failing attempts, and Why Bootlog, the first post I published in the new blog.

Finally, a closing remark. I could have used Jeckyll, you might object. Why not? The real reason is that I wanted to start a new project that could keep me busy and give me a good benchmark to improve my skills. The blog application seemed like the perfect way to combine the need for a new blogging platform with my will to work on a real world system. Not to mention that it feels good to build your own stuff.

Advertisements

How to grant farm-wide read access to a user in Sharepoint 2013

A few weeks ago I was asked to grant a particular user read rights to any resources of a Sharepoint farm; sites, folder, lists, etc…, irrespective of the permission currently set on those resources (i.e. possible unique permissions).

By the way, it appears that I’m also a particularly skilled Sharepoint administrator. It apparently happened over night, without me even noticing.

Unable to find any out-of-the-box solution for my particular situation, I came out with a bunch of scripts that did the trick and I think are worth sharing. Of course, the work I did has been mainly taping together snippets and scripts that I found somewhere else so the credit goes mostly to the Internet, as usual. There is a bit of original work, though.

The basic idea was to give the rights to a new group, GlobalReaders, created for the occasion in each root site, and then add the users to the group as needed. In the future, the users will be easily removed and the rights revoked, if needed.

1. Automating the creation of the GlobalReader group

If the farm has a large number of web applications and site collections, it can be hard to manually create the group. So the first step is automating this task. The following script scans all the sites of the farm and adds the desired group to their root web

function Add-GlobalReadersGroupsToAllSites
{
    $sites = Get-SPSite -Limit ALL
    Write-Host $sites
    foreach($site in $sites)
    {
        Write-Host "Adding GlobalReaders group to " $site.Url
        $site.RootWeb.SiteGroups.Add("GlobalReaders", $site.Owner, $site.Owner,
            "Members of this group has read rights on any resources of the farm (sites, lists, folders, etc...)")
        $site.RootWeb.Update()
    }
}

2. Assigning a group read rights on an SPWeb

The first brick of the procedure is a function that takes the name of a group and an SPWeb URL, and assign the group read rights over the Web itself. The script also takes into account folders and lists whose permission inheritance has been broken (unique permission).


# Assigns Read permission to a list of users for the Web provided
function Grant-ReadPermToGroup
{
    if($args.Length -lt 2)
    {
        Write-Error "Grant-ReadPermToUser requires 2 parameters. Usage: Grant-ReadPermToUser <SubSiteUrl> <GroupName>"
    }

    # Write-Host $args[0] " " $args[1]

    $web = Get-SPWeb -Identity $args[0]
    $site = $web.Site
    $groupList = $web.SiteGroups | Where { $_.Name -eq "GlobalReaders" }
    $readerGroup = $groupList[0]

    Write-Host "Assigning read permission for Web " $web "($($web.Url))"
    Write-Host "Group:"

    Write-Host "    "$readerGroup.Name

    Write-Host "Granting read permission to $readerGroup"
    $assignment = New-Object Microsoft.SharePoint.SPRoleAssignment($readerGroup)
    $role = $site.RootWeb.RoleDefinitions.GetByType([Microsoft.SharePoint.SPRoleType]::Reader)

    $assignment.RoleDefinitionBindings.Add($role);
    Write-Host $assignment
    $web.RoleAssignments.Add($assignment)

    # #########################################################################
    # Now let's deal with lists and folders with unique permission assignments

    # Finds all the lists of the given web that have unique role assignments
    # (broken inheritance)
    $uniqueAssignList = $web | select -ExpandProperty Lists |
        Where { -not $_.Hidden -and $_.EntityTypeName -ne "PublishedFeedList" -and $_.HasUniqueRoleAssignments}

    foreach($l in $uniqueAssignList)
    {
        Write-Host "Grantig read permission for list " $l.Title
        # Assign read permission
        # $role = $site.RootWeb.RoleDefinitions.GetByType([Microsoft.SharePoint.SPRoleType]::Reader)
        $role = $l.ParentWeb.RoleDefinitions.GetByType([Microsoft.SharePoint.SPRoleType]::Reader)
        Write-Host "Role: " $role
        $assignment = New-Object Microsoft.SharePoint.SPRoleAssignment($readerGroup)
        $assignment.RoleDefinitionBindings.Add($role)

        $l.RoleAssignments.Add($assignment)
    }

    # Finds all the non-hidden folder (at any level)
    # of the given web that have unique role assignments
    # (broken inherintance)
    $uniqueFolders = $web |
        select -ExpandProperty Lists |
        Where { -not $_.Hidden -and $_.EntityTypeName -ne "PublishedFeedList"} |
        select -ExpandProperty Folders |
        Where { $_.HasUniqueRoleAssignments -and -not $_.Hidden } 

    foreach($f in $uniqueFolders)
    {
        Write-Host "Grantig read permission for folder " $f.Title
        # Assign read permission
        # $role = $site.RootWeb.RoleDefinitions.GetByType([Microsoft.SharePoint.SPRoleType]::Reader)
        $role = $f.ParentList.ParentWeb.RoleDefinitions.GetByType([Microsoft.SharePoint.SPRoleType]::Reader)
        Write-Host "Role: " $role
        $assignment = New-Object Microsoft.SharePoint.SPRoleAssignment($readerGroup)
        $assignment.RoleDefinitionBindings.Add($role)

        $f.RoleAssignments.Add($assignment)
    }

    Write-Host "     OK! (^__^)"
}

Now we can easily cover the requirement for any SPWeb, provided that we can recursively loop over all of them (and we can, of course).

3. Recursively looping through all the webs

Once you assign the permission for a web, all the subweb are covered, unless they have unique permission. In this case, you have to individually take care of any subwebs that have unique permission (i.e. they do not inherit the permission from the parent because the inheritance has been broken by an administrator at some point in time):

# Grants read permission to a user for a Web and, recursively,
# all its sub-webs
function Grant-ReadPermRecursive
{
    if($args.Length -lt 2)
    {
        Write-Error "Parameters required: Web Url, Group Name"
    }
    # If runDry = True, the function walks the entire web tree, without actually adding new permissions
    $runDry = $false
    if($args.Length -ge 3)
    {
        $runDry = $args[2]
    }
    Write-Host "RunDry = "$runDry
    $web = Get-SPWeb -Identity $args[0]
    Write-Host "Web: " $web
    $groupName = $args[1]
    Write-Host "Username list: " $groupName
    if(!$runDry)
    {
        # Write-Host "I would actually grant permissions"
        Grant-ReadPermToGroup $web.Url $groupName
    }

    $subWebList = $web.Webs
    if($subWebList.Length -gt 0)
    {
        foreach($subWeb in $subWebList)
        {
            if($subWeb.HasUniquePerm)
            {
                Grant-ReadPermRecursive $subWeb.Url $groupName $runDry
            }
        }
    }
}

4. Wrapping it all

Finally, we can wrap the operation with a convenient function that operates on the farm level, looping over all the SPWebApplications and taking into account the root web of each:

$allFarmWebApplications = Get-SPWebApplication
foreach($webApplication in $allFarmWebApplications)
{
    Write-Host "WebApplication: " $webApplication.Url
    foreach($site in $webApplication.Sites)
    {
        Write-Host "   Site: "$site.Url "   RootWeb: "$site.RootWeb
        $rootWeb = $site.RootWeb
        Grant-ReadPermRecursive $rootWeb.Url "GlobalReaders" $false
        Write-Host "-----------------------------"
        Write-Host " "
    }
}

Stress reducing tools and methodologies

A brief list of things that made me a better developer and a less anxious person.

Test Driven Development: Even if nobody in your team is doing TDD and your manager thinks it is just building a servlet for each back end Web Service, you can start applying TDD today and become a better developer. Of all the good natural consequences of TDD, what I like most is its stress reducing effect. If I feel afraid that something might be broken or it might fail in production, I just add more and more test cases, until every edge case is covered. I no longer wake up in the middle of the night worried of what could happen tomorrow when the servers will be restarted. Everything can still go wrong like it used to, but your level of confidence in your code and your reaction speed are greatly improved. You just feel better. And a fix is usually much easier to implement than without tests. Let alone the fact that stupid bugs will actually appear far less frequently than before…

Git: I hated the beast and avoided it like hell until I found an illuminating video on Youtube where a clever guy managed to explain with great clearness how Git actually works and how you can use it effectively. That has been a turning point. I realized that I was unable to use it because of lack of understanding. And once you see what branching and merging really means, you feel powerful, and a whole new world of possibilities unfolds before your eyes. It’s like living in three dimensions after having spent your whole life in Flatland. As of TDD, you do not have to wait until your company understands that leaving SVN and transitioning to Git is the right thing to do (Here I don’t even want to take into consideration SourceSafe, ClearCase or other hideous abominations): you can start using it today. Just “git init” a repository inside the root directory of a project; it does not matter if it’s under SVN source control, if you “gitignore” the right things the two do not interfere which each other. And your are ready to go. Now I wonder how could I have lived so long without Git.

Maven: you can say that it is verbose, it is slow, it eats up a lot of disk space, it’s ugly… I don’t care. I have personally seen what a build system without proper dependency management could be and what can cost in terms of time, money and stress: it’s not even a build system, it’s a destruction system. Maven is currently my default. There is only one thing that pisses me off more than a project not using Maven: one that uses it badly. If a person is not able to checkout a project and run a clean build at his first try, you are doing something wrong.

Sonarqube: A Wonderful free tool that helps you improve your code. It’ a bunch of tools that perform static analysis of code, integrated in a web application that keeps track of how the various parameters of the projects evolve from build to build. You can always learn something from the issues detected by Sonarqube and their relative descriptions. And it feels good to see how the color of a project shifts from red, to yellow, to green as you become a better programmer.

Virtual Machines: This is incredibly important, fundamental, if you happen to work in a hybrid environment. A usual situation for me is having a development machine running Windows and a deployment environment (for test, UAT, production, etc…) completely based on Linux. This is not so strange if you work with JavaEE: most applications and systems actually behave in the same way in Windows and Linux… almost… That is why you always want to give them a spin in a Linux box, before releasing it. After trying almost every virtualization software, my current choice is VMWare Player + Lubuntu. The first is available free of charge for non commercial use and works surprisingly well, the second is a lightweight Linux distro based on Ubuntu that gets rid of the super ugly desktop environment of Canonical and replaces it with LXDE, which requires few resources and performs well in virtual machines and older computers.

Setting up a restlet with Camel in JBoss Fuse

If you have already successfully gone through the steps of the previous tutorial, this is going to be quite fast and straightforward. All you need to know is that in Camel you can set up a restlet to listen to a specific URL/port with the “restlet” prefix.

Let’s assume that we want to listen for REST request and turn the body of the request into a message to be queued on one of our (already existent) ActiveMQ. As in the previous example, we can accomplish the task without even write a line of Java code.

We can add the following elements to our blueprint.xml file:

    <route>
        <from uri="restlet:http://localhost:8282/demo-endpoint?restletMethod=POST"></from>
        <camel:setBody>
            <simple>test=true</simple>
        </camel:setBody>
        <log message="The request body is: ${body}"></log>
        <to uri="activemq:sink-queue" pattern="InOnly"></to>
        <to uri="mock:result"></to>
    </route>

Here I’m specifying the restletMethod parameter, which tells Camel to only respond to GET HTTP request (i.e. any other HTTP verb will result in the request to be discarded). The setBody element is used for making thigs simpler: it sets the body of the exchange to the child value, as you might expect. Now we can “clean-install” the project as usual and switch to the Karaf console. Update the package with a osgi:update command (here, 251 is the ID of my bundle, you will probably have a different one. You can find out what ID your bundle has by executing a “list” command):

JBossFuse:karaf@root> osgi:update 251

After this, execute “list” and take a look at the output. In correspondence with the updated bundle you should see something like this:

[ 251] [Active     ] [GracePeriod ] [       ] [   60] A Camel Blueprint Route (1.0.0)

This is because the bundle has a missing dependency: the camel-restlet Feature. The bundle has been successfully installed, but it cannot be started until the missing dependency is satisfied. The missing feature is not installed by default in Fuse. Luckily, you can easily get it by typing the following command:

JBossFuse:karaf@root> features:install camel-restlet

To learn more about Features, refer to the official documentation.

Restart your bundle. The restlet is now ready. You can try and call it with whatever method you prefer. For simplicity, i present you the command used to perform a test with curl:

curl --data "test=true" http://localhost:8282/demo-endpoint

 

JBoss Fuse installation tutorial

At work I was given the task to study JBoss Fuse and become sufficiently comfortable developing and deploying basic projects on this platform. I’m going to write a series of post to share my experience and considerations.


Some random thoughts

I’m not going to rigorously explain you what Fuse actually is. But if you start from scratch, without any previous knowledge of a Service Bus middleware, it’s quite hard to get the essence of the system. And if you try to make an idea through what you find online, good luck. It’s hard to find something that tells you what you can really use Fuse for, possibly with some insightful examples. In fact, it is almost impossible. Sure you can find some “case studies” or articles that tell you how good Fuse is at integrating systems and how big a shitload of money they saved by using it instead of, say, building a similar monster from scratch. But those are only marketing mumbo jumbo and do not give you any useful tip on the technical side of the matter, which is what I really care about. What help me the most in these cases is bringing it down to a very trivial use case description and a set of practical examples. And this is what I am trying to do here.

Fuse is huge, very huge. It is a collection of subsystems taped together by Karaf, an OSGi container developed by the Apache Foundation. Here are only some of the subsystem included. I only knew the name of most of them until now, and some were completely unknown:

  • Karaf,
  • Camel,
  • CXF,
  • Hawtio,
  • Felix,
  • ActiveMQ,

JBoss Fuse is basically a Service Bus, a middleware, that allows you to host services and integrate a wide variety of heterogeneous systems. But this is not very helpful. So, this is the picture that I have after spending several hours using Fuse and developing tutorial and demo projects: if you have, say, a desktop application developed for Windows, a bunch of Web Services hosted in Tomcat in a Linux box, an external database that needs somehow to be updated and you want to let this system talk to each other, then Fuse might be the way to go. You can set up a Web Service in Fuse (REST or SOAP doesn’t matter) and use Apache Camel to connect the various pieces in a so called “route”. There already are a lot of components that automagically let you call an external web service, read and/or write to a database, reading or write a text file over FTP, reading or writing a directory over LDAP and whatnot. Here is a list of what is available. I particularly enjoyed the SSH connector and I’m looking forward to give it a try in a real project.

Another possible scenario is an Enterprise application that needs to interface with a legacy system. Think about an organization that wants, for some reasons, a new, cool, bleeding edge, good looking front end to amaze and fool the customers, but does not want to get rid of its 30-year-old COBOL code base running on IBM mainframes (nobody wants to do that). You can use Fuse to translate messages (from XML/JSON to plain text and back again), decouple the systems by using queues, log, and so on. Again, this is how I currently picture Fuse in my mind, I do not claim to give you a full coverage of the possible, numerous use cases.


Installation

Finally. Fuse is as easy to install and launch as Liferay, Alfresco and Pentaho (just to name few that I recently had to install). Even easier, in a sense. That is what you expect, since it’s completely Java based. Just unpack the tarball or the zip archive and launch <FUSE_DIR>/bin/fuse or <FUSE_DIR>\bin\fuse.bat, depending on what OS you are on. Keep in mind that the current release of Fuse (6.0.1) requires Java 7 and does not support Java 8. If you have your JAVA_HOME environment variable set to something different, you have to change it by either editing /etc/environment or the startup script. To do the second, which I recommend, Open the “<FUSE_DIR>/bin/karaf” script and add the variable definition, just like this:

#explicitly sets the value of JAVA_HOME to a compatible JDK
JAVA_HOME=/opt/jdk1.7.0_71

DIRNAME=`dirname "$0"`
PROGNAME=`basename "$0"`

#etc...

...

Now run the script named fuse and, if everything is OK, the Karaf console starts showing a prompt like the following:

JBossFuse:karaf@root>

The first thing that we want to do is to create an administrative user in order to access the Web console. So type:

JBossFuse:karaf@root> esb:create-admin-user

And there we go, we can now open a browser and navigate to http://localhost:8181, and have full access to the management web application.