Adding priorities to jobs


**In order to test all this changes, please use the [priority branch in the cli](https://github.com/daisy-consortium/pipeline-cli/tree/priority)**
__First part: Scheduler and Job priorities__

___Changes on the current design___
When we agreed on the new priorities scheme we decided to have to different priorities, per client and per job. So modifications to the following classes have to be done:
Job: add priority
JobContext: add the client (now the context is client aware)
Client and related classes: moved to the framework-core.
Client: add priority.
DefaultExectutionService: Now depends on a ThreadPoolExectionService (fixed size) and this have to be change to take into account the priorities.

___ThreadPoolExecutonService Design___
The main requirements we have are:
1. Some mechanism for moving up and down jobs in the priority queue. 
2. Take into account the job priorities.
3. Avoid starvation.

* [UpdatablePriorityBlockingQueue] (https://github.com/daisy-consortium/pipeline-framework/blob/priority/framework-core/src/main/java/org/daisy/pipeline/job/priority/UpdatablePriorityBlockingQueue.java)
This queue implementation allows to move prioritised tasks and gives a mechanism to update the priorities of the tasks waiting to be executed.

* [PriorityThreadPoolExecutor](https://github.com/daisy-consortium/pipeline-framework/blob/priority/framework-core/src/main/java/org/daisy/pipeline/job/priority/PriorityThreadPoolExecutor.java)
ThreadPoolExecutor that uses an UpdatablePriorityBlockingQueue under the hood. A part from allowing moving up and down tasks it adapts to the executing context by tracking the time that each task has spent in the queue. 

* Fuzzy system:
Each job is now wrapped in fuzzy system that controls each job's final priority. This final priority is calculated in base to the time spent in the working queue (tracked by the executor itself), and the two available priorities. The system is designed so that no task will starve (i.e. a task with high priorities (job and client) that is new in the queue has less final priority than a very old task with low priorities. The system is also tested for general sanity: In the same temporal conditions, tasks with higher priorities have higher final priority, and tasks that have waited longer have higher final priority when the rest of the variables are the same.

The new scheduling service follows the next steps:

1. Each time a new job is submitted the waiting time is set to 0 and its overall priority is computed before being inserted into the queue.
2. Before a task is executed its waiting time is stored.
3. When enough tasks (5 by default) have been executed the average waiting time is calculated, assuring a nice adaption to the current conditions in the queue. The priorities of the rest of the tasks in the queue are updated taking into account their relative waiting time and their different priorities.
4. voila :smile: 

__Second part: Client storage__
In the previous version when someone was using the ClientStorage interface to add new clients they would have to create first a SimpleClient and the concrete implementation of the storage would have to copy it or wrap it somehow to properly manage it. Now that the JobContext and the Client are directly related this could potentially introduce some errors in the Db. 

So, the interface ClientStorage is now in charge of client creation using [ClientStorage.addClient](https://github.com/daisy-consortium/pipeline-framework/blob/priority/framework-core/src/main/java/org/daisy/pipeline/clients/ClientStorage.java#L56) to make sure that the underlying persistent layer is managing the clients correctly.

In the previous version the client storage could return null references in some cases, such as when ClientStorage.get(id) and the id was not found. In order to avoid the users of this part of the API to forget to check for nulls this has been refactored to use guava's Optional.

__Third part: Job creation and management__

Until now jobs and job management were client agnostic, but the new requirements have changed this. Specifically, we needed that a non-admin client could only see/manipulate its own jobs, so now, the job management has become client-oriented. Also I've tried to simplify a bit the job creation for API users, so @marisademeglio feel free to criticise and comment the new approach :wink:.

___JobManagement___
Now the job management is client-centric. Instead of having a a JobManager service now we have a JobManagerFactory that will create  a JobManager only usable for a given client, [JobMangerFactory.createFor(Client client)](https://github.com/daisy-consortium/pipeline-framework/blob/priority/framework-core/src/main/java/org/daisy/pipeline/job/JobManagerFactory.java#L12) . It's clear that for the webservice the concept of client is necessary, on the other hand, for desktop applications we might not be insterested in creating new clients to interact with the manager. That's the reason why we have ClientStorage.defaultClient().

One we have a JobManager we don't longer need a JobContextFactory to create the context and then add it to the manager. The new approach is based on an internal bulider and can be used as
```java
jobManager.newJob(script).isMapping(true).withNiceName("my_job").build();
```
As happened with the client storage, JobManagement won't return null jobs when a job wasn't created or found anymore, now the interface relies on Optional objects that the client code will have to check in order to use the object instead of comparing the returned values against null.

In terms of internal refactorings, AbstractJobManager and ExecutingJobManager have disappeared. Instead we have now a DefaultJobManager that receives an ExecutionService on creation. This eliminates the complexity of having an extra subclass, and at the end of the day we will always want to execute a job when it's added (or inject an idle executing service in the rare case that we don't want to).

___JobStorage___

Now the job storage offers the possibility of filtering by client, so the JobManager can achieve the new requirement seamlessly. To make it more flexible this filtering is done by creating a wrapped version on the storage by invoking [JobStorage.filterBy(Client client)](https://github.com/daisy-consortium/pipeline-framework/blob/priority/framework-core/src/main/java/org/daisy/pipeline/job/JobStorage.java#L14). How the storage is wrapped is heavily dependent on the particular implementation, as the persitentstorage version is way more complex that the volatilestorage and having a common approach of filtering the results (i.e. via Collections2.filter()) would imply losing the advantages of the database oriented approach when accessing the whole set of jobs.

__Fourth part: Webservice update for priority support__

Now an optional priority can be sent along with the job request to set a specific job priority. This priority is also sent back when querying for the job status.

__Fith part: Webservice update for queue management__

Included entries in the webservice to see the queue and move jobs up and down the queue. Although I thought in the beginning to include this functionality under the /admin domain then I realised that as each client can only see its jobs we can allow also APPCLIENT clients to move jobs up and down.