5.2. Architectural overview

This section describes the archicture of Package Drone.

Package Drone consists of a few core concepts. This section will explain these concepts.

The main entity (beside an artifact) is a channel. A channel simply is a container for artifacts. A channel is identified by a unique ID which can never change. Additionally a channel may have an alias name, which is also unique, but may change over time. The ID is generated by the system itself while the alias can be defined by the user.

Each channel has its own set of metadata. A channel can have provided metadata and extracted metadata (also see Section 5.2.1.5, “Metadata”). The extracted metadata is the metadata produced during the aggregation run of a channel. Each channel aggregator can add metadata during this process which will then be stored on channel level.

The functionality of channels is defined by channel aspects. A channel without aspects simple stores BLOBs, but does no further processing on these BLOBs.

A channel can also be locked. This puts the channel in read-only mode.

An artifact is simply a BLOB stored in a channel. Artifacts can be created and deleted, but never modified. This means that the name and data section of an artifact can never change. The same ID gives the same data. Until it is deleted.

An artifact has a unique ID. The ID is not only unique inside the channel but on unique to the whole system. It is generated by Package Drone when the artifact is stored. The artifact also has a name. The name is not unique. So the same name can appear multiple times in a chanel.

Artifacts also have provided and extracted metadata (also see Section 5.2.1.5, “Metadata”). The extracted meta data is created by meta data extractors.

There are different types of artifacts. The default, stored artifacts which where uploaded either manually or by a deployment process (like mvn deploy). Each stored artifact can be parent to child artifacts, which also get greated manually or using a deployment process.

Then there are virtual artifacts. These get created by Virtualizers and are like children artifacts. However, these cannot be deleted manually.

Another artifact type are the generator and generated artifacts (see Section 5.2.1.4, “Generators”). These are like virtual artifacts, with the difference that a specific generator implementation will be used to create the generated child artifacts.

Package Drone is built on Java 8 and OSGi. As OSGi container Eclipse Equinox is used.

The embedded web server is provided by Jetty directly. At the moment Package Drone does not use the OSGi HTTP Service mechanism, but a direct Jetty instance in order to solve some issues with JSP.

For the Web UI Bootstrap 3.x is used.

The database based persistence if provided by EclipseLink which is embedded into OSGi using Eclipse Gemini JPA and Eclipse Gemini DBaccess. DBaccess implements the OSGi specification for JDBC drivers, so that these can be used as OSGi service. Gemini JPA bootstraps EclipseLink, detects and activates bundles which are JPA units, and registers an EntityManagerFactory for each of them as OSGi service.

As already mentioned, Package Drone uses Jetty as web server. However it does currently not use the OSGi HTTP Service variant. For more information see also:

There are two entry points which are currently used. The adapter servlet use the method described here. and directly provide a /WEB-INF/web.xml which defines a servlet.

The second entry point is used by all web UI elements. A central Jetty Context is registered which hosts the DispatcherServlet, which in fact dispatches request to registered web controllers.

The web dispatching functionality is greatly inspired by the Spring WebMVC framework [4]. However it is not directly compatible with it, although some class names might look like.

The dispatcher servlet picks up all web controllers, filters and interceptors and integrates these into the main servlet context. It works like a bridge between OSGi services and the JEE parts of Jetty.

Web Controller

A web controller is a service, registered with OSGi, which provides Java methods which in fact handle incoming web requests. Each method is bound to a URL and request method (GET, POST, …). The method call can have parameters, which are bound to values coming from the URL, the HTTP request or internal processing.

Filter

These are JEE like Filters, which get registered with OSGi, picked up by the main web context and registered with the dispatching. Filters will be bound to all servlets in the main context.

Interceptors

These intercept calls to the web controllers only. But they will have access to the values which go in and out of these controllers.


As seen in Figure 5.1, “Web dispatching” the Jetty core service takes the Servlet from Bundle A, defined by the Context path in the MANIFEST.MF and the servlet definition in the WEB-INF/web.xml. And it also takes the Context service instance registered on the OSGi service bus. In this case Bundle B directly wired the Dispatcher Servlet to the context and provides some additional mechanisms order to look up JSP resources in OSGi.

The Dispatcher servlet however again waits for services registered with OSGi, which have the @Controller annotation assigned, or are Filters or Interceptors. The default dispatcher servlet is registered a the context root path. And, in this case, will forward requests for /c1 to the controller service in Bundle C.

Since also an interceptor in Bundle D is registered, the request to /c1 will go through this interceptor. Where the requests to Servlet A will not go through this interceptor.



[4] In fact the WebMVC was used in the beginnging. However, Spring and OSGi don't go well together. And although this might sound strange, but Spring is not modular enough for OSGi. Spring is modular, but not dynamic. So one Spring is fired up, it can hardly be re-configured and does not support services coming and going like OSGi does.