Skip to content

Commit

Permalink
0.124.0
Browse files Browse the repository at this point in the history
  • Loading branch information
wbouvy committed Oct 10, 2022
1 parent 3bcf2cf commit 91b92a4
Show file tree
Hide file tree
Showing 42 changed files with 12,552 additions and 7,121 deletions.
33 changes: 33 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,39 @@

#### Upcoming Changes

### 0.124 (2022-10-10)

##### Permissions

- Added `SupportPermission`s:
- `SupportPermission`s are used for features typically reserved for customer support, or that behave differently
when used by a customer support operator.
- Added `Filter.SupportPermissions`.

##### CurrentUserService

- Added `CurrentUser.support_permissions` to show the support permissions for the current user.

##### EasypulseService

- Added `Fields` call to get field configuration for Easypulse.

##### ModemService

- Added a few more options to `ListModemsRequest.Sort`:
- `STATUS_ASC_ALPHABETICAL` and `STATUS_DESC_ALPHABETICAL`: sort by status, alphabetically (instead of by status enum order).
- `HEALTH_ASC_ALPHABETICAL` and `HEALTH_DESC_ALPHABETICAL`: sort by health, alphabetically (instead of by severity).
- Renamed Modem.Status to Modem.Lifecycle
- Updated enum values:
- DEFAULT = ACCEPTANCE_TESTING
- ACTIVE = INSTALLED
- DEAD = DECOMMISSIONED
- Added enum value:
- PAUSED
- Deprecated enum values:
- DAMAGED
- LOST

### 0.123 (2022-10-03)

##### EasypulseService
Expand Down
5 changes: 5 additions & 0 deletions base.proto
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,11 @@ message Filter {
repeated UserPermission exclude = 3;
}

message SupportPermissions {
repeated SupportPermission include = 1;
repeated SupportPermission exclude = 2;
}

