Author: jawi
Date: Mon Nov 24 22:42:00 2014
New Revision: 1641501

URL: http://svn.apache.org/r1641501
Log:
Restructured the ACE documentation:

- unified the user/dev docs into a single directory,
  as there is no clear distinction between users and
  developers;
- added a getting started in 5 minutes guide to get
  users up and running;
- updated the users guide to add some more details.


Added:
    ace/site/trunk/content/docs/
    ace/site/trunk/content/docs.mdtext   (with props)
    ace/site/trunk/content/docs/ace-authentication.mdtext   (with props)
    ace/site/trunk/content/docs/ace-deployment-strategies.mdtext   (with props)
    ace/site/trunk/content/docs/ace-roles.mdtext   (with props)
    ace/site/trunk/content/docs/ace_dnd_artifacts.png   (with props)
    ace/site/trunk/content/docs/ace_dnd_artifacts_fail.png   (with props)
    ace/site/trunk/content/docs/ace_dnd_artifacts_ok.png   (with props)
    ace/site/trunk/content/docs/ace_dynamic_association.png   (with props)
    ace/site/trunk/content/docs/ace_server_topology.png   (with props)
    ace/site/trunk/content/docs/ace_server_ui.png   (with props)
    ace/site/trunk/content/docs/ace_static_association.png   (with props)
    ace/site/trunk/content/docs/ace_target_tag_editor.png   (with props)
    ace/site/trunk/content/docs/ace_user_management_admin_ui.png   (with props)
    ace/site/trunk/content/docs/ace_user_management_newuser_ui.png   (with 
props)
    ace/site/trunk/content/docs/ace_user_management_user_ui.png   (with props)
    ace/site/trunk/content/docs/adding-custom-artifact-types.mdtext   (with 
props)
    ace/site/trunk/content/docs/analysis/
    ace/site/trunk/content/docs/analysis/auditlog-analysis.mdtext   (with props)
    ace/site/trunk/content/docs/analysis/bundlerepository-analysis.mdtext   
(with props)
    ace/site/trunk/content/docs/analysis/index.mdtext   (with props)
    ace/site/trunk/content/docs/analysis/security-analysis-flow.svg   (with 
props)
    ace/site/trunk/content/docs/analysis/security-analysis.mdtext
    ace/site/trunk/content/docs/analysis/src/
    ace/site/trunk/content/docs/analysis/src/security-analysis-flow.graffle   
(with props)
    ace/site/trunk/content/docs/analysis/template-mechanism.mdtext
    ace/site/trunk/content/docs/architecture.mdtext   (with props)
    ace/site/trunk/content/docs/auth_api.svg   (with props)
    ace/site/trunk/content/docs/auth_connectionfactory.svg   (with props)
    ace/site/trunk/content/docs/auth_main_components.svg   (with props)
    ace/site/trunk/content/docs/coding-standards.mdtext   (with props)
    ace/site/trunk/content/docs/configuring-relay-servers.mdtext   (with props)
    ace/site/trunk/content/docs/deployment_strategy_classdiagram.svg   (with 
props)
    ace/site/trunk/content/docs/deployment_strategy_update_seq.svg   (with 
props)
    ace/site/trunk/content/docs/design/
    ace/site/trunk/content/docs/design/auditlog-protocol.mdtext
    ace/site/trunk/content/docs/design/index.mdtext
    ace/site/trunk/content/docs/design/remote-interfaces-components.svg   (with 
props)
    ace/site/trunk/content/docs/design/remote-interfaces.mdtext
    ace/site/trunk/content/docs/design/src/
    ace/site/trunk/content/docs/design/src/remote-interfaces-components.graffle 
  (with props)
    ace/site/trunk/content/docs/design/src/remoteinterfaces-components.graffle  
 (with props)
    ace/site/trunk/content/docs/getting-started-5-mins.mdtext   (with props)
    ace/site/trunk/content/docs/history-and-background.mdtext   (with props)
    ace/site/trunk/content/docs/relay_functional_overview.png   (with props)
    ace/site/trunk/content/docs/release-guide.mdtext   (with props)
    ace/site/trunk/content/docs/rest-api.mdtext   (with props)
    ace/site/trunk/content/docs/setup-dev-environment.mdtext   (with props)
    ace/site/trunk/content/docs/shell-api.mdtext   (with props)
    ace/site/trunk/content/docs/simple-workflow.png   (with props)
    ace/site/trunk/content/docs/test-script.mdtext   (with props)
    ace/site/trunk/content/docs/use-cases/
    ace/site/trunk/content/docs/use-cases/index.mdtext
    ace/site/trunk/content/docs/use-cases/uc-01.mdtext
    ace/site/trunk/content/docs/use-cases/uc-02.mdtext
    ace/site/trunk/content/docs/use-cases/uc-03.mdtext
    ace/site/trunk/content/docs/use-cases/uc-04.mdtext
    ace/site/trunk/content/docs/use-cases/uc-05.mdtext
    ace/site/trunk/content/docs/use-cases/uc-06.mdtext
    ace/site/trunk/content/docs/use-cases/uc-07.mdtext
    ace/site/trunk/content/docs/use-cases/uc-08.mdtext
    ace/site/trunk/content/docs/use-cases/uc-09.mdtext
    ace/site/trunk/content/docs/use-cases/uc-10.mdtext
    ace/site/trunk/content/docs/use-cases/uc-11.mdtext
    ace/site/trunk/content/docs/use-cases/uc-12.mdtext
    ace/site/trunk/content/docs/use-cases/uc-13.mdtext
    ace/site/trunk/content/docs/use-cases/uc-14.mdtext
    ace/site/trunk/content/docs/use-cases/uc-15.mdtext
    ace/site/trunk/content/docs/use-cases/uc-16.mdtext
    ace/site/trunk/content/docs/use-cases/uc-17.mdtext
    ace/site/trunk/content/docs/use-cases/uc-18.mdtext
    ace/site/trunk/content/docs/use-cases/uc-19.mdtext
    ace/site/trunk/content/docs/use-cases/uc-20.mdtext
    ace/site/trunk/content/docs/use-cases/uc-21.mdtext
    ace/site/trunk/content/docs/use-cases/uc-22.mdtext
    ace/site/trunk/content/docs/use-cases/uc-23.mdtext
    ace/site/trunk/content/docs/use-cases/usecasesview.svg   (with props)
    ace/site/trunk/content/docs/user-guide.mdtext   (with props)
    ace/site/trunk/content/docs/user-management-guide.mdtext   (with props)
    ace/site/trunk/content/docs/using-client-certificates.mdtext   (with props)
    ace/site/trunk/content/docs/writing-tests.mdtext   (with props)
Removed:
    ace/site/trunk/content/dev-doc/
    ace/site/trunk/content/user-doc/

Added: ace/site/trunk/content/docs.mdtext
URL: 
http://svn.apache.org/viewvc/ace/site/trunk/content/docs.mdtext?rev=1641501&view=auto
==============================================================================
--- ace/site/trunk/content/docs.mdtext (added)
+++ ace/site/trunk/content/docs.mdtext Mon Nov 24 22:42:00 2014
@@ -0,0 +1,61 @@
+Title: Documentation
+
+Apache ACE is a software distribution framework that allows you to manage and 
deploy
+modular OSGi-based applications to many different clients, also known as 
"targets" in ACE
+terminology, allowing precise control over which target gets which software. 
Its key
+features are:
+
+* being able to deploy software to many different targets;
+* atomic upgrades: if an upgrade fails for a target, it is automatically 
rolled back to the former state;
+* deploy different configurations for different targets;
+* smart redeployments of only the changed artifacts to your targets;
+* complete control on the deployment strategy for your targets.
+
+
+## Getting started
+
+If you are interested in just get Apache ACE up and running, you can read the 
[getting
+started in 5 minutes](/docs/getting-started-5-mins.html). To get more 
information about
+the history of Apache ACE, read all about its [history and
+background](/docs/history-and-background.html).
+
+
+## Using Apache ACE
+
+Resources that go into more detail on using Apache ACE:
+
+* read all about using Apache ACE in the [users guide](/docs/user-guide.html);
+* to manage users using ACE's web UI, read the [user management 
guide](/docs/user-management-guide.html);
+* [information about the various roles used in Apache 
ACE](/docs/ace-roles.html);
+* accessing Apache ACE [using the Gogo shell](/docs/shell-api.html);
+* accessing Apache ACE from [its REST API](/docs/rest-api.html);
+* to handle a large number of targets, you can make use of [intermediate relay 
servers](/docs/configuring-relay-servers.html);
+* configuring ACE authentication is described in the [authentication 
guide](/docs/ace-authentication.html);
+* configuring ACE to use two-way SSL is described in [using client 
certificates](/docs/using-client-certificates.html);
+* various deployment strategies for Apache ACE are described in the [ACE 
deployment strategies document](/docs/ace-deployment-strategies.html);
+
+
+## Developing for Apache ACE
+
+There are several resources available on extending and developing for Apache 
ACE, such as:
+
+* [setting up an development environment for developing for Apache 
ACE](/docs/setup-dev-environment.html);
+* more details on writing unit and/or integration tests can be found in [this 
document](/docs/writing-tests.html);
+* all about the coding style and guidelines can be found in the [coding 
standards](/docs/coding-standards.html);
+* guidelines for releasing Apache ACE can be found in [the release 
guide](/docs/release-guide.html);
+* more information about the architectural principals can be found in [the 
architectural guide](/docs/architecture.html);
+* if you are interested in performing load tests, or want to get started with 
automating ACE deployments, read all about it in our [test script 
document](/docs/test-script.html);
+* various use cases are described on the [use cases page](/docs/use-cases);
+
+* [adding support for new types of 
artifacts](/docs/adding-custom-artifact-types.html);
+
+* detailed analysis documentation giving background information on some 
development principles currently used:
+** [audit log analysis](/docs/analysis/auditlog-analysis.html);
+** [bundle repository analysis](/docs/analysis/bundlerepository-analysis.html);
+** [security analysis](/docs/analysis/security-analysis.html);
+** [template mechanism](/docs/analysis/template-mechanism.html).
+
+* detailed design documentation:
+** [remote interface design](/docs/design/remote-interfaces.html);
+** [audit log details](/docs/design/auditlog-protocol.html);
+

