Jump to: navigation, search

Skalli/User Guide

Contents

Getting Started

Option 1: Out-Of-the-Box

Download and extract the ready-to-use distribution. On Windows you might simply run the pre-built executable eclipse.exe. On Linux (and Windows, if you prefer to not use the executable) start Skalli from a shell with

java -Dosgi.compatibility.bootdelegation=true -Declipse.ignoreApp=true -Dosgi.noShutdown=true 
-Dequinox.ds.print=true -Djetty.home=./jetty -Dlogback.configurationFile=./jetty/etc/logback.xml
-Dskalli.persistence.eclipselink.target-database=Derby
-Dskalli.persistence.javax.persistence.jdbc.driver=org.apache.derby.jdbc.EmbeddedDriver
-Dskalli.persistence.javax.persistence.jdbc.url=jdbc:derby:SkalliDB;create=true
-Dskalli.persistence.javax.persistence.jdbc.user=skalli
-Dskalli.persistence.javax.persistence.jdbc.password=skalli
-jar plugins/org.eclipse.osgi_3.8.0.v20120529-1548.jar -clear -console -consoleLog 
-configuration ./configuration

Note, in either case you need a Java 6 or Java 7 runtime (both 32 and 64 bit VMs are supported).

Navigate to http://localhost:8080 and log in with guest/guest or admin/admin. Some sample data is already included, e.g. type skalli in the search field (or enter http://localhost:8080/projects?query=skalli as URL) to obtain the detail page of the Eclipse Skalli project.

Option 2: Installing Jetty Web RT

  • Download the latest Jetty Web Starter Kit and unpack it (e.g. to /opt/jetty). Note, you need a 32 bit Java VM to run Jetty because it is based on a 32 bit Eclipse platform.
  • Configure Jetty [1] according to your needs or copy the etc folder from o.e.s.target/jetty to the etc folder of the Jetty installation as a start.
  • Run Jetty (note: on Windows use rtweb.exe; start.bat seems to be broken in Jetty 3.7.1).
  • Continue with deployment (Option 3).

Option 3: Deploying Skalli with P2

  • In the OSGi console enter the following commands:
provaddrepo https://hudson.eclipse.org/hudson/job/skalli/lastSuccessfulBuild/artifact/org.eclipse.skalli.p2/target/repository/
provlg
provinstall org.eclipse.skalli.orbit.feature.feature.group <iuv>
provinstall org.eclipse.skalli.feature.feature.group <iuv>

<iuv> is the corresponding version of the feature as displayed by provlg.

By default, Skalli is configured to use a file system based storage mechanism for project data (see the storage directory of your Jetty installation). You may copy some test data from org.eclipse.skalli.feature/rootfiles/storage to your storage folder as a start.

First Steps After Installation

Right after you have installed Skalli, you should configure administrator users. By default, every user is an administrator.

Tutorials

If you want to try out the following walktrough yourself, download and start an instance of Skalli as explained above. Login as user ad with password milliways. If the login screen is not directly visible after starting Skalli, click on the link titled (Login) in the upper right corner of the Skalli homepage.

Note, if you are behind a firewall you should configure a proxy first.

Skalli in 20 Minutes: A Quick Walkthrough

First of all, to correct a common misunderstanding just from the beginning, Skalli is not another software hosting facility like Sourceforge, GitHub or GoogleCode. It provides no source code repository, no build system, not even a Wiki or another document storage facility. So what is Skalli about?

Large software development organizations, including but not limited to large software companies and open source foundries like Eclipse, typically struggle with an ever growing amount of projects to deal with. Usually these projects have grown in a quite heterogenous environment with respect to the development tools and infrastructure used. For example, some older projects may host their source code still in CVS or Subversion source code repositories, while new development may happen in Git. Some projects may be built with ANT, while others rely on Maven. Documentation may be partly stored in a central Wiki, but some teams may prefer to store their documents simply on a file share. That is a common observation: One size does (usually) not fit all, and developers are especially insistent with respect to their liked — or more worse: disliked — development tools. Still, organizations strieve to get and retain an overview of all the projects in such a heterogenous environment — and surprisingly often fail.

Skalli tries to fill that gap. It links the various bits and pieces of a project together, gathers information about the projects in an organization, makes this information searchable — and in the consequence: manageable. In doing so, Skalli stores only a very small amount of original data. Remember, Skalli is not another source code repository. Projects can host their source code in whatever source code repository that suits their needs best. Skalli just keeps links to all the repositories and may — currently only for Git — help new projects to initially create repositories, but the actual source code is stored somewhere else.

Knowing that, it should not be a big surprise that the start screen of Skalli looks like the following:

Skalli home page with search field, quick access links and tag cloud


Quite frugal, you might say, but looking a bit more closely, this screen expresses quite exactly the philosophy of Skalli: All is about searching and finding projects that might be important or interesting for you. Just type what you are searching for into the input field, e.g. type modeling, and click on the Search button.

Search result page with navigation links and a list projects matching a given query


This screenshot shows a typcial result of a search query. The project that matches your search query best is displayed on top of the result list. Navigate through the result list with the links at the bottom of the page or choose how many results Skalli should display per page with the links provided above the result list. The overall amount of search hits is displayed beneath the search field in header bar.

Each entry of a query result page provides the most important information about a project in condensed form.

Details provided for a search hit: Title, synopsis, links to important resources, tags and information about the project's position in the project hierarchy


Besides the title of the project and a short synopsis of what the project is about you see a line with some links to important project resources — like the project's home page — and another line with tags that members of the project or just other interested parties have assigned to the project. You can assign arbitrary tags to any project, even if you are not a member of that project.

Note the title of the project entry: It is a link that navigates you to another page with all the project's details:

Detailed information about a project, for example about the development resources, mailing lists, committers and related projects


Each panel — or info box how we prefer to call them — on this page provides a certain piece of information about the project. Some of these boxes are common to almost all projects, e.g. the About and Team boxes. Others can be switched off if the project has no need for them. You can even implement custom info boxes for your instance of Skalli!

We don't want to explain all available info boxes here in detail, but just mention a few of them that you might most certainly want to add to your project:

About 
This info box in the left column shows the description of the project, tags assigned to it, a link to the project's homepage and the current state of the project (Mature in the example).
Mailing Lists 
This info box in the left column provides mailing lists that you can use to communicate with the project members. Clicking on the mailing list link (e.g. emf-dev@eclipse.org in the example) opens a mail client. The links for subscribing/unsubscribing and browsing are automatically generated if you provide a suitable mapping configuration.
Development Infrastructure 
This info box in the left column groups the most important information for developers of the project, e.g. links to the source code repository, build system and bug tracker. Some of the links are generated automatically by the info box if you provide suitable mapping configurations.
Additional Links 
This info box in the left column let's you manage additional links for a project. Links can be grouped under common captions.
Project Hierarchy 
This info box in the right column shows the position of the project in the project hierarchy and allows and easy navigation to the project's parent and sub projects.
Team 
This info box in the right column lists the team leads and committers associated with the project. If a suitable mapping is provided, the name entries are rendered as links leading to an address book or something similar where more information about the project members can be retrieved. Furthermore, by clicking on the projects link right to the name of a committer, you get a list of other projects this committer is associcated with.
Related Projects 
This info box in the right column displays projects that are somehow similiar to the displayed one and you might likely be interested in visiting them, too.
Issues 
This box in the right column is only visible to project members and shows issues Skalli has found when validating the project. Skalli checks the information maintained by a project periodically and gives hints how the data quality could be improved. In the example, Skalli has detected that the homepage link points to nowhere and should be corrected.

Let's assume you want to correct the typo in the homepage link now. If you are a project member — and Arthur Dent, the guy you have logged in as, happens to be member of the Eclipse Modeling Framework (EMF) project — you should see an Edit link in the left navigation bar (in the section This Project). Clicking it navigates you to the following page:

Edit page of the project Eclipse Modeling Framework (EMF). Each section can be switched on or off independently


The screenshot shows only the upper part of the edit page — scroll down to see what else you can maintain — but the point of interest, the invalid homepage link, is clearly marked by Skalli. The correct URL is http://www.eclipse.org/modeling/emf/. Change that and press the Check button at the top of the page. This will revalidate the project and the red error markers should vanish.

Let's have a closer look at what else you can do on this screen: The edit page presents all available extensions you can assign to your project. Nearly every piece of information you can assign to a project comes in the form of an extension. In it's simplest form, a project has just a unique identifier (the Project ID), which is of are more technical nature, and a human readable name that appears as title of the project in the user interface. These are the only mandatory properties you must fill in upon creation of a project. Everything else can be provided later.

In order to assign an extension to a project, just click on the "edit" link in the title bar of the corresponding form. Scroll down to the form titled with Scrum and enable it. We want to assign a Product Owner for the EMF project: Click on Add User, search for art, select Arthur Dent from the search result and leave the search dialog with Add and Close. The form now should look like this:

Enabling the Scrum extension for a project that is dedicated to information related to an agile development method


Leave the edit dialog with the OK button at the bottom of the page. You should see a new info box with title Scrum in the right column of the project's detail page now:

Enabling the Scrum extension produced an additional info box on the project's detail page


Let's go back to the start page of Skalli — you can do that by clickling on the small Skalli logo that appears on all detail screens and most other Skalli pages in the upper left corner — and have a closer look at the links beneath the search input field.

Fast access links navigating to an all projects overview page, to the logged in user's projects and favorites, and to the screen for creating of new projects


The link titled All Projects navigates to an overview page showing all projects known to Skalli in their respective places in the project hierarchy. This has not been mentioned yet, but projects can have an arbitrary amount of subprojects, and each project can have a parent project (one and only one, or none if it is a top-level project). A typical project hierarchy may look like this:

Hierarchical view of all registered projects


Projects in this view are sorted alphanumerically with the top-level projects in bold letters, while subprojects are printed with indentation and in smaller font. You may expand and collapse the individual nodes of the project hierarchy with the corresponding links to gain a better overview, or drill down into parts of the hierarchy with the browse link.

Follwing the link titled My Projects on the Skalli homepage is equivalent to a search for all projects to which the currently logged in user, Arthur Dent, is assigned to either as project lead or committer. The result is presented in the condensed search hit format similar to what has been shown above for the search query modeling. Furthermore, a logged in user like Arthur Dent can mark arbitrary projects as his favorites. You might have recognized the little light bulbs on the project's detail page or on the search result page next to the project titles and wondered whether that is just decoration? Nothing of that kind!

Adding a project to your favorite projects


By simply clicking the icon you can add a project to your favorite projects. The little light bulb icon then changes its color from grey to yellow. Of course, you can remove the project from your favorite projects the same way. To see your favorites, click on the My Favorites in the left navigation pane, or on the Skalli homepage.

