This document describes the high level design for the OpenShift Java Client (OSJC). It is intended to cover aspects of this client in support of the v3 architectural release of OpenShift which is based on Kubernetes and Docker. Design considerations for previous releases of OpenShift are not discussed here.
The primary consideration for the current design is to isolate, as much as possible, consumers of the library (e.g. JBoss Tools) from changes in the the API models. Previous experience has shown it can be challenging to maintain a client(e.g. UI) that supports both bleeding edge versions as well as a more stable code base such as enterprise deployments. Possible scenarios that are specifically being addressed:
- New properties and functionality added to existing types for in the latest API version
- New properties and functionality back-ported to existing types in older API versions
- Property and functionality deprecation for types in the latest API version
The general principle is to separate the models from functionality that supports them. The result is a capabilities model where clients consume the capabilities offered by the various resources instead of depending upon specific versions of the API model. This should simply client code by:
- Removing if/then checks based on model versions
- Allowing consumption of back-ported functionality by enabling the appropriate capability in the library code.
- "Removing" deprecated functionality by removing the capability in the library code.
Consumers of the library should depend upon the various model and capability interfaces provided by the library.
The model types are based upon the resources available for an OpenShift deployment. This includes both OpenShift and Kubernetes types. The OpenShift origin server allows for interaction with the REST interface using several versions of the models. The OSJC allows clients to interact with the server by:
- Providing interfaces that expose only properties that are fundamental to a given type (e.g. triggers for build) or to all types (e.g. name, labels)
- Providing features or functional aspects as separate capabilities (as helper classes)
- Limiting the possible types to those most likely to be of interest (i.e. Pod but not containers)
The current implementation is based upon the JBoss DMR library. This library consumes a JSON string and can access specific parts of the content using a path syntax. The default implementation of the client uses a resource factory to consume a versioned JSON string and return an instance of an API model that has the correct paths to the objects properties. The paths are registered in a versioned property map registry.
Capabilities provide the functional features of a resource.
One use case of capabilities is to retrieve resources that have a logical association.
The OpenShift API model provides a loose association between various resource by adding known annotations to the OpenShift object. A
resource is instantiated with a capability and a client can query a resource to determine
if it is able to provide the given capability.
TBD
- Versioned Packages vs Versioned Property registry?
- Capabilities exposed via some Visitor pattern?