Propchange: ace/site/trunk/content/docs.mdtext
------------------------------------------------------------------------------
    svn:eol-style = native

Added: ace/site/trunk/content/docs/ace-authentication.mdtext
URL: 
http://svn.apache.org/viewvc/ace/site/trunk/content/docs/ace-authentication.mdtext?rev=1641501&view=auto
==============================================================================
--- ace/site/trunk/content/docs/ace-authentication.mdtext (added)
+++ ace/site/trunk/content/docs/ace-authentication.mdtext Mon Nov 24 22:42:00 
2014
@@ -0,0 +1,248 @@
+Title: ACE Authentication
+
+_Enabling authentication in ACE_
+
+Revision 1.0, last updated: April 26th, 2012.
+
+[TOC]
+
+## Introduction
+
+When provisioning software (partly) to targets, one has to rely upon the 
trustworthiness of both the network and the target. Even if everything is under 
your control and governance, one cannot entirely be sure that unwanted access 
takes place. A first step in order to prevent unwanted access is 
*authentication*, which gives you the ability to verify the identity of 
someone. Once the identity is known, one can apply *authorization* in order to 
determine what actions are allowed and which are not.
+In this article, the recently added authentication layer of ACE is explained 
in more depth and how to configure authentication to your situation.  
+The remainder of this article assumes the reader has basic knowledge of the 
principles behind ACE, and has sufficient programming skills. For this 
article, the latest code of ACE (0.8.1-SNAPSHOT, rev.1329269) was used.
+
+
+## Communication paths
+
+Before going in more detail on the design and configuration of the 
authentication layer in ACE, we first need to pinpoint all places were 
authentication needs to be applied. The following figure shows the main 
components in ACE and their communication paths, providing a global overview of 
where authentication is applicable to ACE.
+
+![Figure 1: Overview of components and communication paths in 
ACE](auth_main_components.svg "Figure 1: Overview of components and 
communication paths")  
+**Figure 1**: Overview of components and communication paths.
+
+In the above figure, several of the communication paths (denoted by the 
circled digits) that can be identified in ACE are represented:
+
+1. the client communicates to the ACE server by means of both direct calls to 
its services as well as remote (HTTP[^1]) calls;
+2. a management agent (representing the target) communicates to the ACE server 
through remote calls;
+3. the REST API exposes the entire client and server APIs in a RESTful way. 
Communication to the client occurs by both direct and remote calls;
+4. the Vaadin Web UI exposes the entire client API as web application. Similar 
as the REST API, it communicates both directly as remotely with the client.
+
+As can be seen from the above figure, most of the communication paths are 
remoted. The reason for this is twofold:
+
+1. It allows reuse of components; for example access to the OBR-servlet is 
used by the both the client-API as well the web UI to upload new artifacts;
+2. it enables scalability by allowing components to be deployed on different 
machines; for example, one does not need to run the client on the same machine 
as the server. This could be useful for working on high-latency networks.
+
+All direct (i.e., non remoted) communication paths do not need to be 
authenticated, as they require that both caller and callee run in the same 
virtual machine, making it impossible to be used outside the virtual 
machine[^2]. Hence, we only need to add an authentication layer to the remote 
endpoints. However, adding authentication to all remote endpoints poses us with 
the challenge to let the "internal" communication paths that use remote calls 
to authenticate themselves as well. Not doing so would prevent ACE from 
functioning correctly. A disadvantage of this approach is that it is an 
all-or-nothing approach, either all users of the remote endpoints use 
authentication, or none of them. However, the way users authenticate themselves 
can be different, meaning that one set of users can use basic authentication to 
identify themselves, while another set uses client certificates to identify 
themselves.
+
+
+## Authentication design
+
+The high-level design for security in ACE is explained in the [remote 
interface design](/docs/design/remote-interfaces.html). From this design, we 
can derive several requirements for the design of ACE's authentication layer:
+
+1. should be applicable and configurable for all remoted endpoints. If a new 
endpoint is added to ACE, it should be easy to add and configure authentication 
for it;
+2. should be optional. If no authentication is desired, one should be able to 
remove its services from the ACE distribution;
+3. should be pluggable. Various ways of authentication exist, and new ones can 
emerge. Making the authentication mechanism pluggable allows new ways of 
authentication to be used easily.
+
+Based on these requirements, the design of the authentication layer is 
represented in the following figure: {#fig2}
+
+![Figure 2: Authentication layer class diagram](auth_api.svg "Figure 2: 
Authentication layer class diagram")  
+**Figure 2**: Authentication layer class diagram.
+
+The <tt>AuthenticationService</tt> is responsible for authenticating a user 
based on some piece of information. This piece of information can be an array 
containing a username/password combination, a <tt>HttpServletRequest</tt> 
containing authentication request headers, or any other type of information 
capable of uniquely identifying a user. The actual authentication itself is 
delegated to one or more <tt>AuthenticationProcessor</tt>s, which know how to 
handle  a given set of information (e.g., <tt>HttpServletRequest</tt>) and can 
map this information to a particular user. In more detail, the calling sequence 
of <tt>AuthenticationService#authenticate</tt> would be:
+
+1. <tt>AuthenticationService#authenticate</tt> is called with a blob of data, 
for example a <tt>HttpServletRequest</tt>;
+2. for each known <tt>AuthenticationProcessor</tt>:
+    - <tt>AuthenticationProcessor#canHandle</tt> is called with that blob of 
data. In this method, an authentication processor can decide whether the given 
blob is something it can handle or not;
+    - if it can be handled, the <tt>AuthenticationProcessor#authenticate</tt> 
is called with that blob of data, along with an instance of the 
<tt>UserAdmin</tt> service. The authentication processor is now responsible for 
converting the blob of data to an authenticated user, if possible.
+3. if a <tt>User</tt> object is returned from the authentication service[^3], 
the authentication phase will be regarded as successful. If *no* <tt>User</tt> 
object is returned, the authentication phase will be regarded unsuccessful.
+
+This is only half the story for authentication. As stated before, ACE 
internally also communicates through remote endpoints to access certain 
services. Without any changes, all those remote calls will fail due to missing 
credentials. If we would leave those means of communications as-is, we need to 
track down all places where remote calls are being made and inject the proper 
credentials at each of those places. However, doing this is not only *very* 
invasive and error prone but also not very developer friendly from a 
service-oriented perspective. Alternatively, we could try to include the 
credentials in the URL itself, making it self-contained. Not only would this 
approach limit our ability to use any kind of authentication mechanism (it only 
works for username/password combos), it also required us to supply the 
credentials manually each and every time we want to create a remote connection. 
Instead, we would like to refrain from passing around credentials, and leverage 
the service o
 riented aspects of OSGi to create remote connections for us. This service 
could then be responsible for adding the right credentials for us, leaving the 
calling party totally unaware about the fact authentication might be used (or 
not). Such a service is denoted in the following figure:
+
+![Figure 3: Connection Factory class diagram](auth_connectionfactory.svg 
"Figure 3: Connection Factory class diagram")  
+**Figure 3**: Connection Factory class diagram.
+
+The <tt>ConnectionFactory</tt> is responsible for creating 
<tt>URLConnection</tt>s, given a "plain" URL. So, instead of calling 
<tt>URL#openConnection()</tt> or <tt>URL#openStream()</tt>, we'll now have to 
call <tt>ConnectionFactory#createConnection(url)</tt> instead. But what 
advantage does this give us? In order to allow the connection factory to supply 
the credentials to <tt>URLConnection</tt>s, it is also registered as 
<tt>ManagedServiceFactory</tt> that enables us to provide multiple 
configurations of which credentials should be supplied to what (sets of) URLs. 
The introduction of the connection factory thus allows us to abstract the 
creation of a connection and passing of credentials to it from the URL. 
Internally, the connection factory will match each URL given in 
<tt>createConnection</tt> with the URLs it is configured with. If a matching 
URL is found, it will use the credentials in that configuration to supply to 
the <tt>URLConnection</tt>.
+
+
+### Remote services
+
+We've now closed the circle: we not only have defined how remote endpoints can 
apply authentication, but also how all calling parties can remain using these 
remote endpoints without having to be aware of authentication. The only thing 
left, is a summary of which remote endpoints currently exist in ACE.  
+All remote services are configurable with respect to the endpoint they can be 
accessed. The following table shows an overview of the remote services, 
including the default endpoint they use:
+
+Name | Description | Endpoint | Configuration PID[^4]
+------- | --------------- | ------------ | --------------------- 
+<tt>BundleServlet</tt> | provides access to the OBR (bundle repository) of ACE 
| <tt>/obr</tt> | <tt>o.a.a.obr.servlet</tt>
+<tt>DeploymentServlet</tt> | handles the actual provisioning of deployment 
packages to a target | <tt>/deployment</tt> |<tt>o.a.a.deployment.servlet</tt>
+<tt>LogServlet</tt> | allows any number of logs for a target to be 
synchronized and accessed | <tt>/auditlog</tt>[^5] | 
<tt>o.a.a.server.log.servlet.factory</tt><br/>**note: this is a configuration 
factory!**
+<tt>RepositoryServlet</tt> | provides access to the various 
(artifact/feature/distribution/target) internal repositories of ACE | 
<tt>/repository</tt> | <tt>o.a.a.repository.servlet.<br/>RepositoryServlet</tt>
+<tt>RepositoryReplicationServlet</tt> | allows *relay nodes* to replicate the 
internal repositories of ACE | <tt>/replication</tt> | 
<tt>o.a.a.repository.servlet.<br/>RepositoryReplicationServlet</tt>
+<tt>RESTClientServlet</tt> | provides the RESTful interface to ACE 
|<tt>/client</tt> | <tt>o.a.a.client.rest</tt>
+<tt>VaadinServlet</tt> | provides the Vaadin web interface | <tt>/ace</tt> | 
<tt>o.a.a.webui.vaadin</tt>
+&#160; | &#160; | &#160; | &#160;
+
+## Configuring authentication
+
+Now we have discussed the design of the authentication layer in ACE in rather 
detail, lets continue with how we can configure the authentication. Note that 
in order to make use of this functionality, you need to use the latest TRUNK of 
ACE, as explained in the introduction.
+
+### Configuring authentication for remote services
+
+In the section on the design of the authentication layer, we've mentioned that 
if a remote service wants to make use of authentication, it can make use of the 
<tt>AuthenticationService</tt>. However, one of the design requirements was 
that authentication should be optional as well. In order to enable or disable 
authentication, each remote service needs to do the following:
+
+1. add a **mandatory** configuration property <tt>authentication.enabled = 
false|true</tt> to their configuration. Although any kind of name for this 
configuration property can be used, it is *strongly* advised to stick to the 
same name for all services;
+2. when the configuration of a remote service is updated, it should add a 
service dependency to the <tt>AuthenticationService</tt>. By making this 
service **required** if authentication is *enabled*, and **optional** when 
authentication is *disabled*, we can adhere to the requirement of optionality 
for authentication;
+3. in case authentication is *enabled*, each request the service obtains needs 
to be passed to the <tt>AuthenticationService</tt> first, and depending on its 
outcome, the request can continue or not.
+
+To make this more concrete, we walk through an example of how the 
<tt>BundleServlet</tt> is to be configured. As this is a servlet (as almost all 
other remote endpoints in ACE), we can intercept all service requests by 
overriding the <tt>Servlet#service()</tt> method and perform our authentication 
check there. If this check is successful, we continue passing the service 
request, and return a "401 - Unauthorized" when the check is unsuccessful. 
+
+#### Configuring the authentication
+
+The service configuration, denoted by the 
<tt>org.apache.ace.obr.servlet.cfg</tt> in the stock ACE distribution, looks 
like:
+
+    :::properties
+    # Endpoint for this servlet
+    org.apache.ace.server.servlet.endpoint = /obr
+    # Whether or not authentication is to be used
+    authentication.enabled = true
+
+Note that we've added the <tt>authentication.enabled</tt> property that allows 
us to enable or disable the authentication check for this servlet.
+
+#### Making use of the service configuration
+
+To let the servlet pick up our configuration, it should be registered as 
<tt>ManagedService(Factory)</tt>. To make use of the configuration, we need to 
add the following code to our <tt>BundleServlet</tt>:
+
+    :::java
+    private volatile boolean m_useAuth;
+    private volatile AuthenticationService m_authService;
+    
+    // ...
+    
+    public void updated(Dictionary settings) throws ConfigurationException {
+        if (settings != null) {
+            String useAuthString = (String) 
settings.get("authentication.enabled");
+            if (useAuthString == null || 
!("true".equalsIgnoreCase(useAuthString) || 
"false".equalsIgnoreCase(useAuthString))) {
+                throw new ConfigurationException("authentication.enabled", 
"Missing or invalid value!");
+            }
+            
+            m_useAuth = Boolean.parseBoolean(useAuthString);
+        }
+        else {
+            m_useAuth = false;
+        }
+    }
+    
+    // ...
+    
+    /**
+     * Called by Dependency Manager upon initialization of this component.
+     */
+    protected void init(Component comp) {
+        comp.add(m_dm.createServiceDependency()
+            .setService(AuthenticationService.class)
+            .setRequired(m_useAuth)
+            .setInstanceBound(true)
+        );
+    }
+
+As almost all of the services in ACE are managed by the Dependency Manager, we 
can leverage its dynamics to inject our <tt>BundleServlet</tt> with an instance 
of the <tt>AuthenticationService</tt> and provide us with a configuration[^6]. 
In the <tt>updated()</tt> method, we perform a check whether the prior 
mentioned <tt>authentication.enabled</tt> property is present in the given 
configuration, and if so, whether it represents a valid boolean value. The 
actual boolean value itself will be held in a field (<tt>m_useAuth</tt>) for 
later use.
+
+#### Implementing the authentication check
+
+The actual authentication implementation itself is rather trivial: we simply 
intercept all incoming requests in our servlet and verify whether it resolves 
to a valid user:
+
+    :::java
+    @Override
+    protected void service(HttpServletRequest req, HttpServletResponse resp) 
throws ServletException, IOException {
+        if (!authenticate(req)) {
+            // Authentication failed; don't proceed with the original 
request...
+            resp.sendError(SC_UNAUTHORIZED);
+        } else {
+            // Authentication successful, proceed with original request...
+            super.service(req, resp);
+        }
+    }
+    
+    private boolean authenticate(HttpServletRequest request) {
+        if (m_useAuth) {
+            User user = m_authService.authenticate(request);
+            if (user == null) {
+                m_log.log(LogService.LOG_INFO, "Authentication failure!");
+            }
+            return (user != null);
+        }
+        return true;
+    }
+
+Note that this implementation does not tell *how* the authentication should 
occur, only that it should occur. How the authentication is performed, is 
determined internally by the <tt>AuthenticationService</tt>, with the help of 
the registered <tt>AuthenticationProcessor</tt>s.  
+Also note that the <tt>authenticate</tt> method itself uses the previously 
defined field (<tt>m_useAuth</tt>) to determine whether or not the 
authentication check should be performed. If it is *not* performed, we consider 
the request to be always authenticated, in order to obtain the same semantics 
as we would have without this check.
+
+### Configuring the connection factory
+
+Now that the remote service itself is no longer accepting unauthenticated 
requests, we need to supply the credentials to access this service to the 
<tt>ConnectionFactory</tt> service. This service can be configured using the 
PID <tt>org.apache.ace.connectionfactory</tt>. Note that it is a configuration 
factory, accepting multiple configurations!  
+For accessing our <tt>BundleServlet</tt>, we need to supply it the following 
configuration:
+
+    :::properties
+    # What kind of authentication should we supply
+    authentication.type = basic
+    # The actual credentials for basic authentication
+    authentication.user.name = d
+    authentication.user.password = f
+    # What is the base URL that these credentials apply to:
+    authentication.baseURL = http://localhost:8080/obr/
+
+When this configuration is supplied to the <tt>ConnectionFactory</tt>, it will 
provide a basic HTTP authentication header to each connection created for any 
URL starting with "<tt>http://localhost:8080/obr/</tt>"[^7].  
+To disable authentication for a particular URL, the 
<tt>authentication.type</tt> option can be set to <tt>none</tt>. 
+
+### Configuring the management agent
+
+The management agent itself also needs to use authentication to communicate 
with the remote services of the ACE server. It reuses the 
<tt>ConnectionFactory</tt> service for this, so it needs to obtain the same set 
of configurations as described in the previous section. The only thing we need 
to do is tell the management agent were it can find those configuration file(s):
+
+    :::sh
+    [localhost:~/]$ java -jar org.apache.ace.launcher-0.8.1-SNAPSHOT.jar \
+     discovery=http://localhost:8080/ \
+     identification=MyTarget \
+     auth=/path/to/connectionfactory/config/file(s)
+
+Alternatively, one could adapt the code of the management agent to use the 
<tt>ConfigAdmin</tt> service directly for creating the individual 
configurations using the service factory PID 
<tt>org.apache.ace.connectionfactory</tt>. 
+
+### Configuring users
+
+In order to successfully authenticate a user, it needs a corresponding 
<tt>User</tt> that can be obtained from the <tt>UserAdmin</tt> service. 
Initially, ACE imports a small set of users and roles defined in the 
"<tt>org.apache.ace.server.repository.factory/ace-user.cfg</tt>" configuration 
file. One could update this file in order to add users[^8], or add them, for 
example, to an LDAP-service and make the <tt>UserAdmin</tt> service retrieve 
users from this backend. The exact details on how to configure this are beyond 
this article.
+
+
+## Troubleshooting
+
+If after configuring the authentication of ACE things no longer work, it can 
be hard to find the exact cause of this. In this section, some pointers are 
given to help you to find the probably cause of the problem.
+
+I've enabled authentication, but I can still use all services without passing 
any credentials!
+: If you've updated the configuration files of a running server or management 
agent, the configuration files are not automatically picked up by default. You 
need to stop the server/management agent, clean its felix-cache folder and 
start it again.
+
+With authentication enabled, how can I test whether the endpoints accept my 
credentials?
+: In order to test the remote endpoints of ACE, you can use a tool like [REST 
client](http://code.google.com/p/rest-client/). It allows you to enter 
credentials for any given URL.
+
+After enabling authentication, I do not get any errors after starting the ACE 
server, but it doesn't function correctly!
+: Is the connection factory properly configured? Are *all* 
<tt>authentication.type</tt> options correctly set to <tt>basic</tt> and are 
the username/passwords correctly set? Are the configured base URLs not 
overlapping each other (e.g.: <tt>baseURL = http://localhost:8080/</tt> and 
<tt>baseURL = http://localhost:8080/obr</tt>)?
+
+After enabling authentication, the management agent(s) no longer functions/I 
do not see them added in the web UI.
+: Did you pass the <tt>auth=/path/to/config/file(s)</tt> option to the 
management agent to configure the connection factory? Are those files correctly 
stating the "<tt>authentication.type = basic</tt>", including the username and 
password for the desired URLs? Can you access the URLs mentioned in the 
configuration files with a tool like [REST 
client](http://code.google.com/p/rest-client/)?
+
+I do not want basic HTTP authentication, I want to use (fill in the kind of 
authentication)!
+: The current implementation is quite simple and basic, but it can be extended 
by means of custom authentication processors.
+
+
+## Notes
+
+[^1]: Other communication protocols could be used as well. However, currently, 
only HTTP is natively supported by ACE. For the remainder of this article, 
we'll assume HTTP as protocol.
+
+[^2]: Assuming that all components in the ACE server are trusted and obtained 
from trusted sources. If untrusted components would be allowed, we need to add 
authentication to these communication paths as well.
+
+[^3]: It is up to the implementation of <tt>AuthenticationService</tt> whether 
the *first* found user is returned, or whether it checks if all authentication 
processors yield the *same* user, or any other strategy that is desired.
+
+[^4]:  The common prefix of the shown configuration PIDs are abbreviated, so 
"<tt>o.a.a</tt>" stands for "<tt>org.apache.ace</tt>".
+
+[^5]: Amongst others, any number of log-endpoints can be defined, at least one 
is needed for the audit log to be synchronized between target and ACE server.
+
+[^6]: Note that we're using a configuration dependency for this service. This 
way, the configuration **must** be present before the service itself is 
registered, which allows us to determine if authentication should be used or 
not.
+
+[^7]: Currently, a simple <tt>String#startsWith()</tt> is used to determine 
whether or not a URL matches a configuration. This might change in the future 
when a more sophisticated URL-matching strategy is needed.
+
+[^8]: Make sure to clean the <tt>felix-cache</tt> directory before restarting 
the server, otherwise the new configuration files will not be picked up!

Propchange: ace/site/trunk/content/docs/ace-authentication.mdtext
------------------------------------------------------------------------------
    svn:eol-style = native

Added: ace/site/trunk/content/docs/ace-deployment-strategies.mdtext
URL: 
http://svn.apache.org/viewvc/ace/site/trunk/content/docs/ace-deployment-strategies.mdtext?rev=1641501&view=auto
==============================================================================
--- ace/site/trunk/content/docs/ace-deployment-strategies.mdtext (added)
+++ ace/site/trunk/content/docs/ace-deployment-strategies.mdtext Mon Nov 24 
22:42:00 2014
@@ -0,0 +1,218 @@
+Title: Deployment Strategies
+
+_Implementing custom update policies_
+
+last updated: April 19th, 2012
+
+## Introduction
+
+This article describes how ACE deploys new deployment packages to targets and 
how this strategy can be adapted to support more sophisticated scenario's.  
+The remainder of this article assumes the reader has basic knowledge of the 
principles behind ACE, and has sufficient programming skills. For this 
article, the latest code of ACE (0.8.1-SNAPSHOT, rev.1326140) was used.
+
+## Provisioning
+
+Apache ACE is all about provisioning software artifacts to targets. Software 
artifacts, or simply, artifacts, can be compiled code, configuration files, or 
any other artifact needed for a software system to operate. Provisioned 
artifacts are bundled in so-called "deployment packages", that is comprised of 
the differences between the target's current artifacts and the to-be-deployed 
artifacts. To distinguish between deployment packages, each one is given its 
own version. The increment of versions is done automatically by ACE when 
changes are committed to its repository.  
+When a new deployment package is available, it is not automatically sent to 
the target as the communication between target and management server (ACE) is 
unidirectional and initiated by the target. A target has to periodically check 
whether new deployment packages are available, and if so, do something with it.
+
+## Understanding ACE's deployment strategy
+
+Upon startup, the management agent, which represents a target, schedules 
several tasks that periodically synchronize the local state with that of the 
management server. Two of these tasks relate to the handling of deployment 
packages: `DeploymentCheckTask` and `DeploymentUpdateTask`. Figure 1 shows the 
relationship between the various components.
+
+![Figure 1: class diagram](deployment_strategy_classdiagram.svg "Figure 1: 
class diagram")  
+Figure 1: deployment strategy class diagram.
+
+The `DeploymentCheckTask` is responsible for periodically checking the 
management server for newer versions of deployment packages and if found emits 
an event. The `DeploymentUpdateTask` also periodically checks the management 
server, and if it finds a newer version, automatically downloads and installs 
it.
+
+![Figure 2: sequence diagram](deployment_strategy_update_seq.svg "Figure 2: 
sequence diagram")  
+Figure 2: deployment strategy sequence diagram.
+
+Figure 2 shows a more detailed sequence diagram of the deployment update 
strategy in ACE. The scheduler in the management agent calls the run()-method 
of the DeploymentUpdateTask once every _N_ seconds. This method in its turn 
makes several calls to the `DeploymentService`, which acts as a facade for 
other services in ACE. The `DeploymentService` is queried for the highest local 
and remote versions. If the remote version is newer than the local version, a 
deployment package containing the changes between the local and the remote 
version is installed. Note that this installation is done in a best effort 
strategy: if it fails, all changes are rolled back to what they were. As a 
consequence, if the installation fails one time, it probably will fail the next 
time as well. 
+
+### Tweaking the deployment strategy
+
+By default, the management agent allows the interval in which the update task 
is run to be customized. To change this interval, the management agent should 
be started with the extra system property "`-Dsyncinterval=1500`". The value of 
this property is interpreted as the interval time in milliseconds. Note that 
this property also changes the interval of other tasks as well, so setting it 
to a lower interval could potentially raise lots of traffic to your management 
server.
+
+Another thing you can customize is whether or not the update task should run 
at all. This is done by starting the management agent with the system property 
"`-Dorg.apache.ace.deployment.task=disabled`". While this option is not really 
useful out-of-the-box (the target is not be able to obtain any version at all) 
it opens up a possibility for providing custom deployment strategies.
+
+## Implementing a custom deployment strategy
+
+To implement our own deployment strategy, we need to create a bundle that 
provides the management agent with our update task. We will start with an 
update task that simply prints something to the console each time it is run and 
expand it later on. As can be seen in figure 1, a task is anything that 
implements the `Runnable` interface, so our update task needs to do as well. 
Furthermore, we will use the DependencyManager component from Felix to provide 
us with the right dependent services, the most important one being the 
`DeploymentService`.  
+The (stub) code for our update task looks like:
+
+    #!java
+    package net.luminis.ace.updatetask;
+    
+    import org.apache.ace.deployment.service.DeploymentService;
+    import org.osgi.service.log.LogService;
+    
+    public class MyUpdateTask implements Runnable {
+        // injected by DependencyManager
+        private DeploymentService m_service; 
+        private LogService m_logService;
+        
+        public void run() {
+            System.out.println("Hello from MyUpdateTask: " + new 
java.util.Date());
+        }
+    }
+
+The bundle activator that registers our update task as service:
+
+    #!java
+    package net.luminis.ace.updatetask;
+    
+    import java.util.Properties;
+    
+    import org.apache.ace.deployment.service.DeploymentService;
+    import org.apache.ace.scheduler.constants.SchedulerConstants;
+    import org.apache.felix.dm.DependencyActivatorBase;
+    import org.apache.felix.dm.DependencyManager;
+    import org.osgi.framework.BundleContext;
+    import org.osgi.service.log.LogService;
+    
+    public class Activator extends DependencyActivatorBase {
+      public void init(BundleContext context, DependencyManager manager) 
throws Exception {
+        Properties props = new Properties();
+        props.put(SchedulerConstants.SCHEDULER_NAME_KEY, 
MyUpdateTask.class.getName());
+        props.put(SchedulerConstants.SCHEDULER_DESCRIPTION_KEY, "My own 
deployment update service.");
+        props.put(SchedulerConstants.SCHEDULER_RECIPE, "5000");
+    
+        manager.add(createComponent()
+          .setInterface(Runnable.class.getName(), props)
+          .setImplementation(new MyUpdateTask())
+          .add(createServiceDependency()
+            .setService(DeploymentService.class)
+            .setRequired(true)
+          )
+          .add(createServiceDependency()
+            .setService(LogService.class)
+            .setRequired(false)
+          )
+        );
+      }
+    
+      public void destroy(BundleContext context, DependencyManager manager) 
throws Exception {
+        // Nothing
+      }
+    }
+
+The activator isn't that different from any other one, the only interesting 
part is the service properties that we register along with our update task. The 
three properties are used by the ACE's scheduler to determine that our service 
is actually a scheduled task. With the "recipe" key, the scheduler is told what 
interval (in milliseconds) is to be used to execute our task. In our case the 
recipe is set to 5000, causing our task to be run once every five seconds.  
+To complete the whole cycle, we need some build scripting. For this, we use 
[BndTools](http://bndtools.org):
+
+    :::text
+    Bundle-Name: My Update Task
+    Bundle-Version: 0.0.1
+    Bundle-SymbolicName: net.luminis.ace.updatetask
+    Bundle-Activator: net.luminis.ace.updatetask.Activator
+    Private-Package: net.luminis.ace.updatetask
+    Import-Package: *
+    -buildpath: org.apache.ace.deployment.task.base;version=0.8,\
+         org.apache.ace.scheduler.api;version=0.8,\
+         org.apache.felix.dependencymanager;version=3.0,\
+         osgi.core;version=4.2.0,\
+         osgi.cmpn;version=4.2.0
+
+To let the management agent to find and use our custom update task bundle, we 
need to add the JAR-file to its class path, and start the management agent with 
the following options:
+
+    :::sh
+    [localhost:~/]$ java -Dorg.apache.ace.deployment.task=disabled \
+     -cp 
org.apache.ace.launcher-0.8.1-SNAPSHOT.jar:net.luminis.ace.updatetask-1.0.0.jar 
\
+     org.apache.ace.launcher.Main \
+     bundle=net.luminis.ace.updatetask.Activator \
+     identification=myTarget \
+     discovery=http://localhost:8080
+
+Note that besides adding our bundle to the class path, we also have added the 
`bundle` argument to tell the management agent to include our bundle activator 
in its startup.  
+If everything went well, one of the first few lines printed out on the console 
should be something like:
+
+    Adding additional bundle activator: net.luminis.ace.updatetask.Activator
+    Not starting activator org.apache.ace.deployment.task.
+    ...
+
+After startup, our update task should print a message stating its existence to 
the console every five seconds.
+
+With the boiler plating in place, its time to make our update task a little 
more interesting. We change the code of our update task to the following (for 
brevity, only the run() method is shown):
+
+    #!java
+    public void run() {
+        try {
+            Version local = m_service.getHighestLocalVersion();
+            Version remote = m_service.getHighestRemoteVersion();
+    
+            if ((remote != null) && ((local == null) || 
(remote.compareTo(local) > 0))) {
+                // Ask user whether this update should proceed...
+                System.out.println("Update available! Upgrade from " + local + 
" to " + remote + " [Y/N]?");
+    
+                BufferedReader reader = new BufferedReader(new 
InputStreamReader(System.in));
+                String result = reader.readLine();
+    
+                if ("y".equalsIgnoreCase(result)) {
+                    // Ask the deployer service to install this update...
+                    m_service.installVersion(remote, local);
+    
+                    m_logService.log(LogService.LOG_INFO, "Update installed!");
+                }
+            }
+        } catch (IOException e) {
+            m_logService.log(LogService.LOG_WARNING, "Update failed!", e);
+        } catch (Exception e) {
+            m_logService.log(LogService.LOG_WARNING, "Update failed!", e);
+    }
+
+This new implementation first asks the `DeploymentService` what the current 
local (= version current running on management agent) and remote (= version 
available in the management server) versions are. If the remote version is 
newer/higher than the local version, than we ask the user for permission to 
install the update. When given, the `DeploymentService` is requested to upgrade 
from the local version to the remote version.  
+If you would run this code, you'll notice that if the user doesn't respond 
within the task's interval, a new task is started, causing an ever increasing 
number of tasks to be waiting for user input in case an update is available. 
Currently, due to the current implementation of ACE's scheduler, there is no 
way of disabling this behavior (although it is not really difficult to resolve 
this problem locally in your task).
+
+## Taking it a step further…
+
+So far, we've reused the `DeploymentService` facade from ACE to tweak the 
update process of the management agent a bit. However, there still some magic 
going on in the installation of newer versions (all the logic behind 
`DeploymentService#installVersion`).  
+Let's explore this method a bit more into detail. The `installVersion` method 
roughly (some details are left out for brevity) has the following 
implementation:
+
+    #!java
+    // injected by Felix' dependency manager
+    volatile Deployment m_deployer;
+    volatile EventAdmin m_eventAdmin;
+    volatile Identification m_identification;
+    // denotes the host + port where ACE is listening, e.g. 
http://192.168.1.1:8080/
+    final String m_host;
+    
+    /**
+     * @see 
org.apache.ace.deployment.service.impl.DeploymentServiceImpl#installVersion
+    */
+    public void installVersion(Version highestRemoteVersion, Version 
highestLocalVersion) throws Exception {
+        InputStream inputStream = null;
+    
+        try {
+            String version = highestRemoteVersion.toString();
+            URL baseURL = new URL(m_host, "deployment/" + 
m_identification.getID() + "/versions/");
+            if (highestLocalVersion != null) {
+                version += "?current=" + highestLocalVersion.toString();
+            }
+            URL dataURL = new URL(baseURL, version);
+            inputStream = dataURL.openStream();
+    
+            // Post event for audit log
+            String topic = "org/apache/ace/deployment/INSTALL";
+            m_eventAdmin.postEvent(createEvent(topic, version, dataURL));
+    
+            m_deployer.install(inputStream);
+        }
+        finally {
+            if (inputStream != null) {
+                try {
+                    inputStream.close();
+                }
+                catch (Exception ex) {
+                    // Not much we can do.
+                }
+            }
+        }
+    }
+
+Basically, the method builds up an URL to access the deployment service of 
ACE. Through this URL, the deployment-service creates a deployment package 
containing the changed artifacts between the given local and remote version. 
The `InputStream` containing this deployment package is given to the 
`Deployment` service (a facade to the standard DeploymentAdmin service) to be 
installed. Note that if the installation of the deployment package fails, an 
exception is thrown. As mentioned earlier, the installation of deployment 
packages is done in a "all or nothing" strategy, meaning that if it fails, all 
changes are reverted. For more details on this, you can read the 
DeploymentAdmin specification (see [2], chapter 114).  
+Aside the actual installation of the deployment package, an event is also 
posted to keep track of this installation. This event is picked up by the 
`AuditLog` service of ACE to track all changes made to the management agent 
(_one can argue whether this shouldn't be a responsibility of the Deployment 
facade_). 
+
+Now we have seen how the installation of deployment packages is implemented in 
ACE, we can even tweak that process a bit. For example, we could first download 
the deployment package entirely to a temporary location, and install it from 
there. Or, as we have access to the deployment package, we could also provide 
the user additional information about its contents, perhaps showing a change 
log or a summary of its contents, before installing it.
+
+## References
+
+1. [ACE subversion](http://svn.apache.org/repos/asf/ace/);
+2. [OSGi 4.2 compendium 
specification](http://www.osgi.org/Download/Release4V42).

Propchange: ace/site/trunk/content/docs/ace-deployment-strategies.mdtext
------------------------------------------------------------------------------
    svn:eol-style = native

Added: ace/site/trunk/content/docs/ace-roles.mdtext
URL: 
http://svn.apache.org/viewvc/ace/site/trunk/content/docs/ace-roles.mdtext?rev=1641501&view=auto
==============================================================================
--- ace/site/trunk/content/docs/ace-roles.mdtext (added)
+++ ace/site/trunk/content/docs/ace-roles.mdtext Mon Nov 24 22:42:00 2014
@@ -0,0 +1,43 @@
+Title: Roles
+
+These are the different roles in the system. Users of the system can be 
assigned one or more roles. The roles are also used in the different [use 
cases](use-cases/).
+
+## Release Manager
+
+The release manager manages the software configuration, linking artifacts to 
features and features to distributions.
+
+## Target Manager
+
+The target manager manages the total population of targets and assigns them to 
target operators.
+
+## Target Operator
+
+The target operator manages a (limited) set of targets designated to him by 
the target manager. He is responsible for accepting changes to the software 
configuration for those targets.
+
+## Remote Target Operator
+
+Like the target operator, the remote target operator manages a limited set of 
targets.
+
+## License Manager
+
+The license manager manages the relationship between the targets and the 
distributions.
+
+## Administrator
+
+The administrator manages the users, system settings, rights and security 
certificates for the whole ecosystem.
+
+## Target
+
+A target runs the management agent that is responsible for updating the target.
+
+## Server
+
+The server manages all the metadata that expresses what artifacts should be 
installed on what targets over time. It also contains an OBR for managing the 
actual artifacts.
+
+## Relay server
+
+The relay server acts as a cache for the server. It synchronizes with the 
server and might only contain a subset of the metadata to service a subset of 
the targets.
+
+## Software Developer
+
+The software developer provides artifacts that will be added to the OBR.

Propchange: ace/site/trunk/content/docs/ace-roles.mdtext
------------------------------------------------------------------------------
    svn:eol-style = native

Added: ace/site/trunk/content/docs/ace_dnd_artifacts.png
URL: 
http://svn.apache.org/viewvc/ace/site/trunk/content/docs/ace_dnd_artifacts.png?rev=1641501&view=auto
==============================================================================
Binary file - no diff available.

Propchange: ace/site/trunk/content/docs/ace_dnd_artifacts.png
------------------------------------------------------------------------------
    svn:mime-type = image/png

Added: ace/site/trunk/content/docs/ace_dnd_artifacts_fail.png
URL: 
http://svn.apache.org/viewvc/ace/site/trunk/content/docs/ace_dnd_artifacts_fail.png?rev=1641501&view=auto
==============================================================================
Binary file - no diff available.

Propchange: ace/site/trunk/content/docs/ace_dnd_artifacts_fail.png
------------------------------------------------------------------------------
    svn:mime-type = image/png

Added: ace/site/trunk/content/docs/ace_dnd_artifacts_ok.png
URL: 
http://svn.apache.org/viewvc/ace/site/trunk/content/docs/ace_dnd_artifacts_ok.png?rev=1641501&view=auto
==============================================================================
Binary file - no diff available.

Propchange: ace/site/trunk/content/docs/ace_dnd_artifacts_ok.png
------------------------------------------------------------------------------
    svn:mime-type = image/png

Added: ace/site/trunk/content/docs/ace_dynamic_association.png
URL: 
http://svn.apache.org/viewvc/ace/site/trunk/content/docs/ace_dynamic_association.png?rev=1641501&view=auto
==============================================================================
Binary file - no diff available.

Propchange: ace/site/trunk/content/docs/ace_dynamic_association.png
------------------------------------------------------------------------------
    svn:mime-type = image/png

Added: ace/site/trunk/content/docs/ace_server_topology.png
URL: 
http://svn.apache.org/viewvc/ace/site/trunk/content/docs/ace_server_topology.png?rev=1641501&view=auto
==============================================================================
Binary file - no diff available.

Propchange: ace/site/trunk/content/docs/ace_server_topology.png
------------------------------------------------------------------------------
    svn:mime-type = image/png

Added: ace/site/trunk/content/docs/ace_server_ui.png
URL: 
http://svn.apache.org/viewvc/ace/site/trunk/content/docs/ace_server_ui.png?rev=1641501&view=auto
==============================================================================
Binary file - no diff available.

Propchange: ace/site/trunk/content/docs/ace_server_ui.png
------------------------------------------------------------------------------
    svn:mime-type = image/png

Added: ace/site/trunk/content/docs/ace_static_association.png
URL: 
http://svn.apache.org/viewvc/ace/site/trunk/content/docs/ace_static_association.png?rev=1641501&view=auto
==============================================================================
Binary file - no diff available.

Propchange: ace/site/trunk/content/docs/ace_static_association.png
------------------------------------------------------------------------------
    svn:mime-type = image/png

Added: ace/site/trunk/content/docs/ace_target_tag_editor.png
URL: 
http://svn.apache.org/viewvc/ace/site/trunk/content/docs/ace_target_tag_editor.png?rev=1641501&view=auto
==============================================================================
Binary file - no diff available.

Propchange: ace/site/trunk/content/docs/ace_target_tag_editor.png
------------------------------------------------------------------------------
    svn:mime-type = image/png

Added: ace/site/trunk/content/docs/ace_user_management_admin_ui.png
URL: 
http://svn.apache.org/viewvc/ace/site/trunk/content/docs/ace_user_management_admin_ui.png?rev=1641501&view=auto
==============================================================================
Binary file - no diff available.

Propchange: ace/site/trunk/content/docs/ace_user_management_admin_ui.png
------------------------------------------------------------------------------
    svn:mime-type = image/png

Added: ace/site/trunk/content/docs/ace_user_management_newuser_ui.png
URL: 
http://svn.apache.org/viewvc/ace/site/trunk/content/docs/ace_user_management_newuser_ui.png?rev=1641501&view=auto
==============================================================================
Binary file - no diff available.

Propchange: ace/site/trunk/content/docs/ace_user_management_newuser_ui.png
------------------------------------------------------------------------------
    svn:mime-type = image/png

Added: ace/site/trunk/content/docs/ace_user_management_user_ui.png
URL: 
http://svn.apache.org/viewvc/ace/site/trunk/content/docs/ace_user_management_user_ui.png?rev=1641501&view=auto
==============================================================================
Binary file - no diff available.

Propchange: ace/site/trunk/content/docs/ace_user_management_user_ui.png
------------------------------------------------------------------------------
    svn:mime-type = image/png

Added: ace/site/trunk/content/docs/adding-custom-artifact-types.mdtext
URL: 
http://svn.apache.org/viewvc/ace/site/trunk/content/docs/adding-custom-artifact-types.mdtext?rev=1641501&view=auto
==============================================================================
--- ace/site/trunk/content/docs/adding-custom-artifact-types.mdtext (added)
+++ ace/site/trunk/content/docs/adding-custom-artifact-types.mdtext Mon Nov 24 
22:42:00 2014
@@ -0,0 +1,234 @@
+Title: Adding custom artifact types
+
+Out of the box, ACE comes with support for bundles and configuration files 
that follow the
+Auto Configuration specification. However, it is possible to extend ACE with 
support for
+new types of artifacts. Doing so requires you to do three things:
+
+1. Write a resource processor, according to the Deployment Admin specification.
+2. Write an ArtifactRecognizer service implementation.
+3. Write an ArtifactHelper service implementation.
+
+This document explains how to write each of these, and how to subsequently 
deploy them
+appropriately.
+
+## Writing a resource processor
+
+A resource processor implements the ResourceProcessor interface as defined in 
the
+Deployment Admin specification (OSGi Compendium 114.10). It describes in 
detail the
+contract that needs to be implemented and also contains an example. If you 
want to get
+started quickly, you can use the following code:
+
+       :::java
+       public class Processor implements ResourceProcessor {
+           private volatile DeploymentSession m_session;
+           private String m_deploymentPackageName;
+           private List<String> m_toInstall;
+           private List<String> m_toRemove;
+
+           /**
+            * Sets up the necessary environment for a deployment session.
+            */
+           private void startSession(DeploymentSession session) {
+               if (m_session != null) {
+                   throw new IllegalArgumentException("This resource processor 
is currently processing another deployment session, installing 
deploymentpackage" + m_session.getTargetDeploymentPackage().getName());
+               }
+               m_session = session;
+               m_toInstall = new ArrayList<String>();
+               m_toRemove = new ArrayList<String>();
+               String fromSource = 
session.getSourceDeploymentPackage().getName();
+               String fromTarget = 
session.getTargetDeploymentPackage().getName();
+               if (fromSource.equals("")) {
+                   m_deploymentPackageName = fromTarget;
+               }
+               else {
+                   m_deploymentPackageName = fromSource;
+               }
+           }
+
+           /**
+            * Ends a deployment session.
+            */
+           private void endSession() {
+               m_session = null;
+               m_deploymentPackageName = null;
+               m_toInstall = null;
+               m_toRemove = null;
+           }
+
+           private void ensureSession()  {
+               if (m_session == null) {
+                   throw new IllegalStateException("This resource processor is 
currently not part of a deployment session.");
+               }
+           }
+
+           public void begin(DeploymentSession session) {
+               startSession(session);
+           }
+
+           public void process(String name, InputStream stream) throws 
ResourceProcessorException {
+               ensureSession();
+               m_toInstall.add(name);
+           }
+
+           public void dropped(String resource) throws 
ResourceProcessorException {
+               ensureSession();
+               m_toRemove.add(resource);
+           }
+
+           public void dropAllResources() throws ResourceProcessorException {
+               ensureSession();
+               m_toRemove.addAll(Collections.EMPTY_LIST /* should be a list of 
all current resources */);
+           }
+
+           public void prepare() throws ResourceProcessorException {
+               ensureSession();
+           }
+
+           public void commit() {
+               ensureSession();
+               while (!m_toInstall.isEmpty()) {
+                       System.out.println("installing: " + 
m_toInstall.remove(0));
+               }
+               while (!m_toRemove.isEmpty()) {
+                       System.out.println("removing: " + m_toRemove.remove(0));
+               }
+               endSession();
+           }
+
+           public void rollback() {
+               // nothing special to do.
+               ensureSession();
+               endSession();
+           }
+
+           public void cancel() {
+               ensureSession();
+               // Nothing to do: we have no long-running operation, we only 
read the stream.
+           }
+       }
+
+This should be enough to get you started, but the code takes a few shortcuts 
so please do
+take some time to read the specification and implement each method correctly.
+
+The next step then is to publish this processor as an OSGi service. Don't 
forget to add
+the <tt>SERVICE_PID</tt> property and set its value, because that is how the 
processor is
+later recognized. Package everything up in an OSGi bundle and make sure to 
include these
+two headers in its manifest:
+
+       Deployment-ProvidesResourceProcessor: 
org.apache.ace.resourceprocessor.custom
+       DeploymentPackage-Customizer: true
+
+The first one should match the PID you used earlier.
+
+## Writing an ArtifactHelper and ArtifactRecognizer
+
+These services can usually just be implemented by the same class. The artifact 
recognizer
+is used to identify an artifact as being of this specific type. How it does 
that is up to
+the implementation. It might do something as simple as look at the file 
extension, but a
+lot of recognizers will also inspect (part of) the actual file. The artifact 
helper then
+contains all kinds of methods to help ACE deal with this specific type of 
artifact. The
+API documentation of these two interfaces explains the methods in detail. 
Again, let's get
+started with an implementation of both for a very simple artifact: a file with 
a specific
+extension:
+
+       :::java
+       public class CustomArtifactHelper implements ArtifactRecognizer, 
ArtifactHelper {
+           public static final String KEY_FILENAME = "filename";
+           public static final String MIMETYPE = 
"application/vnd.apache.ace.custom";
+           public static final String PROCESSOR = 
"org.apache.ace.resourceprocessor.custom";
+
+               @Override
+               public boolean canUse(ArtifactObject object) {
+               return (object == null) ? false : 
MIMETYPE.equals(object.getMimetype());
+               }
+
+               @Override
+               public ArtifactPreprocessor getPreprocessor() {
+                       return null;
+               }
+
+               @Override
+               public <TYPE extends ArtifactObject> String 
getAssociationFilter(TYPE obj, Map<String, String> properties) {
+               return "(" + ArtifactObject.KEY_ARTIFACT_NAME + "=" + 
obj.getAttribute(ArtifactObject.KEY_ARTIFACT_NAME) + ")";
+               }
+
+               @Override
+               public <TYPE extends ArtifactObject> int getCardinality(TYPE 
obj, Map<String, String> properties) {
+               return Integer.MAX_VALUE;
+               }
+
+               @Override
+               public Comparator<ArtifactObject> getComparator() {
+                       return null;
+               }
+
+               @Override
+               public Map<String, String> checkAttributes(Map<String, String> 
attributes) {
+                       return attributes;
+               }
+
+           public String[] getDefiningKeys() {
+               return new String[] {ArtifactObject.KEY_ARTIFACT_NAME};
+           }
+
+           public String[] getMandatoryAttributes() {
+               return new String[] {ArtifactObject.KEY_ARTIFACT_NAME};
+           }
+
+               @Override
+               public String recognize(ArtifactResource artifact) {
+                       // here we can examine the stream to check the contents 
of the artifact
+                       // for this demo, our check is just for the extension 
of the URL, which is
+                       // a bit simplistic
+                       if 
(artifact.getURL().toExternalForm().endsWith(".custom")) {
+                               return MIMETYPE;
+                       }
+                       return null;
+               }
+
+               @Override
+               public Map<String, String> extractMetaData(ArtifactResource 
artifact) throws IllegalArgumentException {
+               Map<String, String> result = new HashMap<String, String>();
+               result.put(ArtifactObject.KEY_PROCESSOR_PID, PROCESSOR);
+               result.put(ArtifactObject.KEY_MIMETYPE, MIMETYPE);
+               String name = new File(artifact.getURL().getFile()).getName();
+               result.put(ArtifactObject.KEY_ARTIFACT_NAME, name);
+               result.put(KEY_FILENAME, name);
+               return result;
+               }
+
+               @Override
+               public boolean canHandle(String mimetype) {
+                       return MIMETYPE.equals(mimetype);
+               }
+
+               @Override
+               public String getExtension(ArtifactResource artifact) {
+                       return ".custom";
+               }
+       }
+
+Again, this is no production code, but it should get you started quickly. This 
code will
+recognize artifacts that have the ".custom" file extension. No effort is done 
here to look
+at the contents of the file just to keep the example simple. Publish this 
instance as both
+an ArtifactHelper and an ArtifactRecognizer and make sure to add a service 
property for
+the mime type: <tt>ArtifactObject.KEY_MIMETYPE</tt>,
+<tt>CustomArtifactHelper.MIMETYPE</tt>.
+
+Wrap it up in a bundle, and you're ready to use your custom artifact in ACE.
+
+## Installing everything in ACE
+
+To add the new artifact type to ACE, you first have to take the bundle that 
contained the
+ArtifactHelper and ArtifactRecognizer service and add that to ACE. The bundle 
should be
+part of the ACE client. If you use the "all in one" server, add it to that.
+
+The second step is to upload the resource processor to ACE. You can do that 
like you
+upload any other bundle. Just add it to the artifact column. After adding it, 
it will not
+show up in the column, but ACE will send it to a target if that target needs 
an artifact
+of this type.
+
+Should you ever discover that you made a mistake in your resource processor, 
you can
+simply upload a newer one. Just make sure you bump the version and ACE will 
ensure that
+everybody gets this latest version.
+

Propchange: ace/site/trunk/content/docs/adding-custom-artifact-types.mdtext
------------------------------------------------------------------------------
    svn:eol-style = native

Added: ace/site/trunk/content/docs/analysis/auditlog-analysis.mdtext
URL: 
http://svn.apache.org/viewvc/ace/site/trunk/content/docs/analysis/auditlog-analysis.mdtext?rev=1641501&view=auto
==============================================================================
--- ace/site/trunk/content/docs/analysis/auditlog-analysis.mdtext (added)
+++ ace/site/trunk/content/docs/analysis/auditlog-analysis.mdtext Mon Nov 24 
22:42:00 2014
@@ -0,0 +1,112 @@
+Title: Audit Log Analysis
+
+An audit log is a full historic account of all events that are relevant for a 
certain object. In this case, we keep audit logs of each target that is managed 
by the provisioning server.
+
+Problem
+=======
+
+The first issue is where to maintain the audit log. On the one hand, one can 
maintain it on the target, but since the management agent talks to the server, 
it could keep the log too.
+
+Then there is the question of how to maintain the log. What events should be 
in it, and what is an event?
+
+Finally, the audit log should be readable and query-able, so people can review 
it.
+
+The following use cases can be defined:
+
+* Store event. Stores a new event to the audit log.
+* Get events. Queries (a subset of) events.
+* Merge events. Merges a set of (new) events with the existing events.
+
+Context
+=======
+
+We basically have two contexts:
+
+* Target, limited resources, so we should use something really "lean and mean".
+* Server, scalable solution, expect people to query for (large numbers of) 
events.
+
+Possible solutions
+==================
+
+As with all repositories, there should be one location where it is edited. In 
this case, the logical place to do that is on the target itself, since that is 
where the changes actually occur. In theory, the server also knows, but that 
theory breaks down if things fail on the target or other parties start 
manipulating the life cycle of bundles. The target itself can detect such 
activities.
+
+The next question is what needs to be logged. And how do we get access to 
these events?
+
+When storing events, each event can get a unique sequence number. Sequence 
numbers start with 1 and can be used to determine if you have the complete log.
+
+Assuming the target has limited storage, it might not be possible to keep the 
full log available locally. There are a couple of reasons to replicate this log 
to a central server:
+
+* space, as said the full log might not fit;
+* safety, when the target is somehow (partly) erased or compromised, we don't 
want to loose the log;
+* remote diagnostics, we want to get an overview of the audit log without 
actually connecting to the target directly.
+
+When replicating, the following scenarios can occur:
+
+1. The target has lost its whole log and really wants to (re)start from 
sequence number 1.
+2. The server has lost its whole log and receives a partial log.
+
+Starting with the second scenario, the server always simply collects incoming 
audit logs, so its memory can be restored from any number of targets or relay 
servers that report everything they know (again). Hopefully that will lead to a 
complete log again. If not, there's not much we can do.
+
+The first scenario is potentially more problematic, since the target has no 
way of knowing (for sure) at which sequence number it had arrived when 
everything was lost. In theory it might ask (relay) servers, but even those 
might not have been up to date, so that does not work. The only thing it can do 
here is: Start a new log at sequence number 1. That means we can have more than 
one log in these cases, and that again means we need to be able to identify 
which log (of each target) we're talking about. Therefore, when a new log is 
created, it should contain some unique identifier for that log (an identifier 
that should not depend on stored information, so for example we could use the 
current time in milliseconds, that should be fairly unique, or just some random 
number).
+
+How to find the central server? Use the discovery service!? This is not that 
big of a deal.
+
+Events should at least contain:
+
+* a datestamp, indicating when the event occurred;
+* a checksum and/or signature;
+* a short, human readable message explaining the event;
+* details:
+    * in the form of a (possibly multi-line) document
+    * in the form of a set of properties
+
+The server will add:
+
+* the target ID of the target that logged the event.
+
+Storage will be resolve differently on the server and target. On the target, 
using any kind of database would amount to having to include a considerable 
library, which makes these solutions impractical there. We might want to 
consider something like that for the server though. The options we have, are:
+
+* Relational database
+* Object database
+* XML
+* DIY
+
+How do events get logged?
+
+* explicitly, our management agent calls an AuditLog service method;
+* implicitly, by logging (certain) events in the system;
+
+Implicit algorithms can be build on top of the AuditLog service. What we need 
to monitor is the life cycle layer, which basically means adding a 
BundleListener and an FrameworkListener. Those capture all state changes of the 
framework. Technically we can either directly add those listeners, or use 
EventAdmin if that is available.
+
+What would be the best way for the target to send audit log updates to the 
server? I don't think we want the server to poll here, so the target should 
send updates (periodically). So how does it know what to send?
+
+* it could keep track of the last event it sent, sending newer ones after that;
+* it could ask for the list of events the server has;
+* it could send its highest log event number, and get back a list of missing 
events on the server, and then respond with the missing events.
+* it could just send everything.
+
+Discussion
+==========
+
+Having two layers for the audit log makes sense:
+
+* The first, lowest, layer is the AuditLog service that gives access to the 
log. On the one hand it allows people to log messages, on the other it should 
provide query access. Those should be split into two different interfaces.
+* The second layer can build on top of that. It can either be removed 
completely, which means the responsibility for logging becomes that of the 
application (probably the management agent). It can be implemented using 
listeners. Finally, it can be implemented using events.
+
+On the target we should implement a storage solution ourselves, to keep the 
actual code small. The code should be able to log events quickly (as that will 
happen far more often than retrieving them).
+
+Communication between the target and server should be initiated by the target. 
The target can basically send two commands to the server:
+
+1. My audit log contains sequence number 4-8, tell me your numbers. The server 
then responds (for example) with 1-6. This indicates we need to send 7-8.
+2. Here you have events 7-8, can you send me 1-3? The server stores its 
missing events, and sends you the events it has (always check if what you get 
is what you requested).
+
+This is setup in this way so the same commands can also be used by relay 
servers to replicate logs between server and target.
+
+Conclusion
+==========
+
+* The audit log is maintained on the target.
+* On the target, we implement the storage mechanism ourselves to ensure we 
have a solution with a very small footprint.
+* On the server, we use an XStream based solution to store the logs of all the 
targets.
+* Our communication protocol between target and (relay)server however, should 
probably not rely on XML.
+* Our communication protocol between server and (relay)server might rely on 
XML (determine at design time what makes most sense).

Propchange: ace/site/trunk/content/docs/analysis/auditlog-analysis.mdtext
------------------------------------------------------------------------------
    svn:eol-style = native

Added: ace/site/trunk/content/docs/analysis/bundlerepository-analysis.mdtext
URL: 
http://svn.apache.org/viewvc/ace/site/trunk/content/docs/analysis/bundlerepository-analysis.mdtext?rev=1641501&view=auto
==============================================================================
--- ace/site/trunk/content/docs/analysis/bundlerepository-analysis.mdtext 
(added)
+++ ace/site/trunk/content/docs/analysis/bundlerepository-analysis.mdtext Mon 
Nov 24 22:42:00 2014
@@ -0,0 +1,45 @@
+Title: Bundle Repository Analysis
+
+The bundle repository stores actual bundles and other artifacts. It is kept 
external to be able to leverage existing repositories and better protect the 
intellectual property of our users.
+
+Problem
+=======
+
+The bundle repository is an external repository that stores the actual bundle 
data and other artifacts. We keep this data external to our system to better 
protect the intellectual property of our users. Having only the meta-data in 
our system ensures the bundles and artifacts themselves can remain on a 
separate, protected network, even when the provisioning server itself is used 
in a hosted or cloud environment.
+
+Access to the bundle repository is URL based.
+
+The use cases are:
+
+* Get bundle, which returns the full bundle. This use case is mandatory, as 
this is the main goal for having a bundle repository.
+* Get bundle meta-data, which returns only the meta-data. This one is nice to 
have, as it would help us on slow connections when we only want metadata.
+* Get a list of (a subset of) all bundles in the repository. When 
provisioning, we already know what we want. When managing the shop we might 
have use for querying features and we should seriously look at OBR as an 
implementation. Also, as part of the Equinox provisioning effort, they are 
defining a similar model.
+* Install/update bundle. Makes the repository editable from the outside.
+* Delete bundle. Mentioned separately here because of the dangers of deleting 
bundles that might still be in use (the repository has no way of knowing what's 
in use).
+
+Context
+=======
+
+Whilst we will no doubt create our own bundle repository, it would be a big 
bonus if we could work with other bundle repositories. OBR comes to mind, but 
there might be others. Therefore it's important to create an implementation 
that maps easily onto (for example) an HTTP based repository.
+
+Our requirement to have URL based access to bundles ensures we can do that.
+
+Possible solutions
+==================
+
+As mentioned before, we basically have two solutions:
+
+1. use an existing solution;
+2. creating our own.
+
+Discussion
+==========
+
+Most use cases can be done either way. If you look at the OSGi Alliance's 
RFC-112 for OBR, the only thing it does not support is manipulating a 
repository. You could argue that's because it is beyond the scope, and because 
currently, OBR can be implemented using any webserver (it's basically just a 
set of bundles and a single XML descriptor).
+
+Conclusion
+==========
+
+I think we should create our own implementation of OBR, extending it with 
editing capabilities, and perhaps subsetting it (at least initially, we might 
not want a whole requirements, capability and dependency mechanism in there 
right now, as that's something we deal with inside our provisioning system).
+
+At the same time, adding these editing capabilities should not mean we cannot 
still generate static files that can be deployed on an external HTTP server. We 
do want to add an API for editing, but we don't want to make the whole 
repository depend on the capability to run code on that server, since we might 
want to do all maintenance on some client that simply uploads files to a server.
\ No newline at end of file

Propchange: 
ace/site/trunk/content/docs/analysis/bundlerepository-analysis.mdtext
------------------------------------------------------------------------------
    svn:eol-style = native

Added: ace/site/trunk/content/docs/analysis/index.mdtext
URL: 
http://svn.apache.org/viewvc/ace/site/trunk/content/docs/analysis/index.mdtext?rev=1641501&view=auto
==============================================================================
--- ace/site/trunk/content/docs/analysis/index.mdtext (added)
+++ ace/site/trunk/content/docs/analysis/index.mdtext Mon Nov 24 22:42:00 2014
@@ -0,0 +1,7 @@
+Title: Analysis
+
+* [Security Analysis](security-analysis.html)
+* [Template Mechanism](template-mechanism.html)
+* [Audit Log Analysis](auditlog-analysis.html)
+* [Bundle Repository Analysis](bundlerepository-analysis.html)
+

Propchange: ace/site/trunk/content/docs/analysis/index.mdtext
------------------------------------------------------------------------------
    svn:eol-style = native

Added: ace/site/trunk/content/docs/analysis/security-analysis-flow.svg
URL: 
http://svn.apache.org/viewvc/ace/site/trunk/content/docs/analysis/security-analysis-flow.svg?rev=1641501&view=auto
==============================================================================
Binary file - no diff available.

Propchange: ace/site/trunk/content/docs/analysis/security-analysis-flow.svg
------------------------------------------------------------------------------
    svn:mime-type = image/svg+xml


Reply via email to