Let's finally see how you can create a new project: On the Skalli homepage you will find the link Create Project that navigates you to a page where you can choose what kind of project to create:

Selecting the type of a new project


Currently Skalli provides only two types of projects, free-style projects and free-style components, but you can add custom project types quite easily. The distinction between projects and components is not so sharp as it might appear, but the general idea is the following: In Skalli's philosophy projects are about people — just a couple of people come together to share an idea, work together or produce something, which is not necessarily software. On the other side, there are quite often certain more technically oriented aspects of a project, project artifacts or processes of some kind, and for that Skalli provides components. In practise you will see components usually in deeper levels of a project hierarchy, and actually the only hard rule Skalli forces upon components is that a component must never be the parent of a project.

Let's not bother you with these details now, but just accept the default and click on Create Project. The next screen however should be quite familiar to you: It is just the edit page we have seen before. The only difference is that all the forms are empty and most of the extensions are initially switched off. As mentioned above, Skalli is not very demanding with respect to the minimal set of properties you must maintain for a project: Just enter a Project Id, which must be unique among all the projects so that it can, for example, be used as part of the URL of the project's detail page, and a human readable name that will appear as title of the project everywhere. That's it! Just press OK and admire the project page Skalli creates for you.

This concludes our little walkthrough of the basic screens of Skalli. However, there is much more to discover!

How to Implement Skalli Extensions

You can write your own extensions for Skalli. There are several extension points, e.g. you can add custom properties to the project model, provide a form to edit them, show them in an info box on a project's detail page, pass them to Lucene to search for them, or translate them into REST format. The extension mechanism is based completely on OSGi Declarative Services, with which Eclipse developers should be quite familiar.

There are currently the following tutorials available:

The first shows how to implement a simple Hello World info box, while the second demonstrates everything you need to know if you want to enhance the project model and integrate smoothly with all the services and UIs. The source code of these tutorials is part of the Skalli source code, see bundles org.eclipse.skalli.ext.simplehelloworld and org.eclipse.skalli.ext.helloworld, respectively.

Configuration

Most of the various configuration settings of Skalli can be managed via REST API calls. For Firefox we recommend to use the RESTClient add-on, but curl or another suitable web console should do the job as well.

Choosing the Storage Service

Skalli is not bound to a certain storage mechanism but searches the runtime for suitable implementations of the interface org.eclipse.skalli.services.persistence.StorageService. If not explicitly specified, Skalli will use a file system based storage mechanism by default.

In order to switch to an alternative storage mechanism, you can either

  1. define the system property skalli.storageService and set it to the qualified class name of a storage service implementation.
  2. define the property skalli.storageService in the configuration file skalli.properties which must be added to the root directory of the org.eclipse.skalli.core bundle. If you don't want to change that bundle, create a fragment with org.eclipse.skalli.core as fragment host and add the property file there. You may also download a blueprint from here: [2]. The value of the property again is the class name of the service implementation.

Using File System Based Storage: Setting the Working Directory

If you are using the file system based storage mechanism, you should define a working directory. The file system storage service will use that directory for all project related data and customization settings.

The working directory can be specified

  1. by defining the system property workdir=<path-to-working-directory>
  2. by defining a property workdir in the configuration file skalli.properties (see above)

The value of the property in both cases must be the absolute path of the working directory. If workdir is not set explicitly the current directory is used as default.

Using a Database as Storage

If you want to use a database as the primary storage service, you must define the property skalli.storageService with the value org.eclipse.skalli.core.storage.jpa.JPAStorageComponent. By default, file system persistence is used for project information and customization. For the timeline feature a database is required, but you might still keep your project data in the file system. In that case, configure only the database parameters (see below), but do not change the skalli.storageService property.

Skalli uses the persistence unit store. You can configure all public static final fields from PersistenceUnitProperties by specifying properties of the form

skalli.persistence.<property>=<value>

Database parameters can be specified

  1. by defining system properties (-Dskalli.peristence.<property>) on the command line or in eclipse.ini
  2. by defining properties in the configuration file skalli.properties (see above)

Example : Configuring a permanent Derby database in /tmp/SkalliDB

-Dskalli.storageService=org.eclipse.skalli.core.storage.jpa.JPAStorageComponent
-Dskalli.persistence.eclipselink.target-database=Derby
-Dskalli.persistence.javax.persistence.jdbc.driver=org.apache.derby.jdbc.EmbeddedDriver
-Dskalli.persistence.javax.persistence.jdbc.url=jdbc:derby:/tmp/SkalliDB;create=true
-Dskalli.persistence.javax.persistence.jdbc.user=...
-Dskalli.persistence.javax.persistence.jdbc.password=...

Note, the prepackaged Skalli distribution already contains the necessary Derby bundles and drivers. If you want to use another database, you might need to package suitable drivers from the Gemini DBAccess project.

Configuring LDAP

Skalli is able to use LDAP to retrieve information about users, e.g. to be able to select and manage committers for projects. Note, LDAP is not used to authenticate users accessing Skalli! By default, Skalli is configured to delegate authentication to the web container (FORM-based authentication).

For defining LDAP access you need to issue a PUT request to /api/config/ldap.

PUT https://<your-host>/api/config/ldap
<ldap>
  <providerUrl>ldaps://ldap.example.org:636 </providerUrl>
  <username>skalli@example.org</username>
  <password>verysecretpassword</password>
  <baseDN>CN=Users,DC=example.org</baseDN>
  <searchScope>onelevel</searchScope>
  <ctxFactory>com.sun.jndi.ldap.LdapCtxFactory</ctxFactory>
  <cacheSize>1000</cacheSize>
  <sslNoVerify>true</sslNoVerify>
</ldap>

The given configuration is only an example. Adapt the parameters to your needs.

Notes:

  • <providerUrl> specifies the full URL of the LDAP server to contact including protocol (either ldap: or ldaps:), host and port (default: 389 for ldap:, 636 for ldaps:). (required)
  • <username> and <password> specify the credentials for the LDAP server. (required)
  • <baseDN> defines the base path for search queries. (required)
  • <searchScope> specifies the depth of an LDAP search, either base (only the base path is searched), onelevel (the base path and its direct children are searched) or subtree (the whole subtree under the base path is searched). (required)
  • <cacheSize> gives the number of users that should be cached to reduce the traffic on the LDAP server. The default is 100, which is fine for a Skalli instance with only a couple of projects. Increase the cache size to be larger than the number of distinct project committers.
  • <sslNoVerify> - if set to true, certificates provided by the LDAP server are ignored. Otherwise the LDAP client checks certificates against the default JRE truststore cacerts. Note, this option is only relevant for LDAP over SSL.
  • <authentication> specifies the authentication method to use for communication with the LDAP. Note, that is depends on the LDAP provider, which authentication methods are supported. Default is simple (user/password credentials). For details see the documentation for the java.naming.security.authentication environment variable.
  • <referral> specifies how the LDAP client should handle referrals, either ignore (referrals are ignored), follow (follow referrals automatically) or throw (throw an exception if a referral is encountered). Default is ignore. For details see the documentation for the java.naming.referral environment variable.
  • <ctxFactory> the JNDI context factory to use for creating LDAP connections. Default is com.sun.jndi.ldap.LdapCtxFactory.

Switching between LDAP and a Local User Store

If you prefer to use a Skalli internal store to manage user information like full name and email address instead of using an LDAP server, issue a REST request to resource /api/config/userStore to specify the user store in charge:

PUT https://<your-host>/api/config/userStore
<userStore>
  <type>local</type>
  <useLocalFallback>false</useLocalFallback>
</userStore>