message FieldEnumValues {
string field = 1;
repeated string include = 2;
Expand Down
255 changes: 255 additions & 0 deletions buf.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,255 @@
# Hiber API

This is the protobuf specification of the Hiber GRPC API.

Hiber also offers a limited, [read-only rest API](https://github.com/hiberglobal/rest-api) for convenience.
This is based on the protobuf object definitions, but is (for now) mainly intended as a compatibility option
to fetch messages and message events.

## Technical tools

### Protocol Buffers

Protobuf is Google's replacement for JSON.
Due to its use of binary buffers, it's a more efficient way to encode data than text based protocols (SOAP, JSON), especially in encoding integers. Fields are encoded through
a 'tag', which are integers, which improves the density even more.

There are protobuf libraries in most used languages, such as Java, JavaScript, Golang, C#, C, and C++. This makes adoption of the protocol really easy.
Because server and client model are generated from the same source, there can be no confusion about the model.

For more information, take a look at:

- [Protobuf at Github](https://github.com/google/protobuf/wiki)
- [Google Protocol Buffers Developer Guide](https://developers.google.com/protocol-buffers/)

### GRPC

GRPC is a way of defining rpc services in the protobuf format.
GRPC is based on HTTP/2 and formalized the networking, status responses and streaming implementation for API calls.
Because the specification generates both the client and server code, the specification is valid by default
and API documentation is in one place.

For more information, take a look at:

- [GRPC Homepage](https://grpc.io/)
- [GRPC Concepts](https://grpc.io/docs/guides/concepts.html)
- [GRPC Language Guides](https://grpc.io/docs/)
- [GRPC at Github](https://github.com/grpc/grpc)

### GRPC Web

Since GRPC is based on HTTP/2, it is not (yet) compatible with web browsers.
In order to support web-based applications, we are running the grpc-web proxy.
This allows GRPC calls from the browser, using the typescript code generated by the GRPC Web generator.

For more information, take a look at:

- [GRPC Web Specification](https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-WEB.md)
- [GRPC Web on Github](https://github.com/improbable-eng/grpc-web/)

(Note that Google has recently release [a beta version of their implementation of GRPC Web](https://github.com/grpc/grpc-web).
We are looking into switching to that implementation in the future.)

## Usage

First of all, have a look through the .proto files in this repository.
You will find that they are very easy to read, and we have tried to name everything as clearly as possible,
so as to avoid unnecessary extra documentation.

To use the proto files, clone this repository and generate code in your preferred language:

- [C++](https://grpc.io/docs/tutorials/basic/c.html#generating-client-and-server-code)
- [C#](https://grpc.io/docs/tutorials/basic/csharp.html#generating-client-and-server-code)
- [Dart](https://grpc.io/docs/tutorials/basic/dart.html#generating-client-and-server-code)
- [Go](https://grpc.io/docs/tutorials/basic/go.html#generating-client-and-server-code)
- [Java](https://grpc.io/docs/tutorials/basic/java.html#generating-client-and-server-code)
- [Node](https://grpc.io/docs/tutorials/basic/node.html#creating-the-client)
- [Objective-C](https://grpc.io/docs/tutorials/basic/objective-c.html#generating-client-code)
- [PHP](https://grpc.io/docs/tutorials/basic/php.html#generating-client-code)
- [Python](https://grpc.io/docs/tutorials/basic/python.html#generating-client-and-server-code)
- [Ruby](https://grpc.io/docs/tutorials/basic/ruby.html#generating-client-and-server-code)

### Simple example

For example:

```
service CurrentUserService {
rpc CurrentUser (CurrentUserRequest) returns (CurrentUser);
}
message CurrentUser {
string id = 1;
string email = 2;
string name = 3;
repeated string organizations = 4;
}
message CurrentUserRequest {
}
```

(Note that this is a reduced, and possibly outdated, example and you should consult the actual proto file for the actual, up to date definition.)

This defines a service that has one rpc call, which expects an empty request object and returns a CurrentUser object.

For API client purposes, you can mostly ignore the numbers and see this as a data class.
Note the `repeated` keyword for the `organizations` field. This indicates that the field is of an array type (like `string[] organizations`).

### List requests, selection objects and pagination

For many of our list calls, which can list items like modems, users, etc., we use a selection object to
simplify the filtering of the data.

Since the same selection criteria can be used in different calls, selection objects are a simple way to
extract this duplication out of the definitions.

For example:

```
service WebhookService {
rpc List (ListRequest) returns (ListRequest.Response);
}
message Webhook {
int64 id = 1;
string organization = 2;
string description = 3;
repeated api.tag.Tag tags = 4;
}
message WebhookSelection {
string description = 1;
string url = 2;
Filter.Webhooks webhooks = 3;
api.tag.TagSelection tags = 4;
}
message ListRequest {
message Response {
repeated Webhook webhooks = 1;
ListRequest request = 2;
Pagination.Result pagination = 3;
}
string organization = 1;
WebhookSelection selection = 2;
Pagination pagination = 3;
}
message Pagination {
message Result {
int32 size = 1;
int32 page = 2;
int32 total = 3;
int32 totalPages = 4;
Pagination previous = 6;
Pagination next = 7;
}
int32 size = 1;
int32 page = 2;
}
```

(Note, again, that this is a reduced, and possibly outdated, example.)

This code actually contains a few interesting things. First, nested messages.
These are used to denoted linked function, i.e. the `Response` message inside the `ListRequest`.

The `WebhookSelection` message contains the filters that can be applied to webhooks.
Note that the `WebhookSelection` message contains a `TagSelection` as well.
This is another selection object, used to filter webhooks by tags.

The `Pagination` message is used to paginate the result.
It's a simple page size and page number combination (where 0 is the first page).
The `Pagination.Result` message also contains `size` and `page`, but has corrected the `size` field to a
maximum value (or default value if it was 0).
For convenience, it also contains a previous and next `Pagination` object, for easy pagination.

Note that `ListRequest.Response` contains a `ListRequest`, which is a corrected version of the request.
Selection object may have certain defaults or value limits, which will be visible in the corrected request.

### Default values

Everything in protobuf has a default value, which has a few interesting complications.

For example:

```
enum ContentType {
DEFAULT = 0;
JSON = 1;
PROTO = 2;
}
```

Since protobuf has a default value for all objects, enum takes the first value as default value.
To avoid the situation where omitting the field would still set a value, we've introduced the `DEFAULT` value.

```
message UpdateBoolean {
bool updated = 1;
bool value = 2;
}
```

Since false is the default value for a boolean, we need to distinguish between an omitted value and
setting the value to false in an update object.
For this, we've added an `UpdateBoolean` message (and `UpdateClearableString` and `UpdateZeroableInt`
for string that can be set to empty, and ints that can be set to 0, respectively)

Usage is pretty simple, set a value in the object and set `updated` to true.

### Versioning

Protobuf/GRPC has a built-in versioning mechanism by using numbered fields.
This essentially means that a field would change in a non-backwards compatible way, it would either be removed and added it with a new number, or deprecated and a new field with a new name would be added.
In case of removal, the server is able to detect whether an old version is used and convert the field.

For more information and a small number of examples, see the examples of versioning methods in the examples repo: [Versioning example](https://github.com/HiberGlobal/examples/tree/master/versioning)

## Developing on our API

For Hiber customer development, we have set up endpoints under [acc.env.hiber.cloud](https://acc.env.hiber.cloud):

- [acc.env.hiber.cloud](https://acc.env.hiber.cloud): The Hiber web application
- [api.acc.env.hiber.cloud](https://api.acc.env.hiber.cloud) (or [grpc.acc.env.hiber.cloud](https://grpc.acc.env.hiber.cloud)):
The GRPC API, accessible over https on port 443 or 1443.
(Note that opening this url in your browser will not work, since it requires HTTP2.)

Notes:
- This can be considered a stable production-like environment.
- Technically, you might be able to connect a normal GRPC client to the GRPC Web API, but this is not recommended.

### API Tokens

The Hiber API requires a token for all GRPC calls, using a metadata field called `authorization` with value `bearer $YOUR_TOKEN_HERE`.

To get a token for our API, go to the web application at [acc.env.hiber.cloud](https://acc.env.hiber.cloud) and log in.
Once you are linked to an organization (this process is defined in the api, but not implemented in the web interface yet)
you can create a token (using another token) on the API.

(Note: for pilot customers, a number of tokens can be generated in advance, so this process is not necessary.)

### Using our API in production

For actual modems and modem messages, use [hiber.cloud](https://hiber.cloud):

- [hiber.cloud](https://hiber.cloud): The Hiber web application
- [api.hiber.cloud](https://api.hiber.cloud) (or [grpc.hiber.cloud](https://grpc.hiber.cloud)):
The GRPC API, accessible over https on port 443 or 1443.
(Note that opening this url in your browser will not work, since it requires HTTP2.)

## Examples

We've provided a collection of minimal examples in different languages in
our [examples repository](https://github.com/HiberGlobal/examples).

For initial development, to simplify client experimentation with our GRPC API, and as a server used by our examples,
we've created a simple mock server that implements our API.
It will return example data, and does not do any error handling aside from requiring that a token is present.

For simple usage, you can simply pull the docker image at [hiberglobal/mock-server](https://hub.docker.com/r/hiberglobal/mock-server/)
(most of the examples do this automatically when you run them).
You can see the source code get some more information at [the mock-server folder in the examples repository](https://github.com/HiberGlobal/examples/blob/master/mock-server/).
52 changes: 52 additions & 0 deletions buf.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
version: v1
name: buf.build/hiber/api
breaking:
use:
- WIRE
except:
- FIELD_WIRE_COMPATIBLE_TYPE
lint:
use:
- DEFAULT
except:
- ENUM_VALUE_PREFIX
- DIRECTORY_SAME_PACKAGE
- PACKAGE_SAME_JAVA_MULTIPLE_FILES # this works fine for Java
- PACKAGE_DIRECTORY_MATCH
- PACKAGE_VERSION_SUFFIX
- RPC_RESPONSE_STANDARD_NAME
- RPC_REQUEST_STANDARD_NAME
- RPC_REQUEST_RESPONSE_UNIQUE
ignore_only:
# For C++ compatibility, enums in the same package can not have the same enum value names
# This is mostly not an issue, since the values are mostly unique within a package, except for:
# the unknown/unspecified zeroth enum value.
# We should start making those unique.
ENUM_ZERO_VALUE_SUFFIX:
- assignment.proto
- base.proto
- easypulse.proto
- event.proto
- export.proto
- field.proto
- field_service.proto
- integration_mqtt.proto
- integration_slack.proto
- map.proto
- message.proto
- modem.proto
- modem_alarm.proto
- modem_message_body_parser.proto
- modem_message_downlink.proto
- modem_transfer.proto
- organization.proto
- permission.proto
- publisher.proto
- subscription.proto
- unit_preferences_service.proto
- user.proto
- value.proto
- value_service.proto
- webhook.proto
# The sort enum is unique in its own right and doesn't need a suffix.
- device_service.proto
6 changes: 6 additions & 0 deletions currentuser.proto
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,12 @@ message CurrentUser {
/* Permissions for the user. If this is a token, the user permissions may be limited. */
Filter.UserPermissions user_permissions = 10;

/* Permissions for customer support.
* Used for features typically reserved for customer support, or that behave differently
* when used by a customer support operator.
*/
Filter.SupportPermissions support_permissions = 14;

string mission_control_settings = 11;

/* Whether the user accepted the terms and conditions. */
Expand Down
Loading

0 comments on commit 91b92a4

Please sign in to comment.