@Generated(value="com.github.davidmoten:openapi-codegen-runtime:0.1.5") public interface Service extends ErrorHandler
EGC API
Sending a new MSI is two-phase (create then send). This is because the msiId value is a critical piece of information for the client (to be able to check status and/or cancel) and the API design must ensure that the client is safely in possession of msiID before a send happens. If the method was one phase then there would be no guarantee that the msiID was received (a failure could happen in any link in the return snetworking chain like a router, firewall, proxy server or indeed a problem at the client application end that prevented persistence of the msiID for later use). Moreover, if the method was one phase and a failure in the network chain occurred then not only would an orphan MSI be sent by the provider but the client would not have knowledge that the MSI had been successfully queued for sending and would naturally retry the send (multiple times even) and we end up with the same MSI being sent 2+ times.
To further clarify the problem being solved by a two phase send here is a discussion of the delivery guarantees of HTTP responses.
Note that a one phase call where the client generated a new unique id (using a UUID for instance) is a possible solution but is less desirable because it introduces a problematic edge case where the client accidentally uses the same id more than once. If two different messages are sent with the same id (concurrently even) then the service should ensure that only one message is accepted and that the service consumer is aware that the other message failed. To do this demands coordination with a single transactional resource (like a relational database) which also demands that that resource is highly available (relational databases are often not great at that during upgrade cycles). There are ways to get high availability (highly available cloud services like DynamoDB and many more can offer conditional updates) but there is a much simpler way with two-phase.
If instead of the one-phase call the server creates the msiId and communicates it to the client then the server side can potentially be scaled with ease if the msiID is a UUID for instance (which is effectively unique without coordination with other nodes).
For example, a highly available and scalable service could be constructed in AWS cloud using API Gateway with Lambda integrations that for the create message and send actions does this
A separate component then actions items on the queue(s). When both the send and create messages have been read then an actual send can take place. What is clear from this design is that many concurrent nodes could be receiving messages without coordinating with a central node/service to ensure id uniqueness.
Note also that to support two-phase send the status value of
CREATED is included.
The List MSIs action uses a paginated response as the number of MSIs in a response can get large. Pagination can reduce server overhead and improve response times. Client-driven pagination is where the client specifies an offset (skip) field and that number of rows is skipped by the server to return the next page. This can be inefficient for the server-side (see discussion) and it is preferred to use server-driven pagination which is where each page returned also includes a continuation token to be included in the next page call. The nice thing about this approach is that the server side can simply return an offset in the continuation token if desired but we enable more efficient techniques if wanted later.
Early versions of this API have suggested the inclusion of a
NationalSASId field in the created MSI with the purpose of allowing
a client to correlate an MSI with its internal data.
This field is a convenience only and thus theoretically should not be included. A client should manage its correlations itself by storing the unique msiId returned by the service paired with its internal identifiers.
If something is required then it should be labelled something
like tag and have arbitrary values so that the client can use it for
anything. Labelling it NationalSASId suggests more meaning to the
field than it may have. TODO confirm.
Note that the api below allows for float precision locations for geographic circles and rectangles. An implementation of this API may choose to use the location with reduced precision (for example lat longs rounded to nearest integer).
A PUT to an /msi/[id} path ]with content like {"isCancelled":true}
has been suggested as a way of cancelling a broadcast. This can be
achieved in a much simpler way with the DELETE verb without content
(a cancel action can be considered as a logical delete in the context
of this API). A cancelled broadcast cannot be changed in status but
can be queried.
Initial proposals for the API suggested a partial abstraction of C-Codes. In particular Priority, MsiType and AreaType were abstracted. This API demonstrates a full abstraction of C-Codes. It is equivalent to C-Codes but has an easier to read and process representation and the mapping to C-Codes then becomes a server-side implementation detail. By using the data modelling constructs of OpenAPI v3 and JSON Schema users can generate code for their API-consuming application that imposes compile-time checking (varies on language) instead of experiencing runtime failures.
TODO is there a requirement for full explicit C-Code support (zero abstraction)?
Initial proposals for this API included a re-authenticate method whereby a new token was returned if a currently valid token was supplied. This is a security hole in that anyone in possession of one valid token (but not the username and password) can stay authenticated forever. In the same vein, a sensible limit on validity duration of a token should be imposed so that a leaked token cannot be used for long. Given the likely usage of the API (in terms of the number of calls made in a time interval by a client) there should be no significant performance penalty forcing a refresh of the token each hour (or even less).
Bearer authentication is used (RFC6750).
Bearer authentication is carried in the Authorization request header in this format:
Authorization: Bearer BASE64_ENCODED_TOKEN
TODO The encoded content of the token is not defined (for example, JWT could be used) but is left to the implementer. Should the authentication flow follow an existing standard like OAuth 2.0?
Previous API drafts used the field names startDate and endDate for an MSI.
Given that those fields refer to timestamps not just dates the names startTime
and endTime have been used.
Iridium can at times provide receive and read acknowledgements. TODO get better documentation of the capability and a proper specification for their response from a list acks call.
There may be use cases for the following additional fields on an MSI:
A user could record in their own systems when they created or cancelled a broadcast but it might help problem diagnosis if that information was together.
TODO confirm
It would also be useful in some circumstances for users to know exactly when a message was broadcast by satellite. Although messages may be scheduled for immediate or later broadcast there may be significant delays till the broadcast occurs and the user should be able to see the actual broadcast times.
TODO discuss with satellite providers
| Modifier and Type | Method and Description |
|---|---|
default void |
cancelMsi(String id)
This is a logical delete of a broadcast in that it
prevents future broadcasts happening for this msiId
(be it a single or repeating broadcast).
|
default MsiId |
createMsi(MsiContent requestBody)
Submits message content and returns a unique id (across all
users) that is to be used in the send method.
|
default Msi |
getMsi(String id)
Returns the details of an MSI broadcast using the unique MSI identifier.
|
default GetMsis200Response |
getMsis(Optional<OffsetDateTime> startTimeMin,
boolean startTimeMinInclusive,
Optional<OffsetDateTime> startTimeMax,
boolean startTimeMaxInclusive,
Optional<OffsetDateTime> endTimeMin,
Optional<Boolean> endTimeMinInclusive,
Optional<OffsetDateTime> endTimeMax,
boolean endTimeMaxInclusive,
int limit,
Optional<List<String>> status,
Optional<String> broadcastType,
Optional<String> continuationToken)
Returns Maritime Safety Information broadcasts requested to
be sent by the user.
|
default Status |
getMsiStatus(String id)
Returns the status of an MSI broadcast using the unique MSI identifier.
|
default AuthenticationResponse |
getToken(AuthenticationRequestBody requestBody)
Obtains a token that will be passed in a request header to calls
to other paths on this API for authentication and authorization
purposes.
|
default void |
sendMsi(String id)
Requests that an existing unsent MSI be sent.
|
errorResponse, errorResponseBody, notImplemented, responsedefault AuthenticationResponse getToken(AuthenticationRequestBody requestBody) throws ServiceException
Obtains a token that will be passed in a request header to calls to other paths on this API for authentication and authorization purposes.
[status=200, application/json] --> AuthenticationResponse
[status=400, application/json] --> Error
[status=401, application/json] --> Error
[status=500, application/json] --> Error
requestBody - requestBodyServiceExceptiondefault GetMsis200Response getMsis(Optional<OffsetDateTime> startTimeMin, boolean startTimeMinInclusive, Optional<OffsetDateTime> startTimeMax, boolean startTimeMaxInclusive, Optional<OffsetDateTime> endTimeMin, Optional<Boolean> endTimeMinInclusive, Optional<OffsetDateTime> endTimeMax, boolean endTimeMaxInclusive, int limit, Optional<List<String>> status, Optional<String> broadcastType, Optional<String> continuationToken) throws ServiceException
Returns Maritime Safety Information broadcasts requested to be sent by the user.
Note that none of the parameters are required. If no parameters are supplied then all MSIs for the current user will be returned (paged).
The limit field may not be honoured exactly by the server
side (in that it might exceed a maximum limit of the server).
The results of this query may return in any order and that order may vary in repeated calls (for example, the returned MSIs may not be ordered by timestamp). If the client requires an ordering by time then all pages should be requested and then sorted client-side. TODO confirm expectations
[status=200, application/json] --> GetMsis200Response
[status=400, application/json] --> Error
[status=401, application/json] --> Error
[status=403, application/json] --> Error
[status=500, application/json] --> Error
endTimeMaxInclusive - If endTimeMaxInclusive is true (the default value if not specified)
then filters MSIs on endTime <= endTimeMax.
If endTimeMaxInclusive is false then filters MSIs
on endTime < endTimeMax.
If endTimeMaxInclusive not specified then has no effect.endTimeMax - If endTimeMaxInclusive is true (the default value if not specified)
then filters MSIs on endTime <= endTimeMax.
If endTimeMaxInclusive is false then filters MSIs
on endTime < endTimeMax.endTimeMin - If endTimeMinInclusive is true (the default value if not specified)
then filters MSIs on startTime >= startTimeMin.
If startTimeMinInclusive is false then filters MSIs
on startTime > startTimeMin.limit - Requests that at most `limit` MSIs are returned in the call.
The server may cap the requested `limit` (fewer items may be
returned). To request the next page available include the
returned `continuationToken` in the next call. If there are
no more items available then the response will not contain
a `continuationToken`.startTimeMin - If startTimeMinInclusive is true (the default value if not specified)
then filters MSIs on startTime >= startTimeMin.
If startTimeMinInclusive is false then filters MSIs
on startTime > startTimeMin.startTimeMinInclusive - If startTimeMinInclusive is true (the default value if not specified)
then filters MSIs on startTime >= startTimeMin.
If startTimeMinInclusive is false then filters MSIs
on startTime > startTimeMin.
If startTimeMinInclusive not specified then has no effect.endTimeMinInclusive - If endTimeMinInclusive is true (the default value if not specified)
then filters MSIs on endTime >= endTimeMin.
If endTimeMinInclusive is false then filters MSIs
on endTime > endTimeMin.
If endTimeMinInclusive not specified then has no effect.broadcastType - the type of broadcaststartTimeMax - If startTimeMaxInclusive is true (the default value if not specified)
then filters MSIs on startTime <= startTimeMax.
If startTimeMaxInclusive is false then filters MSIs
on startTime < startTimeMax.continuationToken - Describes to the server the starting point of
the next page of results and is obtained from
the current page. May contain an offset if desired
but is at the discretion of implementer. Note that
it is possible that a call specifying a continuation
token may return en empty list (but an empty list return
should not have a continuation token on it so at
that point paging would stop).status - Only MSIs that have a status in the given list
are returned. If the list is empty (or the parameter
is not present) then no filtering on status occurs.
TODO** support multi-status filtering or just one?startTimeMaxInclusive - If startTimeMaxInclusive is true (the default value if not specified)
then filters MSIs on startTime <= startTimeMax.
If startTimeMaxInclusive is false then filters MSIs
on startTime < startTimeMax.
If startTimeMaxInclusive not specified then has no effect.ServiceExceptiondefault MsiId createMsi(MsiContent requestBody) throws ServiceException
Submits message content and returns a unique id (across all users) that is to be used in the send method. It is ok for a message to never be sent but the provider should have the freedom to clean up (delete) unsent messages after some reasonable period or after more than N unsent messages are created. (TODO ask providers what is reasonable minimum period and maximum number of unsent messages so it can be documented here).
[status=201, application/json] --> MsiId
[status=400, application/json] --> Error
[status=401, application/json] --> Error
[status=403, application/json] --> Error
[status=500, application/json] --> Error
requestBody - requestBodyServiceExceptiondefault Msi getMsi(String id) throws ServiceException
Returns the details of an MSI broadcast using the unique MSI identifier.
[status=200, application/json] --> Msi
[status=400, application/json] --> Error
[status=401, application/json] --> Error
[status=403, application/json] --> Error
[status=404, application/json] --> Error
[status=500, application/json] --> Error
id - unique msi identifierServiceExceptiondefault void sendMsi(String id) throws ServiceException
Requests that an existing unsent MSI be sent. If the MSI has already been sent or the MSI has been cancelled then nothing occurs (this method is idempotent).
[status=400, application/json] --> Error
[status=401, application/json] --> Error
[status=403, application/json] --> Error
[status=404, application/json] --> Error
[status=500, application/json] --> Error
id - unique msi identifierServiceExceptiondefault void cancelMsi(String id) throws ServiceException
This is a logical delete of a broadcast in that it prevents future broadcasts happening for this msiId (be it a single or repeating broadcast). Once cancelled an MSI cannot be resent. However, the broadcast details are still available to be queried.
[status=400, application/json] --> Error
[status=401, application/json] --> Error
[status=403, application/json] --> Error
[status=404, application/json] --> Error
[status=500, application/json] --> Error
id - unique msi identifierServiceExceptiondefault Status getMsiStatus(String id) throws ServiceException
Returns the status of an MSI broadcast using the unique MSI identifier.
[status=200, application/json] --> Status
[status=400, application/json] --> Error
[status=401, application/json] --> Error
[status=403, application/json] --> Error
[status=404, application/json] --> Error
[status=500, application/json] --> Error
id - unique msi identifierServiceExceptionCopyright © 2023. All rights reserved.