Notes:

  • <type> determines whether LDAP or a local user store should be used to retrieve user information. Allowed values are local (default) and ldap.
  • <useLocalFallback> determines whether the local user store should be used as a fallback if no suitable LDAP server is available (only relevant if type ldap is set. Allowed values are true and false (default).
  • Alternatively you may specify the userstore and the fallback options by defining the system properties userStore.type and userstore.useLocalFallback, respectively. The same can be achieved by defining the corresponding properties in the global configuration file skalli.properties</tt> (see above).

Users are stored in the directory <workdir>/storage/User (if the file system based storage is used). Each user is persisted in a separate XML file named <userId>.xml in this directory.

Example of a <userId>.xml file:

<org.eclipse.skalli.common.User>
  <userId>ad</userId>
  <firstname>Arthur</firstname>
  <lastname>Dent</lastname>
  <email>arthur.dent@milliways.com</email>
  <telephone>+000 314159265</telephone>
  <room>42</room>
  <location>End of the Universe (and then right)</location>
  <department>kitchen</department>
  <company>Milliways - The Restaurant at the End of the Universe</company>
  <sip>sip:arthur.dent@milliways.com</sip>
  <detailsMissing>false</detailsMissing>
</org.eclipse.skalli.common.User>

Notes:

  • userId must be the id of an authenticated user of your web container (Jetty, Tomcat etc.). For example, in Jetty you can define user ids in etc/realm.properties.
  • There is currently no UI to manage users this way.

Configuring User Groups

For the purpose of configuring permissions you may want to create user groups. Currently Skalli has no mechanism to read groups, for example, from LDAP, but you can configure user groups with the REST API (or implement your own GroupService).

The REST API for retrieving and registering groups is assigned to path /api/config/groups:

GET/PUT https://<host>:<port>/api/config/groups
<groups>
  <group>
    <groupId>groupA</groupId>
    <member>user1</member>
    <member>user2</member>
    ...
  </group>
  <group>
    <groupId>groupB</groupId>
    <member>user2</member>
    <member>user3</member>
    ...
  </group>
</groups>

Note that the group identifiers must be unique. You can assign any number of members to a group. Members are referenced by their user identifiers. There is a reserved group "administrators" allowing to define the group of administrators of a Skalli instance (see below).

An individual group can be accessed by /api/config/groups/<groupId>, where <groupId> is the name of the group. The following example would return the members of group groupA from above:

GET https://<host>:<port>/api/config/groups/groupA
 
<group>
  <groupId>groupA</groupId>
  <member>user1</member>
  <member>user2</member>
  ...
</group>

Configuring the Administrators Group

Skalli administrators are usually allowed to do more than normal users, e.g.

  • edit all projects
  • delete projects
  • see issues for all projects
  • configure a Skalli instance

The concrete permissions associated with administrator users however depend on configuration (see Configuring Permissions). After a fresh installation all users are administrators by default. You should change that as soon as possible.

You can define the members of the reserved group administrators via REST API:

PUT/GET https://<host>:<port>/api/config/groups/administrators

For example, suppose you want to put users foo and bar into the administrators group. For that use the following PUT request:

PUT https://<host>:<port>/api/config/groups/administrators
 
<group>
  <groupId>administrators</groupId>
  <member>foo</member>
  <member>bar</member>
</group>

If you delete the "administrators" group or remove all members you will get a warning and all users will be administrators again.

Configuring Roles

Roles are a way to assign permits to users and user groups in an easy way (see Configuring Permissions). Skalli does not make use of the JEE role concept, since most roles in Skalli are project-related (project members, project leads) and not the global roles that JEE can deal with. However, for certain cases, the ability to define global roles and use them for permit configuration might be convenient.

The REST API for retrieving and registering roles is assigned to path /api/config/roles:

GET/PUT https://<host>:<port>/api/config/roles
<roles>
  <role>
    <role>roleA</roleId>
    <user>user1</user>
    <user>user2</user>
    <group>groupX</groups>
    ...
  </role>
  <role>
    <role>roleB</role>
    <group>groupY</group>
    ...
  </role>
</roles>

This is quite similiar to defining user groups, with the difference that roles can be assigned to individual users and user groups. Note that the role identifiers must be unique. You can assign any number of users or groups to a role. Both are referenced by their unique identifiers.

Configuring Authorization

Note, some permit checks in the examples in this section may not yet work. If you want to help implementing them, feel free!

Skalli's authorization concept is based on so-called permits that are related to REST resources. A permit is a triplet of an action, a resource described by its REST resource path and the information whether the action is allowed or forbidden on the resource. Permits can be assigned to individual users or groups of users (which is treated as if the permissions were assigned to all the members of the group), to roles (which can be assigned to users and groups of users), or globally to all users. In summary, permits describe, what the currently logged in user can do or do not with any given resource.

Actions

The actions one can perform on a resource are:

GET reading/viewing/searching a resource
PUT writing/editing an already existing resource
POST creating a new resource
DELETE deleting/archiving a resource

These are the standard REST commands. This list is extensible and we may add more actions in the future.

Resources

Resources are denoted by their REST resource paths (without the /api prefix). For example:

/projects Collection of all projects
/projects/<projectId> Certain project referenced by its project id (or UUID)
/projects/<projectId>/subprojects Collection of subprojects of a given project
/projects/<projectId>/issues Issues of a given project
/projects/<projectId>/properties Properties of a given project
/projects/<projectId>/properties/<propertyName> Property with name <propertyName> of a given project
/projects/<projectId>/extensions Collection of extensions of a given project
/projects/<projectId>/extensions/<shortName> Extension with name <shortName> of a given project
/projects/<projectId>/extensions/<shortName>/properties Properties of an extension with name <shortName> of a given project
/projects/<projectId>/extensions/<shortName>/properties/<propertyName> Property with name <propertyName> of an extension with name <shortName> of a given project
/users Collection of all users
/users/<userId> User with given user identifier
/users/<userId>/permits Permits of a given user
/favorites/<userId> Favorites of a given user
/config Root of all configurations
/config/groups Configuration of user groups
/config/groups/<groupId> Configuration of a certain group
/config/permits Configuration of permits
/config/permits/<permitId> Configuration of a certain permit
/config/roles Configuration of roles
/config/roles/<roleId> Configuration of a certain role

This list, of course, is not complete and not for all of these resources there are corresponding REST requests implemented yet.

Permits

Combining one of the above actions with a resource path and either ALLOW or FORBID specifies a permit. Examples:

ALLOW GET /projects User may read/view/search all projects.
FORBID PUT /projects/**/extensions/devInf User must not edit the Development Information extension (of any project).
ALLOW POST /projects User may create new projects (anywhere in the hierarchy).
ALLOW POST /projects/<projectId>/subprojects User may create subprojects of a given project.
FORBID DELETE /projects/<projectId> User must not delete the given project (but may still delete other projects).
ALLOW PUT /projects/<projectId> User may edit the given project.
ALLOW ** /projects/** User may perform any action on any project.
ALLOW GET /projects/${project} User may retrieve the current project.

The placeholder ** denotes an arbitrary entry of a collection-like resource: A path like /projects/** for example denotes an arbitrary project in the collection of all projects. Note that there is a difference between /projects, which is the collection of all projects, and /projects/**, which denotes a concrete but arbitrary entry in the collection of all projects. Placeholders for actions and collection entries can be combined, like in the second last example.

The placeholder in the last example, ${project}, denotes the project in which context the currently logged in user is navigating. When Skalli evaluates the permits of a user in the context of a certain project, e.g. when the user wants to access a project's detail page, this placeholder is replaced by the project's id. If the user would, for example, request the project skalli the above permit would resolves to ALLOW GET /projects/skalli. Permits of this type are useful for configuring project-related roles.

Combining Permits

By assigning several permits to a user (group, role), one can express more complex situations. For example, a combination of the following permits

FORBID POST /projects
ALLOW POST /projects/<projectId>/subprojects

would allow a user to create projects only as subprojects of a given project <projectId>, but not top-level projects. The combination

FORBID PUT /projects/**
ALLOW PUT /projects/**/extensions/<shortName>
ALLOW PUT /projects/skalli

would prohibt a user from editing projects in general, except for a certain extension <shortName>. Furthermore, in this case the user would be granted edit rights for a project named skalli. For that project, and only for that project, it would be allowed editing all extensions.

Note that a permission that is applied to a resource is automatically applied to all inner resources of that resource, too: A project, for example, has properties and extensions, which again have properties. These are the inner resources of a project. Therefore, a permission applied to a whole project applies also to all its extensions and to the properties of these extensions. However, if there is an explicit permit specified for an inner resource, the inner permit overrules permits specified for the surrounding resource. Furthermore, permits for a concrete resource (like the permit for the concrete project skalli in the example) overrule permits defined for a whole bunch of resources using the ** placeholder. The placeholder ${project} in contrast is replaced by a concrete project id and therefore a permit with a ${project} applies to a concrete resource.

Roles

Roles are a convenient way to assign multiple permissions to a user or group of users. A role is just a configurable collection of permissions with a dedicated name, i.e. the role name. For example, if you assign a user to a project in the UI, the role projectmember is assigned to that user, which is equivalent to assigning all permits configured for that role. Usually you would configure just the following permit for role projectmember:

ALLOW ** /projects/${project}

This permit uses the special placeholder ${project}. When Skalli evaluates the permits of a user in the context of a certain project, e.g. when the user wants to access a project's detail page, this placeholder is replaced by the current project's id and resolves to something like ALLOW ** /projects/skalli. There is another predefined role projectlead which is assigned to project leads. You might create your own project-related roles (see for example Skalli's Scrum extension for an example).

In some cases you might want to restrict the right to elect new project members to, for example, project leads only. You could then configure the following set of permits for role projectmember:

ALLOW ** /projects/${project}
FORBID PUT /projects/${project}/extensions/team

This would allow project members to still view all information of the project and edit it, except for the "team" extension. Therefore, ordinary project members would not be able to elect new members or remove a project lead.

This example also demonstrates that a permit for an inner resource (the team extension) overrules permits cascaded down from an outter resource (the project in this case).

Sources of Permits

The effective set of permissions assigned to any given user at a certain point in time is derived from

  • Global configuration, which defines a basic set of permissions valid for all users
  • Permits of the groups the user is member of
  • Permits associated with roles assigned to the user
  • Individual permits assigned to the user

When a user logs in, Skalli collects all relevant permits from these sources (in the given order, i.e. top-down) and assigns them to the user. It may happen that conflicting permits are configured for any given user, e.g. a certain action on a certain resource might be allowed by global permits, but forbidden by role permits. Such conflicts are resolved in the list top-down: Initially the set of permissions of a certain user is populated with the permissions defined by global configuration. Then all permissions associated with the groups the user is member of are added to the set, and so on. In each step, a permit with given action and resource attributes overwrites any previously found permit with the same action and resource attributes.

Retrieving Effective Permits

The effective set of permits for a given user can be retrieved with the REST call

GET https://<host>:<port>/api/users/<userId>/permits

For a user "hugo" this might for example return

<permits>
  <owner>hugo</owner>
  <permit><action>GET</action><path>/projects/skalli/extensions/team</path><level>1</level></permit>
  <permit><action>**</action><path>/projects/skalli/extensions/team</path><level>0</level></permit>
  <permit><action>PUT</action><path>/projects/skalli</path><level>1</level></permit>
  <permit><action>GET</action><path>/</path><level>1</level></permit>
  <permit><action>**</action><path>/</path><level>1</level></permit>
  ...
</permits>

The order of permits corresponds to the order, in which Skalli would evaluate them during a request. As a rule of thumb, the permits with longer (i.e. representing inner resources), and more concrete paths (with less ** placeholders) tend to be at the top of the list. Level 1 in the result stands for ALLOW, while level 0 corresponds to FORBID. Note that ${project} placeholders are resolved in the result, so the first three permits in the result above may be repeated multiple times for various projects.

The effective set of permits in the context of a certain project can be retrieved with the REST call

GET https://<host>:<port>/api/users/<userId>/permits/<projectId>

The result format is the same as in the example above, just filtered for a certain project. Note that a permit like ALLOW ** / is independent of a project and would therefore be included in the result.

Configuring Permits

Permits can be configured with the REST request /api/config/permits:

PUT https://<your-host>/api/config/permits
<permits>
   <permit>
      <type>global</type>
      <action>GET</action>
      <path>/</path>
      <level>1</level>
    </permit>
    <permit>
      <type>global</type>
      <action>**</action>
      <path>/api/config/**</path>
      <level>0</level>
    </permit>
     <permit>
      <type>role</type>
      <action>**</action>
      <path>/projects/${project}</path>
      <level>1</level>
      <owner>projectmember</owner>
    </permit>
    <permit>
      <type>role</type>
      <action>**</action>
      <path>/projects/${project}</path>
      <level>1</level>
      <owner>projectlead</owner>
    </permit>
    <permit>
      <type>group</type>
      <action>**</action>
      <path>/</path>
      <level>1</level>
      <owner>administrators</owner>
    </permit>
    <permit>
      <type>group</type>
      <action>**</action>
      <path>/api/config/**</path>
      <level>1</level>
      <owner>administrators</owner>
    </permit>
    <permit>
      <type>user</type>
      <action>GET</action>
      <path>/api/config/**</path>
      <level>1</level>
      <owner>hugo</owner>
    </permit>
  </permits>

The above example shows a typical permit configuration for a Skalli instance. Besides the attributes action, path and level, which define a permit, there are additional attributes: type is one of global, role, group or user and corresponds to the sources of permits described above. Furthermore, except for global permits, each configuration entry must be assigned to an owner, which is either a role, group or individual user. In each case the owner is represented by its unique id. If possible you should keep it that way.

The currently configured permits can be retrieved with the request

GET https://<your-host>/api/config/permits

The result format is slightly different:

<permits>
  <permit>
    <pos>0</pos>
    <uuid>769d2202-e8f4-4580-bae9-ad227739fb64</uuid>
    <link rel="self" href="http://<your-host>/api/config/permits/769d2202-e8f4-4580-bae9-ad227739fb64"/>
    <type>global</type>
    <action>GET</action>
    <path>/</path>
    <level>1</level>
  </permit>
  ...

The <uuid> attribute is assigned automatically during the configuration upload and can be used to access and manipulate individual permits. The <pos> parameter gives the index of the permit in the list (starting with 0) and can be used to re-order the permit entries in the list. Note that the order of permit configurations matters! Essentially, for each permit type entries are evaluated top-down in the configuration list.

An individual permit can be retrieved with the REST request

GET http://<your-host>/api/config/permits/<uuid>

The URL is the same as in the link tag in the result above. The result of this request is a single permit configuration, e.g.

<permit>
  <pos>0</pos>
  <uuid>769d2202-e8f4-4580-bae9-ad227739fb64</uuid>
  <link rel="self" href="http://<your-host>/api/config/permits/769d2202-e8f4-4580-bae9-ad227739fb64"/>
  <type>global</type>
  <action>GET</action>
  <path>/</path>
  <level>1</level>
</permit>

In order to move that permit, for example, to the third place in the list, use a PUT request with a pos attribute of 2 (remember: indexes start with 0):

PUT http://<your-host>/api/config/permits/769d2202-e8f4-4580-bae9-ad227739fb64
 
<permit>
  <pos>2</pos>
  <type>global</type>
  <action>GET</action>
  <path>/</path>
  <level>1</level>
</permit>

With the same request you can also change any other attribute of the permit, e.g. path or action.

In order to delete a permit, use the REST request

DELETE http://<your-host>/api/config/permits/<uuid>

Adding new permits requires a POST request to /api/config/permits, e.g.

POST http://<your-host>/api/config/permits
 
<permit>
  <pos>42</pos>
  <type>global</type>
  <action>GET</action>
  <path>/projects</path>
  <level>0</level>
</permit>

Th pos attribute is optional. If no explicit position is specified the new permit is added to the end of the permit list. Otherwise it is inserted at the given position. It is not necessary to specify a UUID, since one is created during the upload automatically.

User Details Links

Defining the URL pattern for links to pages showing details about committers, contributers, members etc. In the Team info box on a project's detail page clicking on the name of a committer leads to the user's detail page.

PUT https://<your-host>/api/config/view/userdetails
<userdetails>
  <url>http://www.eclipse.org/projects/lists.php?list=projectsforcommitter&param=%s</url>
</userdetails>

Notes:

  • %s is a placeholder for the user's identifier.
  • The example above generates links for Eclipse committers.

Proxy

If you are behind a firewall you should configure the proxy to use for outbound HTTP or HTTPS connections, respectively. Skalli for example has a mechanism for checking of URLs defined by projects, and for that it needs to be able to communicate with the outside world. You can define the proxy to use by starting the Java virtual machine with the usual system properties http.proxyHost, http.proxyPort, https.proxyHost, https.proxyPort and proxy.nonProxyHosts.

Example:

-Dhttp.proxyHost=proxy -Dhttp.proxyPort=8080 -Dproxy.nonProxyHosts="*.example.org;*.example.com;non-proxy-host"

Alternatively you may configure the proxy with a REST call to /api/config/proxy.

Example:

PUT https://your-host>/api/config/proxy
<proxy>
  <host>proxy</host>
  <port>8080</port>
  <host.ssl>proxyssl</host.ssl>
  <port.ssl>8443</port.ssl>
  <nonProxyHosts>*.example.org;*.example.com;non-proxy-host</nonProxyHosts>
</proxy>

Automatic URL Inference from SCM Location

A Skalli project can enable the "Development Infrastructure" extension to provide information about the project's source code repository, continuous integration build (e.g. on a Hudson/Jenkins server), bug tracker used to track issues etc. Additionally, a link to a browsable front-end of the source code repository can be entered (e.g. a link to a gitweb server), as well as a link to a code review system like Gerrit.

However, Skalli also supports a mechanism that allows defining automatic mappings between the source repository of a project (in Maven SCM notation) and web sites for browsing of the source code, reviewing of commits etc.

For that you need to issue a PUT request to /api/config/devInf/scmMappings.

Example:

PUT https://<your-host>/api/config/devInf/scmMappings
<?xml version="1.0" encoding="UTF-8" ?>
<scmMappings>
  <scmMapping>
    <id>review.gerrit.example.org</id>
    <purpose>review</purpose>
    <pattern>^scm:git:git://(git\.example\.org)(:\d+)?/(.*)\.git$</pattern>
    <template>http://${1}:8080/#project,open,${3},n,z</template>
    <name>Gerrit Code Review</name>
    <provider>git</provider>
  </scmMapping>
  <scmMapping>
    <id>browse.gitweb.example.org</id>
    <purpose>browse</purpose>
    <pattern>^scm:git:git://(git\.example\.org)(:\d+)?/(.*\.git)$</pattern>
    <template>http://${1}:50000/git/?p=${3}</template>
    <name>Browse Sources in GitWeb</name>
    <provider>git</provider>
  </scmMapping>
  <scmMapping>
    <id>browse.git.eclipse.org</id>
    <purpose>review</purpose>
    <pattern>^scm:git:git://git.eclipse.org/gitroot/(.+\.git)$</pattern>
    <template>http://git.eclipse.org/c/${1}/</template>
    <name>Browse Sources on Eclipse.org</name>
    <provider>git</provider>
  </scmMapping>
</scmMappings>

The first entry for example defines a mapping between Git repositories matching the regular expression (git\.example\.org(:\d+)?)/(.*)\.git (meaning: all Git repositories hosted by the server git.example.org) and a Gerrit code review system (purpose review). When a project defines an SCM location matching the given pattern, Skalli creates a link from the given link template by replacing the numbered variables with the content of the corresponding regular expression groups extracted from the SCM location. In the example above, ${1} stands for the first group, i.e. the host git.example.org (without port), while ${3} denotes the third group, i.e. the repository name. For example, an SCM location like scm:git:git://git.example.org/myproject.git would map to http://git.example.org:8080/#project,open,myproject,n,z. The numbered variable ${0} is replaced by the project's symbolic name, e.g. with technology.skalli, and the named variable ${userId} stands for the identifier of the currently logged in user.

For more details about Java regular expressions and groups refer to [3].

Notes:

  • The mechanism described above is not limited to Git as SCM system. It is based on a simple regular expression matching/replacing mechanism and should be applicable to all kinds of SCM systems.
  • The purpose of a mapping defines for which kind of links a mapping should be applied. Predefined purposes are:
    browse 
    for a link to a browsable front-end of an SCM system like gitweb.
    review 
    for a link to a code review system like Gerrit.
    activity 
    for a link to a graphic visualizing of the commit activity of a project.
    activitydetails
    for a link to details about the commit activity of a project.
    create_bug 
    for a link that allows to create bugs in a bug tracking system.
    copy-to-clipboard 
    for a link that is to be copied to the clipboard. This mapping can for example be used to convert an scm location of the form scm:git:git://git.example.org/skalli.git to https://myaccount@git.example.org/skalli.git prior to copying it to the clipboard. For that, the mapping supports the additional variable ${userId}.
    maven-resolver
    for a link to a git frontend, from which the Maven resolver can retrieve POM files.
    feed 
    for a link to an RSS/Atom feed related to a project. This kind of links is used by the generic feed provider.
    feed-link 
    additional mapping for links within RSS/Atom feeds.
  • Skalli extensions are free to define additional purposes.
  • The id can be defined freely, but must be unique in the list of mappings.
  • The name tag defines the caption an info box should render for mapped links.
  • The provider tag can be used to preselect plugins or connectors that can handle a given scm location (for example the Maven Resolver determines which git frontend to address from the provider attribute).

Mappings for Eclipse Projects

If you use Skalli primarily for managing of projects at eclipse.org, you might find the following mappings interesting:

<?xml version="1.0" encoding="UTF-8" ?>
<scmMappings>
  <scmMapping>
    <id>browse.git.eclipse.org</id>
    <purpose>review</purpose>
    <pattern>^scm:git:git://git.eclipse.org/gitroot/(.+\.git)$</pattern>
    <template>http://git.eclipse.org/c/${1}/</template>
    <name>Browse Sources on Eclipse.org</name>
    <provider>git</provider>
  </scmMapping>
  <scmMapping>
    <id>clipboard.git.eclipse.org</id>
    <purpose>copy-to-clipboard</purpose>
    <pattern>^scm:git:git://git.eclipse.org/gitroot/(.+\.git)$</pattern>
    <template>https://${userId}@git.eclipse.org/gitroot/${1}</template>
    <name>Copy SCM Location to Clipboard</name>
    <provider>git</provider>
  </scmMapping>
  <scmMapping>
    <id>bugs.eclipse.org</id>
    <purpose>create_bug</purpose>
    <pattern>^https://bugs.eclipse.org/bugs/buglist.cgi?.*(product=[^&amp;]*).*</pattern>
    <template>https://bugs.eclipse.org/bugs/enter_bug.cgi?${1}</template>
    <name>Create Bugs on bugs.eclipse.org</name>
    <provider>bugtracker</provider>
  </scmMapping>
  <scmMapping>
    <id>activity.git.eclipse.org</id>
    <purpose>activity</purpose>
    <pattern>^scm:git:git://git.eclipse.org/gitroot/(.+\.git)$</pattern>
    <template>http://dash.eclipse.org/dash/commits/web-app/active-graph.cgi?project=${0}</template>
    <name>Commits Activity Meter</name>
    <provider>git</provider>
  </scmMapping>
  <scmMapping>
    <id>activitydetails.git.eclipse.org</id>
    <purpose>activitydetails</purpose>
    <pattern>^scm:git:git://git.eclipse.org/gitroot/(.+\.git)$</pattern>
    <template>http://dash.eclipse.org/dash/commits/web-app/summary.cgi?company=y&amp;month=x&amp;project=${0}</template>
    <name>Commits by Company by Month</name>
    <provider>git</provider>
  </scmMapping>
</scmMappings>

Automatic URL Inference from Mailing Lists

PUT https://<your-host>/api/config/info/mailingList
<mailingListMappings>
  <mailingListMapping>
    <id>listserv</id>
    <purpose>browse </purpose>
    <name>Browse</name>
    <pattern>^(.+)@listserv.example.org$</pattern>
    <template>https://listserv.example.org/${1}</template>
  </mailingListMapping>
  <mailingListMapping>
    <id>listserv.archive</id>
    <purpose>browse-archive</purpose>
    <name>Browse Archive</name>
    <pattern>^(.+)@listserv.example.org$</pattern>
    <template>https://listserv.example.org/archives/${1}</template>
  </mailingListMapping>
</mailingListMappings>

This mechanism works similar to the SCM mappings above. If a mail address is entered that matches the given pattern, then the template is evaluated and variables are replaced with the corresponding regular expression groups of the pattern. For example, myproject@listserv.example.org would give the URL https://listserv.example.org/myproject to browse the latest content and https://listserv.example.org/archives/myproject to browse an archive of the mailing list, respectively. The defined name is rendered as link label. You may register mappings for different mailing list providers in parallel.

Predefined purposes:

  • browse 
    a link to a browsable view of the latest content of the mailing list
    browse-archive 
    a link to a browsable archive of the mailing list
    subscribe 
    a link that allows to subscribe to the mailing list
    unsubscribe 
    a link that allows to unsubscribe from the mailing list

Note, extensions are free to define additional purposes. The Mailing List info box ignores the purpose and just renders all links that match the entered mailing list(s).

Mappings for Eclipse Projects

If you use Skalli primarily for managing of projects at eclipse.org, you might find the following mappings interesting:

<mailingListMappings>
  <mailingListMapping>
    <id>listinfo.eclipse.org</id>
    <purpose>subscribe</purpose>
    <name>Subscribe/Unsubscribe</name>
    <pattern>^(.+)@eclipse.org$</pattern>
    <template>https://dev.eclipse.org/mailman/listinfo/${1}</template>
  </mailingListMapping>
  <mailingListMapping>
    <id>mhonarc.eclipse.org</id>
    <purpose>browse-archive</purpose>
    <name>Browse Archive</name>
    <pattern>^(.+)@eclipse.org$</pattern>
    <template>http://dev.eclipse.org/mhonarc/lists/${1}</template>
  </mailingListMapping>
</mailingListMappings>

Scheduling of Validation Jobs

Defining a schedule for the asynchronous validation of projects.

PUT https://<your-host>/api/config/validation
<validations>
    <validation>
        <schedule>
            <daysOfWeek>*</daysOfWeek>
            <hours>*/2</hours>
            <minutes>0</minutes>
        </schedule>
        <minSeverity>ERROR</minSeverity>
        <action>VALIDATE</action>
        <userId>homer</userId>
        <entityType>Project</entityType>
    </validation>
    <validation>
        <schedule>
            <daysOfWeek>MON</daysOfWeek>
            <hours>2</hours>
            <minutes>0</minutes>
        </schedule>
        <minSeverity>INFO</minSeverity>
        <action>QUEUE</action>
        <userId>homer</userId>
        <entityType>Project</entityType>
    </validation>
    ...
</validations>

The first entry validates all projects daily every second hour (e.g. a 0:00, 2:00, ...) and reports issues with at least severity ERROR (other possible values: INFO, WARNING, FATAL). The entries of <schedule> support crontab notation defining the minutes (tag <minutes>), hours (tag <hours>) and days of the week (tag <daysOfWeek>) when a validation should run. 24-hour format is used for <hours> (possible values: 0..23). The day of the week can be defined with numbers (0=Sunday,1=Monday,...,7=Sunday), long names (SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY), or short names (SUN, MON, TUE, WED, THU, FRI, SAT), respectively. Note that the names are handled case-insensitive, i.e. Sun, SUN and sun mean all the same.

Supported actions are

  • QUEUE 
    put all entities of the given <entityType> (currently supported values: Project) into the queue for entities to be revalidated. The validation is done asynchronously.
    QUEUE_ALL 
    put all entities of all types into the queue for entities to be revalidated (<entityType> is ignored). The validation is done asynchronously.
    VALIDATE 
    validates entities of the given <entityType> (currently supported values: Project). The validation is done synchronously. Note, depending on the number of entities to validate and validators to be executed this may consume considerable resources on a Skalli instance. You may want to schedule such actions during night times and choose an appropriate <minSeverity>.
    VALIDATE_ALL 
    validates all entities of all types. The validation is done synchronously.

The specified <minSeverity> is passed to all registered validators, so that each validator can decide, whether it should produce issues or not. For example, a validator that checks links to other websites could be designed to produce FATAL issues, if the URL of the link is not a valid URL, ERROR issues, if the link points to a non-existing host, WARNING issues, if the host is temporarily unavailable, and finally INFO issues, if the link is redirected permanently and a project committer should adapt the link.

The severity of issues is defined as follows:

  • FATAL 
    The project (or one of its extensions) cannot be persisted before the issue is resolved. This severity usually indicates a syntactical problem, e.g. a malformed URL. Therefore, it makes not much sense to run a scheduled validation with <minSeverity> FATAL because such validations operate on persisted project data.
    ERROR 
    The issue is serious but the entity can still be persisted. Example: A given URL is valid but points to a non-existing host.
    WARNING 
    The issue is not serious, but should be fixed.
    INFO 
    Not an issue at all, but a hint how the data quality of an entity could be improved further.

Maven POM Resolver

Skalli is able to extract information about the project coordinates and modules from the POM descriptors of Maven projects. Currently this mechanism is limited to projects for which sources are accessible through a supported git frontend like gitweb or gitblit.

A project that wants to participate in that mechanism must enable the Maven project extension in the edit dialog and provide the path to its reactor POM. If the reactor POM resides in the project's root directory, the corresponding attribute can be left empty in the form.

Furthermore, you must configure a schedule for the asynchronous evaluation of the POM descriptors similiar to the scheduling of validation jobs above:

PUT https://<your-host>/api/config/ext/maven/resolver
<mavenResolver>
  <schedule>
    <daysOfWeek>*</daysOfWeek>
    <hours>*/2</hours>
    <minutes>0</minutes>
  </schedule>
  <userId>homer</userId>
</mavenResolver>

The example schedules the evaluation of all Maven reactor POMs on a daily basis every second hour (e.g. a 0:00, 2:00, ...). The entries of <schedule> support the usual crontab notation.

Note that you must provide a suitable SCM location mapping (purpose maven-resolver) for a supported git frontend. Currently there are connectors available for gitweb (provider gitweb) and gitblit (provider gitblit), but there is an extension point for custom POM resolvers.

For example, for a gitweb you might define the following mapping:

  <scmMapping>
    <id>gitweb.resolve</id>
    <purpose>maven-resolver</purpose>
    <pattern>^scm:git:git://(git\.example\.org)(:\d+)?/(.*\.git)$</pattern>
    <template>http://${1}:50000/git/?p=${3}</template>
    <name>Dowload POMs</name>
    <provider>gitweb</provider>
  </scmMapping>

The Maven resolver tries to match the SCM locations of a Maven project (i.e. of a project that has a Maven extension enabled) with the pattern specified in the mappping. If there is a matching, the reactor POM of the project is downloaded and evaluated recursively for modules. The result is stored in the Maven extension and displayed in the corresponding Maven info box.

Nexus Connector

If a Nexus connection is configured the Maven resolver described in the last section can determine available artifact versions for Maven projects:

GET https://<host>:<port>/api/config/ext/nexus
<nexus>
    <url>http://skalli.example.org/nexus/</url>
    <domain>repositories</domain>
    <target>build.milestones</target>
</nexus>

The Nexus connector uses the /service/local/data_index/<domain>/<target>/content?g=<groupId>&a=<artifactId> API call provided by Nexus (for details see https://repository.sonatype.org/nexus-indexer-lucene-plugin/default/docs/rest.data_index.html).

The retrieved artifact versions are stored in the Maven extension of a project.

Destination Service

Skalli extensions can access external systems to gather information, e.g. the Maven & Nexus Resolver or Feeds. Access to such systems can be restricted and credentials are needed (e.g. with https). The destination service allows to store such credentials and provides a pre-configured http client to the extension. It will try to match all supplied regular expression destination patterns with the supplied URL and if a match is found, configure the credentials. Currently BASIC authentication is supported.

PUT https://<your-host>/api/config/destinations
<destinations>
  <destination>
    <id>gitweb.basic-auth</id>
    <authenticationMethod>basic</authenticationMethod>
    <pattern>^https://(git\.example\.org):50001/git/(.*)$</pattern>
    <user>skalli</user>
    <password>verysecretpassword</password>
  </destination>
</destinations>

In a GET request the password will be omitted due to security reasons.

News and Alerts

Defining the target for the What's New? link, as well as alerts and info messages.

PUT https://<your-host>/api/config/view/news
<news>
  <url>http://host.examle.org/whatsnew/technology.skalli</url>
  <alerts>
    <message>This is a test system!</message>
    <message>Next Planned Maintenance: tonight 10pm</message>
  </alerts>
  <messages>
    <message>Do you need help? Please contact our &lt;a href="mailto:heldesk@example.org"&gt;Help Desk&lt;/a&gt;</message>
    <message>bla bla not important bla bla</message>
  </messages>
</news>

Notes:

  • Users are directed to the news URL when clicking on the version link in the upper right corner, too.
  • The alert messages are rendered in red box on the welcome screen and on all major screens in the header bar, while the info message are rendered in light blue boxes only on the welcome page. All messages may contain some basic HTML tags like links and formatting.

Branding

Branding of Skalli by overwriting the default page title.

PUT https://<your-host>/api/config/view/branding
<branding>
  <pageTitle>Projects@Eclipse</pageTitle>
</branding>

Notes:

  • The default page title, if not otherwise configured, is Skalli.
  • The string maintained in <pageTitle> defines the second part of the page titles only. Depending on the page displayed the left part of the page title gives additional information about the page content. For example, the detail page of a project shows the name of the project in the page title.

Top Links

Defining Top Links (Sponsored Links) to be display in the header of all Skalli pages.

PUT https://<your-host>/api/config/view/toplinks
<toplinks>
  <toplink>
    <displayName>Home</displayName>
    <url>http://www.eclipse.org</url>
  </toplink>
  <toplink>
    <displayName>Downloads</displayName>
    <url>http://www.eclipse.org/downloads/</url>
  </toplink>
  <toplink>
    <displayName>Users</displayName>
    <url>http://www.eclipse.org/users/</url>
  </toplink>
  <toplink>
    <displayName>Members</displayName>
    <url>http://www.eclipse.org/membership/</url>
  </toplink>
  <toplink>
    <displayName>Committers</displayName>
    <url>http://www.eclipse.org/committers/</url>
  </toplink>
  <toplink>
    <displayName>Resources</displayName>
    <url>http://www.eclipse.org/resources/</url>
  </toplink>
  <toplink>
    <displayName>Projects</displayName>
    <url>http://www.eclipse.org/projects/</url>
  </toplink>
  <toplink>
    <displayName>About Us</displayName>
    <url>http://www.eclipse.org/org/</url>
  </toplink>
</toplinks>

Notes:

  • The URL maintained in <url> defines the destination of a top link.
  • The string maintained in <displayName> defines the label rendered for the link.

Feedback Link

Providing a link to which users can send bug reports, feature requests, questions etc.

PUT https://<your-host>/api/config/view/feedback
<feedback>
  <url>mailto:skalli-support%40.example.org%3fsubject%3dFeedback</url>
  <displayName>Feedback</displayName>
</feedback>

Notes:

  • The maintained <url> is called when a user clicks on the feedback link displayed in the header of all Skalli pages (between the logged in user and the version information). Usually this link redirects to an email address (as in the example).
  • The string maintained in <displayName> is used as label for the feedback link.


Gerrit Connector

Configuring host/port and credentials for connections to Gerrit servers:

PUT https://<your-host>/api/config/gerrit

The body may contain multiple server configurations, e.g.

<servers>
  <server>
    <id>main-gerrit</id>
    <name>Productive Gerrit</name>
    <description>Use this Gerrit for serious projects</description>
    <contact>gerrit-admins@example.corp</contact>
    <protocol>ssh</protocol>
    <host>gerrit.example.org</host>
    <port>29418</port>
    <user>Arthur</user>
    <privateKey>-----BEGIN RSA PRIVATE KEY-----
      Proc-Type: 4,ENCRYPTED
      DEK-Info: DES-EDE3-CBC,61D359AC0BC0C4BD
 
      rSy...
    </privateKey>
    <passphrase>password</passphrase>
    <scmTemplate>scm:git:${protocol}://${host}:${port}/${repository}.git</scmTemplate>
    <groupDescription>Created by ${user}. More details: ${link}</groupDescription>
    <projectDescription>Created by ${user}. More details: ${link}</projectDescription>
    <subprojectsOnly>true</subprojectsOnly>
    <parent>-- All Projects --</parent>
    <branch>master</branch>
    <useContributorAgreement>true</useContributorAgreement>
    <useSignedOffBy>true</useSignedOffBy>
  </server>
  <server>
    <id>sandbox-gerrit</id>
    <name>Sandbox Gerrit</name>
    <description>Use this Gerrit for playing around and testing</description>
    <contact>gerrit-admins@example.corp</contact>
    <protocol>ssh</protocol>
    <host>gerrit-sandbox.example.org</host>
    ...
  </server>
</servers>

Notes:

  • <id> a unique identifier of the Gerrit server, e.g. a host name [mandatory].
  • <name> a human readable name or identifier for the Gerrit server to be displayed in the UI selection list [mandatory].
  • <description> an optional description for the Gerrit server.
  • <protocol> must currently be ssh since this is the only support protocol for Gerrit's admin API [mandatory].
  • <user>, <privateKey> and <passphrase> specify the credentials for the communication with Gerrit [mandatory].
  • <contact> specifies a mail address to contact for problems with the Gerrit server. A link labeled Gerrit Contacts will then appear on the Create Git/Gerrit Repository form. If empty, no link will be rendered.
  • <scmTemplate> defines a blueprint for the SCM location attribute Skalli should assign to a project after successfully creating a Git repository. If not specified, Skalli uses a default value as shown in the example. The value may contain the following variables (among others, but these are the most useful):
    • ${repository} - the name of the Git repository;
    • ${protocol} - the protocol used by Gerrit (as specified with the configuration parameter <protocol>);
    • ${host} - the Gerrit host (as specified with the configuration parameter <host>);
    • ${port} - the Gerrit port (as specified with the configuration parameter <port>);
    • ${userId} - the unique identifier of the user creating the Gerrit project;
    • ${projectId} - the symbolic name of the project to which the Git repository is assigned;
  • <projectDescription> defines a blueprint for the title assigned to Gerrit projects. The title is for example displayed in Gerrit's project list. If not specified, Skalli uses a default value as shown in the example. The value may contain the following variables (in addition to those mentioned for <scmTemplate>):
    • ${link} - link to the project's detail page, e.g. http://example.org/projects/skalli;
    • ${user} or ${user.displayName} - the display name of the user creating the Gerrit project;
    • ${user.email} - the email address of the user creating the Gerrit project; in principle, all properties of a user can be specified in the form ${user.propertyName};
    • ${name} - the display name of the project to which the Git repository is assigned;
    • properties of extensions of the project in the form ${extensionName.propertyName};
  • <groupDescription> defines a blueprint for the title assigned to Gerrit groups. If not specified, Skalli uses a default value as shown in the example. The value may contain the same variables as the project description;
  • <subprojectsOnly> - if set to true, only subprojects, but not top-level projects are allowed to have Git repositories.
  • <parent> the Gerrit project that will be set as parent for all projects created with the Create Git/Gerrit Repository form, unless an explicit parent is specified in the form. Newly created Gerrit projects will inherit access rights from this parent project. If not specified, the parent is set to the default project -- All Projects --. For details see the --parent option of Gerrit's create-project commmand.
  • <branch> specifies which default branch to create in a Git repository. If not specified, a master branch ist created. For details see the --branch option of Gerrit's create-project commmand.
  • <submitType> specifies the default submit type of the Git repository, either FAST_FORWARD_ONLY, MERGE_IF_NECESSARY (default), MERGE_ALWAYS or CHERRY_PICK. For details see the --submit-type option of Gerrit's create-project commmand.
  • <useContributorAgreement> - if set to true, Gerrit requires a contributor agreement for contributing patches to the Gitr repository. For details see the --use-contributor-agreements option of Gerrit's create-project commmand.
  • <useSignedOffBy> - if set to true, Gerrit requires a Signed-off-by header in commits. For details see the -use-signed-off-by option of Gerrit's create-project commmand.

Timeline and Feeds

Note: The timeline mechanism requires a database storage.

The timeline info box shows recent changes to resources related to a project, like committs in the source code repository, build jobs or updates of issues in a bugtracking system. The information for the timeline is retrieved from remote systems on a regular basis if you define a corresponding schedule:

PUT https://<your-host>/api/config/feed/updater
<feedUpdater>
  <schedule>
    <daysOfWeek>*</daysOfWeek>
    <hours>*</hours>
    <minutes>00</minutes>
  </schedule>
</feedUpdater>

The entries of <schedule> support the usual crontab notation.

The actual downloading of timeline information is performed by so-called feed providers. This is an extension point, for which you can register custom feed providers for more specialized backend systems. By default, a generic feed provider for retrieving RSS/Atom feeds from remote systems is available.

Configuring the Generic RSS/Atom Feed Provider

The generic feed provider searches for SCM location mappings with purpose feed and interprets the derived links as RSS/Atom feeds.

For example, suppose there is a gitweb fronend for your git repositories available, then you might configure the following SCM mapping:

<?xml version="1.0" encoding="UTF-8" ?>
<scmMappings>
  <scmMapping>
    <id>feed.gitweb</id>
    <name>Git</name>
    <purpose>feed</purpose>
    <pattern>^scm:git:(git|ssh|http|https)://(git\.example\.org)(:\d+)?/(.*\.git)$</pattern>
    <template>https://${2}/git/?p=${4};a=atom</template>
    <provider>gitweb</provider>
  </scmMapping>
</scmMappings>

This would allow retrieving timeline information for all projects with SCM locations matching the given pattern by tapping gitweb's atom feeds for these projects. This mechanism is not limited to git frontends, but you can access arbitrary RSS/Atoms feeds as long as URLs for these feeds can be derived from the SCM locations of projects.

Note, the name attribute of a configuration is used as checkbox label in the timeline infobox. The provider attribute is used internally to distinguish the various sources of timeline information. Both attributes should be defined thoroughly and should be different for all mappings with purpose feed (unless you want to mix feed information for example from multiple gitweb servers).

Configuring the Hudson/Jenkins Feed Provider

No additional configuration is required, but a project must define a suitable CI URL in its development infrastructure information.

Configuring an Additional Link Mapping

Sometimes it might be necessary to map links contained in RSS/Atom feed entries for display. For that you might define an additional SCML location mapping with purpose feed-link:

<scmMappings>
    <scmMapping>
        <id>feed.link.gitweb</id>
        <purpose>feed-link</purpose>
        <pattern>^https://(example\.dot\.org)(:\d+)?/(.+)$</pattern>
        <template>https://${1}:50001/${2}</template>
        <name>Map Feed Links</name>
        <provider>git</provider>
    </scmMapping>
</scmMappings>

REST API Usage

All information associated with a project and its extensions, issues, users, access statistics etc. can be retrieved from a REST-like API with HTTP GET commands. Write access currently is only partly implemented.

In general, the REST API uses the same URL scheme as the browsable UI. For example, the detail page of a project with name technology.skalli is accessible with the URL

https://<host>:<port>/projects/technology.skalli

The corresponding REST information then can be obtained with a GET request like

GET https://<host>:<port>/api/projects/technology.skalli

Note the prefix /api/ at the beginning of the resource path.

XML Schemas for the REST API

Skalli's REST API provides all resources as XML documents. XML schemas for these documents can be downloaded from a running Skalli instance with

GET https://<host>:<port>/schemas/<schema>

where <schema> is one of the following:

project.xsd 
Schema for a single project resource
projects.xsd 
Schema for the all projects list
subprojects.xsd 
Schema for the subprojects list of a project
user.xsd 
Schema for a user resource
issues.xsd 
Schema for validation issues reported for a project
common.xsd 
Common declarations used by all schemas

These schemas are documented and should be self-explaining.

Extensions provide their own XML schemas, for example:

extension-info.xsd 
Schema for the Info extension (basic stuff like link to home page, mailing lists etc.)
extension-people.xsd 
Schema for the People extension (info about project leads and committers)
extension-devinf.xsd 
Schema for the Develoment Infrastructure extension (info about SCM locations, bugtracker etc.)
extension-scrum.xsd 
Schema for the Scrum extension (additional info for projects following a Scrum-like development process)
extension-maven.xsd 
Schema for the Maven extension (additional info for projects built with Maven)
extension-review.xsd 
Schema for the Review extension (reviews and ratings of a project)

Note, this list is not complete since Skalli supports custom extensions. It is not required, but strongly encouraged that custom extensions provide a suitable XML schema, too. Skalli searches bundles implementing custom extensions for a folder named schemas and makes schemas found there available for download automatically (compare for example the bundle org.eclipse.skalli.model.ext.misc). The naming convention for schema files is extension-<shortname>.xsd. For details consult the tutorials and documentation about writing custom extensions.

Common REST Requests

List All Projects

To collect information about all the projects available in Skalli issue a GET request to /api/projects.

GET https://<host>:<port>/api/projects

The response looks similar to:

<?xml version="1.0" encoding="UTF-8" ?>
<projects xmlns="http://www.eclipse.org/skalli/2010/API" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://www.eclipse.org/skalli/2010/API http://skalli.example.org/schemas/projects.xsd" 
    apiVersion="1.4">
  <project apiVersion="1.4" lastModified="2011-05-11T15:03:48.254Z" modifiedBy="admin">
    <uuid>98620072-2e54-4e71-9ce1-51a81fc8761c</uuid>
    <id>hello</id>
    <template>default</template>
    <name>Hello World</name>
    <link rel="project" href="http://skalli.example.org/api/projects/98620072-2e54-4e71-9ce1-51a81fc8761c"/>
    <link rel="browse" href="http://skalli.example.org/projects/hello"/>
    <link rel="issues" href="http://skalli.example.org/api/projects/98620072-2e54-4e71-9ce1-51a81fc8761c/issues"/>
    <phase>initial</phase>
    <description>The Hello World projects is a default dummy project</description>
    <extensions/>
  </project>
  <project>...</project>
 </projects>

Note that by default only some basic information is returned for each project, but no information from the project's extensions. However, by adding the query parameter extensions=<comma-separated list of extensions> to the URL, you can choose to retrieve information from selected extensions, too.

For example, with

https://<host>:<port>/api/projects?extensions=people,devInf

you could obtain the project leads and committers of all projects as well as information about the development resources (repositories, bugtrackers etc.) used by these projects.

The XML schema for the response can be retrieved from any running Skalli instance with the URL https://<host>:<port>/schemas/projects.xsd.

Search Projects

The REST API supports searching for projects with Lucene queries. Furthermore, you can retrieve all projects with a certain tag.

Searching with a Lucene query 
https://<host>:<port>/api/projects?query=<lucene query>

The query parameter can be any valid Lucene query and must be properly encoded. query=* returns all known projects.

Searching for projects that have a certain property 
https://<host>:<port>/api/projects?query=<lucene query>&property=<extension.propertyName>

The property is specified by the name of the extension it belongs to (e.g. info, devInf) plus its own name. For example: property=info.pageUrl would match projects with a homepage link. The extension prefix can be omitted, if a property of the project itself is address. For example property=description would match projects with a non-blank description.

Searching for projects that do not have a certain property 
https://<host>:<port>/api/projects?query=<lucene query>&property=<!extension.propertyName>

Unlike in the use case above the query will return all the projects with the given extension that do not define a property with the given propertyName

Searching for projects that have a property matching a certain pattern 
https://<host>:<port>/api/projects?query=<lucene query>&property=<extension.propertyName>
&pattern=<regular expression>

By adding a pattern one can search for projects that have properties matching a given regular expression. For example, property=projectId&pattern=technology%5c%2e%2e%2b would match projects with symbolic names starting with technology. (technology%5c%2e%2e%2b is the URL-encoded form of technology\..+). The search is by default case-sensitive, but you may add the query parameter ignoreCase to search case-insensitive. Note, case-insensitive search may be less performant, since Unicode case-matching rules are applied.

Note, for collection-like properties (e.g. devInf.scmLocations) the pattern is applied to all collection entries. A project matches if any of the entries matches the given pattern.

This query is especially useful for mass data changes.

Searching for all projects with a certain tag 
https://<host>:<port>/api/projects?tag=<tag>


The result for all these queries is a list of projects with the same level of details as for the "all projects list" above, i.e. by default no information from project extensions is returned. However, by adding the query parameter extensions=<comma-separated list of extensions> to the URL, you can choose to retrieve information from selected extensions, too.

If not otherwise specified, the requests return all matching results sorted by relevance, best matches first. If you want to limit the number of hits returned by the query, add the query parameter count=<number of hits> to the request URL. You can also consume the result "page by page" like in the UI by adding the query parameter start=<index of first hit> to the request URI.

Project Details

In order to retrieve detail information about a certain project and its extensions, use a REST call of the following pattern:

GET https://<host>:<port>/api/projects/<projectId>

You can either use the project's symbolic name, e.g. technology.skalli, or its UUID. Note that the symbolic name of a project can change over time, while the UUID is fixed once the project is created.

A typical result would look like this:

<?xml version="1.0" encoding="UTF-8" ?>
<project xmlns="http://www.eclipse.org/skalli/2010/API" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://www.eclipse.org/skalli/2010/API https://skalli.example.org/schemas/project.xsd" 
    apiVersion="1.4" lastModified="2011-11-21T10:42:44.176Z" modifiedBy="hugo">
  <uuid>2f50f2a1-ddaf-4e7b-adea-e10294303887</uuid>
  <id>technology.skalli</id>
  <template>default</template>
  <name>Eclipse Skalli</name>
  <shortName>skalli</shortName>
  <link rel="project" href="https://skalli.example.org/api/projects/2f50f2a1-ddaf-4e7b-adea-e10294303887"/>
  <link rel="browse" href="https://skalli.example.org/projects/technology.skalli"/>
  <link rel="issues" href="https://skalli.example.org/api/projects/2f50f2a1-ddaf-4e7b-adea-e10294303887/issues"/>
  <phase>Incubation</phase>
  <description>One of the major goals of this project is to make a new generation project management 
tool accessible and usable by the Eclipse community and other open source projects.... </description>
  <link rel="parent" href="https://skalli.example.org/api/projects/5856b08a-0f85-4d31-b007-ab367cfd247a"/>
  <members>
    <member>
      <userId>mochmann</userId>
      <link rel="user" href="https://skalli.example.org/api/user/mochmann"/>
      <name>Michael Ochmann</name>
      <firstName>Michael</firstName>
      <lastName>Ochmann</lastName>
      <email>michael@example.org</email>
      <role>projectmember</role>
    </member>
    <member>
      <userId>bvariwg</userId>
      <link rel="user" href="https://skalli.example.org/api/user/bvariwg"/>
      <name>Britta Varwig</name>
      <firstName>Britta</firstName>
      <lastName>Varwig</lastName>
      <email>britta@example.org</email>
      <role>projectmember</role>
    </member>
    <member>
      <userId>skaufmann</userId>
      <link rel="user" href="https://skalli.example.org/api/user/skaufmann"/>
      <role>projectmember</role>
      <role>projectlead</role>
    </member>
  </members>
  <extensions>
    <devInf xmlns="http://www.eclipse.org/skalli/2010/API/Extension-DevInf" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.eclipse.org/skalli/2010/API/Extension-DevInf https://skalli.example.org/schemas/extension-devinf.xsd"
        apiVersion="1.0" lastModified="2011-09-30T17:43:43.425Z" modifiedBy="mochmann" inherited="false" derived="false">
      <bugtrackerUrl>https://bugs.eclipse.org/bugs/buglist.cgi?query_format=specific&amp;order=relevance+desc&amp;bug_status=__open__&
amp;product=Skalli</bugtrackerUrl>
      <ciUrl>https://hudson.eclipse.org/hudson/job/skalli/</ciUrl>
      <scmLocations>
        <scmLocation>scm:git:git://git.eclipse.org/gitroot/skalli/org.eclipse.skalli.git</scmLocation>
      </scmLocations>
    </devInf>
    <info xmlns="http://www.eclipse.org/skalli/2010/API/Extension-Info" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://www.eclipse.org/skalli/2010/API/Extension-Info https://skalli.example.org/schemas/extension-info.xsd"
          apiVersion="1.0" inherited="false" derived="false">
      <homepage>http://www.eclipse.org/skalli/</homepage>
      <mailingLists>
        <mailingList>skalli-dev@eclipse.org</mailingList>
      </mailingLists>
    </info>
    <people xmlns="http://www.eclipse.org/skalli/2010/API/Extension-People" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://www.eclipse.org/skalli/2010/API/Extension-People https://skalli.example.org/schemas/extension-people.xsd" 
          apiVersion="1.0" inherited="false" derived="false">
      <leads>
        <lead>
          <userId>skaufmann</userId>
          <link rel="user" href="https://skalli.example.org/api/user/skaufmann"/>
        </lead>
      </leads>
      <members>
        <member>
          <userId>mochmann</userId>
          <link rel="user" href="https://skalli.example.org/api/user/mochmann"/>
        </member>
        <member>
          <userId>bvarwig</userId>
          <link rel="user" href="https://skalli.example.org/api/user/bvarwig"/>
        </member>
        <member>
          <userId>rwetzold</userId>
          <link rel="user" href="https://skalli.example.org/api/user/rwetzold"/>
        </member>
      </members>
    </people>
    ...
  </extensions>
</project>

The XML schema for the response can be retrieved from any running Skalli instance with the URL https://<host>:<port>/schemas/project.xsd.

It is also possible to retrieve known validation issues for a certain project:

GET https://<host>:<port>/api/projects/<projectId>/issues

The response could look like the following:

<issues 
        xsi:schemaLocation="http://www.eclipse.org/skalli/2010/API https://skalli.example.org/schemas/issues.xsd" 
        apiVersion="1.0" lastModified="2011-11-30T05:42:19.722Z" modifiedBy="skalli">
    <isStale>false</isStale>
    <issue>
        <timestamp>1322631739713</timestamp>
        <severity>WARNING</severity>
        <extension>org.eclipse.skalli.model.core.Project</extension>
        <propertyId>description</propertyId>
        <issuer>org.eclipse.skalli.common.util.ProjectDescriptionValidator</issuer>
        <item>0</item>
        <message>The project description is empty. Let others know what this is about.</message>
    </issue>
    <issue>
        <timestamp>1322631739713</timestamp>
        <severity>WARNING</severity>
        <extension>org.eclipse.skalli.model.ext.devinf.DevInfProjectExt</extension>
        <propertyId>ciUrl</propertyId>
        <issuer>org.eclipse.skalli.common.util.HostReachableValidator</issuer>
        <item>0</item>
        <message>'https://hudson.eclipse.org/hudson/job/skali/' not found on target server (404 Not Found).</message>
    </issue>
</issues>

In the example, the project has two validation issues, both of severity WARNING, one in the project's basic information (the description is missing), and another in the Development Infrastructure extension (the URL has a typo and therefore points to nowhere). The lastModified attribute tells when the project has been checked last, and the <isStale> tag indicates whether the following list of issues is still valid. Since Skalli executes all validation checks asynchronously, it might happen that the project is already scheduled to be re-validated in the near future. In that case, the stale flag is set and a client may decide to wait for the re-validation, or take the (possibly outdated) result from the last run.

The XML schema for the response can be retrieved from any running Skalli instance with the URL https://<host>:<port>/schemas/issues.xsd.

List of Subprojects

To list all subprojects for a given project use the following request:

GET https://<host>:<port>/api/projects/<projectId>/subprojects

The response returns a plain unsorted list of subprojects. It is possible to provide a depth of search as a request parameter:

GET https://<host>:<port>/api/projects/<projectId>/subprojects?depth=<depth>

If depth is not specified, the search will traverse the whole project hierarchy.

A typcial example of a project with some subprojects could look like the following:

<?xml version="1.0" encoding="UTF-8" ?>
<subprojects xmlns="http://www.eclipse.org/skalli/2010/API" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://www.eclipse.org/skalli/2010/API https://skalli.example.org/schemas/subprojects.xsd" 
     apiVersion="1.0">
  <project apiVersion="1.4" lastModified="2011-11-21T10:42:44.176Z" modifiedBy="hugo">
    <uuid>2c50f6a1-ddaf-4e7b-aded-e10295303887</uuid>
    <id>technology.skalli</id>
    <template>default</template>
    <name>Eclipse Skalli Orbit</name>
    <shortName>skalliorbit</shortName>
    <link rel="project" href="https://skalli.example.org/api/projects/2c50f6a1-ddaf-4e7b-aded-e10295303887"/>
    <link rel="browse" href="https://skalli.example.org/projects/technology.skalli"/>
    <link rel="issues" href="https://skalli.example.org/api/projects/2c50f6a1-ddaf-4e7b-aded-e10295303887/issues"/>
    <phase>Incubation</phase>
    <description>...</description>
    <link rel="parent" href="https://skalli.example.org/api/projects/5856b08a-0f87-4d91-b007-ac367ced247a"/>
    <extensions/>
  </project>
  <project apiVersion="1.4" lastModified="2011-09-12T12:40:09.877Z" modifiedBy="hugo">
      ...
  </project>
</subprojects>

The content is the same as for the list of all projects above and contains no information from project extensions by default. However, by adding the query parameter extensions=<comma-separated list of extensions> to the URL, you can choose to retrieve information from selected extensions, too.

The XML schema for the response can be retrieved from any running Skalli instance with the URL https://<host>:<port>/subprojects.xsd.

Timeline

Information about changes to project resources, like new commits, can be retrieves as RSS or Atom feed with

GET https://<host>:<port>/api/projects/<projectId>/timeline

By default, an RSS 2.0 feed is provided.

Another feed format can be selected by adding a format query parameter with one of the following supported formats: atom_0.3, atom_1.0, rss_0.9, rss_0.91N (RSS 0.91, Netscape variant), rss_0.91U (RSS 0.91, Userland variant), rss_0.92, rss_0.93, rss_0.94, rss_1.0, rss_2.0, atom (equivalent to atom_1.0) or rss (equivalent to rss_2.0).

The following would, for example, return the timeline as Atom 1.0 feed:

GET https://<host>:<port>/api/projects/<projectId>/timeline?format=atom

Feed entries can be filtered by adding a sources query parameter. The value is a comma-separated list of source identifiers, such as git, gitweb or jenkins, depending on the available feed updater plugins (interface o.e.s.services.feed.FeedUpdater).

The number of feed entries to return may be specified with a count query parameter. Default is 10.

User Information

To get the contact information of a certain user use the following REST request:

GET https://<host>:<port>/api/user/<userId>

The response will look similar to:

<?xml version="1.0" encoding="UTF-8" ?> 
<user xmlns="http://www.eclipse.org/skalli/2010/API" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://www.eclipse.org/skalli/2010/API http://skalli.example.org/schemas/user.xsd" apiVersion="1.0">
  <link rel="self" href="https://skalli.example.org/api/user/mochmann" /> 
  <userId>mochmann</userId> 
  <firstname>Michael</firstname> 
  <lastname>Ochmann</lastname> 
  <email>...</email> 
  <phone>...</phone> 
  <sip>...</sip> 
  <company>...</company> 
  <department>...</department> 
  <location>...</location> 
  <room>...</room> 
</user>

The XML schema for the response can be retrieved from any running Skalli instance with the URL https://<host>:<port>/schemas/user.xsd.

Refresh Actions on Infoboxes

Infoboxes on project detail pages may implement generic actions, for example a refresh action for the content displayed, that can be triggered through special URLs.

In order to trigger an action on a certain infobox use the following URL pattern:

GET https://<host>:<port>/projects/<projectName>/infoboxes/<shortName>?action=<action>

In order to trigger an action for all infoboxes that support a certain action you might also use the following shortcut:

GET https://<host>:<port>/projects/<projectName>/infoboxes?action=<action>

In both cases, <action> is the identifier of the action to trigger. It depends on the individual infobox, which actions it provides, but usually you can expect that infoboxes support at least the refresh action (which of course may just render the same content again). In order to address an individual infobox you need the unique <shortName> of that infobox. The following list gives the short names of the standard infoboxes:

  • About :
  • Mailing Lists :
  • Development Information
  • Additional Links :
  • Project Activity :
  • Project Hierarchy :
  • Team :
  • Scrum :
  • Related Projects :
  • Issues :
  • Maven Project Information : maven
  • Timeline :

Infoboxes that want to support actions must implement a suitable perform method (see interface InfoBox).

Admin Tasks

User Groups

In order to manage and retrieve user groups use the following REST call:

PUT/GET https://<host>:<port>/api/config/groups

You might also access individual groups with

PUT/GET https://<host>:<port>/api/config/groups/<groupId>

For example, the following would define the members for two groups, administrators and anotherGroup, respectively.

<groups>
  <group>
    <groupId>administrators</groupId>
    <member>skalliadmin</member>
    <member>jon</member>
  </group>
  <group>
    <groupId>anotherGroup</groupId>
    <member>jon</member>
    <member>jim</member>
  </group>
</groups>

Each group must have a unique groupId and one or many member entries. The group name administrators is reserved and enumerates the administrators of the current Skalli instance. Find more details about administrators in section Configuring Administrator Users .

List of Bundles

To get the statuses for all referenced bundles issue a GET request to /api/admin/status

GET https://<host>:<port>/api/admin/status

The response will contain a list of bundles:

<bundles>
 <bundle>
      <name>org.eclipse.skalli.common</name>
      <version>0.1.0.qualifier</version>
      <state>Active</state>
    </bundle>
  <bundle>...</bundle>
 </bundles>

with their names, versions and states (ACTIVE, INSTALLED, UNINSTALLED, STARTING, STOPPING, RESOLVED)

Statistics

To see the information about the usage of your application issue a GET request to /api/admin/statistics

GET https://<host>:<port>/api/admin/statistics

The response provides you with statistics from the last start of the application and contains such info as the amount of users, their IDs, locations, which browsers and URLs they used, which search strings, etc.:

<?xml version="1.0" encoding="UTF-8" ?>
<statistics xmlns="http://www.eclipse.org/skalli/2010/API/Admin" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://www.eclipse.org/skalli/2010/API/Admin 
     http://skalli.example.org/schemas/admin-statistics.xsd" apiVersion="1.0">
  <info>
    <started>01.06.2011 16:07:02</started>
    <snapshot>03.06.2011 16:34:47</snapshot>
    <duration>02 days 00:27:45</duration>
  </info>
  <users>
    <count>0</count>
    <userIds/>
    <locations/>
    <departments/>
  </users>
  <browsers/>
  <referers>
    <referer count="12">admin</referer>
  </referers>
  <usages/>
  <searches/>
</statistics>

Backup & Restore

To backup project data, favorites, issues, users, groups and the configuration use the following request:

GET https://<host>:<port>/api/admin/backup

This returns a ZIP file containing the requested resources in XML format. You may also backup only part of the information by appending include or exclude lists to the URL, respectively:

GET https://<host>:<port>/api/admin/backup?exclude=Favorites,User
GET https://<host>:<port>/api/admin/backup?include=Project,Issues

The first request excludes favorites and users from the backup, while the second only includes projects and related issues. The parameter values are comma-separated lists of the following storage categories: Project, Issues, Favorites, User and customization.

To restore data use the corresponding PUT request:

PUT https://<host>:<port>/api/admin/backup

The ZIP archive containing the backup information must be sent in the request body. For example, use curl for upload:

curl -u <user>:<password> --basic --upload-file "backup.zip" "http://localhost:8080/api/admin/backup?action=overwrite"

Note, this request rejects attempts to overwrite non-empty storage categories by default (returned status code: 412). The parameter action=overwrite must be added to enforce the restore, or the non-empty storage categories must be excluded explicitly.

For example, the following request

PUT https://<host>:<port>/api/admin/backup?exlude=Issues&action=overwrite

would restore all storage categories (by forcefully overwriting any existing content) except issues.

Monitor the Validation Queue

To get the status and content of currently queued items in the validation queue use a REST request of the following form:

GET https://<host>:<port>/api/admin/services/org.eclipse.skalli.core.validation/monitors/queue

Note, you might register custom monitors for other services, too. (TODO: describe the service monitor extension point).


Mass Data Change

It might be handy to change a certain property in all the projects, that contain it.

GET https://<host>:<port>/api/projects?query=<lucene query>&property=<extension.propertyName>
&pattern=<regular expression>

The result enumerates those projects that would match the criteria for a mass data change. Note that the result automatically contains detail information about the named extension, i.e. the result looks like as if you had added an &extensions=<extension> parameter to the query. This way you can easily verify that your query worked.

  • Second, perform a dry run, i.e. let Skalli change the specified property on all the projects matching your query by applying a template, but without saving the result.

To do so, just switch the HTTP command to PUT

PUT https://<host>:<port>/api/projects?query=<lucene query>&property=<extension.propertyName>
&pattern=<regular expression>

and add a request body describing how to update the value of the property. For example, you might want to replace the homepage URLs of your projects, because the host name has changed:

PUT https://<host>:<port>/api/projects?query=*&property=info.pageUrl
&pattern=http%3A%2F%2Foldhost.example.org%2F%28.%2B%29
<propertyUpdate>
   <template>http://newhost.example.org/${1}</template>
</propertyUpdate>

The given pattern is the URL-encoded form of the regular expression http://oldhost.example.org/(.+). Like for SCM location mappings, placeholders like ${1} in the template are replaced by the corresponding groups from the regular expression. After the replacement the project is validated for FATAL issues to detect for example syntactical errors the update would introduce.

The PUT request in the example would return the same result as the corresponding GET request, with the exception that all pageUrl properties had been updated. This way you could easily verify that the mass change worked as intended.

  • Finally, you can apply the mass data change by adding the parameter persist=true to the PUT request:
PUT https://<host>:<port>/api/projects?query=*&property=info.pageUrl
&pattern=http%3A%2F%2Foldhost.example.org%2F%28.%2B%29&persist=true
<propertyUpdate>
   <template>http://newhost.example.org/${1}</template>
</propertyUpdate>

WARNING: Backup your project data before applying a mass data change!

Terms

[Skalli] Extension All display & application logic elements needed to provide a specific functionality. You can write your own extensions and bring Skalli to visualise their information.
Info Box A single box displaying the information of one extension to the user
Project Details Page The main project page containing the info boxes
View Mode The project details page without edit forms and without initially visible editing capabilities
Navigation Panel The list of links on the left hand side (currently of the project details page)
Edit Mode The forms page when clicking edit in the navigation panel of the project details page