Skip to content

Latest commit

 

History

History
80 lines (60 loc) · 9.11 KB

delivery-interface.md

File metadata and controls

80 lines (60 loc) · 9.11 KB

Delivery Interface Example

Eiffel messaging can favorably be used to implement software delivery interfaces between products and organizations. This is typically achieved by a system placing requirements on the events its constituent parts must use to communicate that they offer a new candidate for integration, and then driving that integration by reacting to those events. The Eiffel vocabulary offers considerable freedom in the level of detail of such interfaces - as always, an important principle is freedom in what you communicate, but not in how you communicate it. Consequently what is presented here is an example of the event usage a system may require from its constituent parts in order to ensure a satisfactory level of traceability; actual implementations may require more or less, but the essential building blocks are the same.

Introduction

A prime concern in designing delivery interfaces is to ensure traceability across products, organizations and enterprises. From a traceability point of view the links of particular interest are typically content and quality related ones: what does this artifact contain, what has changed, has it been tested etc. Consequently this example focuses on those events and links; all causality links and activity events have been excluded. This does not mean that no such events and links may be used, however, but merely that they are not a required part of the delivery interface in this particular example.

In this example the EiffelConfidenceLevelModifiedEvents CLM1 and CLM2 are used to signal that a new candidate is considered good enough to be integrated (ArtC1 and ArtC2), while the remaining events provide context and meta-data.

A JSON array of all events used in this example can be found here.

Event Graph

alt text

Event-by-Event Explanation

ID1, ID2, ID3

The EiffelIssueDefinedEvents represent issues of varies types (in this case, REQUIREMENT and WORK_ITEM) which other events may reference to document why a certain action has been taken.

SCC1, SCC2, SCC3, SCS1, SCS2, SCS3

The EiffelSourceChangeCreatedEvents declare that changes have been made and link to relevant EiffelIssueDefinedEvents. This does not mean mean that the change has been merged onto the project mainline (or other relevant branch) - this is instead declared by The EiffelSourceChangeSubmittedEvent. The distinction between the two is important when working with review processes, private repositories and/or pull requests. If none of that is applicable, the two events are simply sent at once.

The structure of events shown in this example represents a common development branch, where changes are represented by SCS1, SCS2__ and SCS3. Each of these submitted changes references a EiffelSourceChangeCreatedEvent via CHANGE links, and also points to the latest previously submitted version(s). This establishes an unbroken chain of source revisions along with a record of the process leading up to that submission.

CDef1, CDef2, CDef3

EiffelCompositionDefinedEvents declaring that new compositions are available to be built. Note that in this example not every composition leads to the creation of a new artifact. In industrial practice this is a common phenomenon, for which there may be a number of reasons - often there simply isn't sufficient time or resources to build each individual change.

Note that EiffelCompositionDefinedEvents may reference any number of elements: often a composition doesn't just consist of the one source revision, but a large collection of sources, binaries and third party libraries.

ArtC1, ArtC2

The EiffelArtifactCreatedEvents representing new versions of the built software.

TCS1, TCS2, TCF1, TCF2

EiffelTestCaseStartedEvents and EiffelTestCaseFinishedEvents representing one test execution per artifact (ArtC1 and ArtC2, respectively). Note that management of test cases per se is not within the scope of Eiffel, but like many events EiffelTestCaseStarted is able to reference external entities. Furthermore, it is assumed in this example that these externally managed test case descriptions in turn are able to reference any requirements they verify (which is arguably good practice in any context). With those references in place, these events can be used to answer the question "Which requirements have been verified in which version of the product, and what was the outcome?".

CLM1, CLM2

EiffelConfidenceLevelModifiedEvents signaling that a new version of this component or part of the system is deemed ready for delivery. In this example, this is the event that the next tier of the system hierarchy reacts to, and proceeds to pick up the referenced artifact (ArtC1 and ArtC2, respectively) to integrate it.

Traceability in Practice

Analysis of the events provided in this example (and the external data sources referenced by them) can, purely from a systems integration point of view, be used to answer the following questions:

  • Which test cases have succeeded and/or failed for ArtC2, as opposed to ArtC1?
  • When was a certain source change first delivered?
  • When was a certain requirement/feature implementation first delivered?
  • Which requirements have been verified in ArtC2, as opposed to ArtC1?
  • What is the source code diff from ArtC1 to ArtC2?
  • Which requirements, tasks and/or features have been implemented between ArtC1 and ArtC2.

Let's take a closer look at answering the last question by going through the process one step at a time.

  1. Identify the two artifact versions to be compared. Depending on the use case, the versions to be compared can either be explicit or implicit: "I want to compare ArtC2 and ArtC1" or "I want to compare ArtC2 to its previous version". In the latter case, the PREVIOUS_VERSION link can be traced to the object of interest.
  2. Build a list of constituent EiffelSourceChangeSubmittedEvents of the newer artifact (ArtC2):
    1. Identify the composition of the artifact (CDef3).
    2. Append any EiffelSourceChangeSubmittedEvents referenced via ELEMENT links (SCS3).
    3. Recursively apply the process to any EiffelArtifactCreatedEvent or EiffelCompositionDefinedEvent referenced via ELEMENT links (none, in this example).
  3. Repeat the process for the older artifact (ArtC1).
  4. Identify the delta of EiffelSourceChangeSubmittedEvents between the two lists ({SCS3} and {SCS1}, respectively):
    1. Remove any EiffelSourceChangeSubmittedEvents present in both lists (none, in this example).
    2. Include any remaining EiffelSourceChangeSubmittedEvents in the newer list (SCS3).
    3. Recursively follow the PREVIOUS_VERSION links of these events, including everything up until anything in the list of the old version (in this example, yielding SCS2).
    4. Any events in the list of the old version not hit upon represent deletions.
  5. The resulting delta is {SCS3, SCS2}.
  6. For each EiffelSourceChangeSubmittedEvent in the list, follow the CHANGE link to its corresponding EiffelSourceChangeCreatedEvent.then append to the final output all elements of their data.issues arrays ({Req2, Req1, Task1}). Note that these objects contain a field describing the transition of the issue (i.e. what happened to it as a consequence of the source change - was it completed or removed?); for more information, see EiffelSourceChangeCreatedEvent.
  7. Repeat the process for the list of deletions and append any issues thus discovered, but inverting the transition.

Following these steps we find that Req2, Req1 and Task1 were completed between ArtC1 and ArtC2. Furthermore, this information is propagated throughout the enterprise and persistently stored, regardless of the issue handling tools or processes used by the individual development unit.