See first: Juju | Integration
See also: How to add an integration to a charm
Before juju v.3.0
, ‘integrations’ were called ‘relations’. Remnants of this persist in the names, options, and output of certain commands, and in integration event names.
In Juju, an integration is a connection between applications, or between different units of the same application (the latter are also known as ‘peer relations’).
The definitions of relations are handled through interfaces, which are “loosely typed”, meaning there is no de-facto specification for:
- What information a relation must send/receive
- What actions are to be taken with data sent/received over the wire
While there is no formal specification, it is important to carefully consider the interface you present. Integrations are formed based on interface name only. For integrations to work effectively, the same data format needs to be set/observed on either side of the integration.
Contents:
Types of integration
Provide and require integration
Provide and require integration are the typical form of integration for the case when you want to connect an application with another.Implicit integration
Implicit integrations are a special form of provide or require integration that allow for simple integrations to be formed without requiring any modifications to target charms. Implicit integrations exist in the reserved namespace. There is currently only one such integration provided to all deployed applications: juju-info.
The juju-info integration captures very select data from the remote unit:
- private-address
- public-address
A common use for this type of integration is when authoring a subordinate charm that can be integrated with any other charm – in this case the juju-info implicit integration can be used.
Peer integration
Charms can contain peer integrations, which causes each unit of an application to respond to the other units deployed in the same application.Integration data
The primary means for applications to communicate over an integration is using integration data. This is exposed to the charm as a property of the event passed to the relevant callbacks. All integration events inherit from the RelationEvent class, which encapsulates the relevant integration at .relation. The integration includes a data parameter of type RelationData which is a mapping containing all integration data stored by participating applications and units.
Integration data comprises a number of “databags” (or “data buckets”). Each application and each unit has its own databag, which is a Python str:str mapping. There are some rules about accessing integration data:
- Units can read and write their own unit databags (e.g. event.relation.data[self.unit])
- Units can read from any other unit databags (e.g. event.relation.data[event.unit])
- Application leaders can read and write their application databags (e.g. event.relation.data[self.app])
- Non-leaders can read from other application databags (e.g. event.relation.data[event.app])
Integration data is persisted to the controller database, and therefore persists across invocations of the charm code and through the various event handlers that may access it.
The framework also provides a mechanism for a charm author to fetch an integration from the model by name or ID. This can be useful in cases where methods (that are not integration event callbacks) need to access integration data. An example of this might be updating application data on a peer integration in the leader-elected event callback. Details of this method are documented in the API docs, and it is used in context in the examples provided. Where there are multiple integrations present for a single integration name, the get_integration method takes an id of the integration to fetch. In these cases it may be easier to iterate over the integrations property of the model, which returns a Mapping of all integrations.
Contributors: @florezal