Skip to content

Code Structure

Jasper Nalbach edited this page Jul 25, 2017 · 1 revision

Modules

las2peer is splitted up into mutliple modules, which are the core, connectors (WebConnector) and the RESTMapper.

The core provides the p2p functionality, including low level communication as well as service execution. In theory, the core is enough to start a p2p network and run basic services.

The RESTMapper provides functionality to implement a service that exposes a RESTful interface. All nodes that should be able to run a RESTful service needs the RESTMapper to be installed. The WebConnector makes the RESTful interfaces defines by those services available to the web and defines endpoints for creating agents and uploading services to the network.

Core structure

Service API structure

The service API introduced to abstract the inner workings of a las2peer implementation from the concepts. This should increase the compatibility of services over multiple las2peer versions and also increase the awareness of a good interface that is exposed to the outside.

The service API follows the following principles:

  • A context represents the set of actions that can be performed in a given scope (i.e. a service).
  • Concepts like symmetric/asymmetric keys, encryption and signing are abstracted to locking and owning.

The methods of the current Context interface are designed as follows:

  • Fetching something from the network means downloading an envelope/agent, requesting means fetching and unlocking.
  • All updates to envelopes and agents are only applied locally and do not throw an exception.
  • When storing an agent or envelope, all operations are applied to the network and permissions are checked at this stage.
  • If an operation requires an agent, the main agent is used by default. Otherwise another agent can be specified in the last parameter which performs the action.

Implementation hints / warnings

  • Do not mess up with the class loader. All classes that are part of a service needs to be loaded using the ServiceClassLoader responsible for the current service. We experienced bugs that tried to load such classes when loading an envelope from the network.
  • Execute service code in the respective ServiceThread. The service always exepcts an active context, which is bound to a thread. Executing service code (except the startup/shtudown hooks) in another thread leads to unexepcted behaviour.
  • Make sure the service cannot break things! Always copy agents when passing them to the service, hide lower level functionality to the service and keep sensible information (i.e. keys and passphrases) from the service away.

Outstanding refactoring / Ideas

The first implementation of the service API is a wrapper / adapter around the "old" core structure. However, it follows the same concepts and principles as the original structure and thus, few but neccessary changes are outstanding:

  • The Context could be extended for async methods of the form requestEnvelopeAsync(..., Callback callback). Note the callback function should be scheduled throught the executor service available through Context.getExecutor() to keep the current context.
  • The Context could be splitted up into its different functionalities. For example, one could have a basic P2pContext providing functionality to access las2peer's p2p features, a MonitorContext providing MobSOS functionality etc. They could then be put together to a ServiceContext which would be the equivalent to the current Context. The "new" Context would be a supertype for all types of contexts.
  • Currently there is no nice interface for unit tests to use las2peer's p2p features. The idea would be to create a TestContext that provides only access to the p2p functionality.
  • Introduce a Lockable and Signable (or Artifact) interface/abstract class and make Envelope(Impl) and Agent(Impl) inheriting from that. The idea is that an agent provides methods openLockable(Lockable), and sign(Signable). This way,
    • the corresponding implementations of the AnonymousAgent can simply throw an AgentAccessDeniedException and makes the instanceof AnonymousAgent checks superfluous and
    • maybe some casts to *AgentImpl can be removed.
  • The internal Envelope should be simplified as it makes too many assumption about the underlying overlay network. E.g. EnvelopeVersion should be removed and the functionality should be shifted to the PastryNodeImpl implementation.

Disclaimer: Please note that these are only ideas and may not be suited or not reasonable.

Try to keep the API stable, which should be not hard because it is seperated from the implementation. You will learn that there will be always things that you want to refactor. Do it over time, but make sure to check if the jUnit tests are sufficient to test if the new implementation does not break anything..