Skip to content

Commit

Permalink
refactor: add model when limb connects adaptor
Browse files Browse the repository at this point in the history
- adjust the logic of limb side
- update the design doc

addresses #61
  • Loading branch information
Frank Mai authored and guangbochen committed May 27, 2020
1 parent fb68f6f commit fd24433
Show file tree
Hide file tree
Showing 6 changed files with 159 additions and 81 deletions.
86 changes: 45 additions & 41 deletions docs/adaptors/design_of_adaptor.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,51 +78,55 @@ At the same time, the implementation of adapter can be connected to a single dev
adaptors.edge.cattle.io/modbus
```

Please view [here](./develop.md) for more detail about developing an adaptor.

The access management of adaptors takes inspiration from [Kubernetes Device Plugins management](https://kubernetes.io/docs/concepts/extend-kubernetes/compute-storage-net/device-plugins/). The workflow includes the following steps:

1. The `limb` starts a gRPC service with a Unix socket on host path to receive registration requests from adaptors:

```proto
service Registration {
rpc Register (RegisterRequest) returns (Empty) {}
}
message RegisterRequest {
// Name of the adaptor in the form `adaptor-vendor.com/adaptor-vendor`
string name = 1;
// Version of the API the adaptor was built against
string version = 2;
// Name of the unix socket the adaptor is listening on, it's in the form `*.socket`
string endpoint = 3;
}
```

2. The adaptor starts a gRPC service with a Unix socket under host path `/var/lib/octopus/adaptors`, that implements the following interfaces:

```proto
service Connection {
rpc Connect (stream ConnectRequest) returns (stream ConnectResponse) {}
}
message ConnectRequest {
// Parameters for the connection, it's in form JSON bytes
bytes parameters = 1;
// Desired device, it's in form JSON bytes
bytes device = 2;
}
message ConnectResponse {
// Observed device, it's in form JSON bytes
bytes device = 1;
}
```

3. The adaptor registers itself with the `limb` through the Unix socket at host path `/var/lib/octopus/adaptors/limb.socket`.

4. After successfully registering itself, the adaptor runs in serving mode, during which it keeps connecting devices and reports back to the `limb` upon any device state changes.
1. The `limb` starts a gRPC service with a Unix socket on host path to receive registration requests from adaptors: <a id="registration"></a>
```proto
// Registration is the service advertised by the Limb,
// any adaptor start its service until Limb approved this register request.
service Registration {
rpc Register (RegisterRequest) returns (Empty) {}
}
message RegisterRequest {
// Name of the adaptor in the form `adaptor-vendor.com/adaptor-vendor`.
string name = 1;
// Version of the API the adaptor was built against.
string version = 2;
// Name of the unix socket the adaptor is listening on, it's in the form `*.socket`.
string endpoint = 3;
}
```
1. The adaptor starts a gRPC service with a Unix socket under host path `/var/lib/octopus/adaptors`, that implements the following interfaces: <a id="connection"></a>
```proto
// Connection is the service advertised by the adaptor.
service Connection {
rpc Connect (stream ConnectRequest) returns (stream ConnectResponse) {}
}
message ConnectRequest {
// Parameters for the connection, it's in form JSON bytes.
bytes parameters = 1;
// Model for the device.
k8s.io.apimachinery.pkg.apis.meta.v1.TypeMeta model = 2;
// Desired device, it's in form JSON bytes.
bytes device = 3;
}
message ConnectResponse {
// Observed device, it's in form JSON bytes.
bytes device = 1;
}
```
1. The adaptor registers itself with the `limb` through the Unix socket at host path `/var/lib/octopus/adaptors/limb.socket`.
1. After successfully registering itself, the adaptor runs in serving mode, during which it keeps connecting devices and reports back to the `limb` upon any device state changes.

## Available Adaptor List

- [dummy](../../adaptors/dummy)

- [ble](../../adaptors/ble)
- [modbus](../../adaptors/modbus)
- [opcua](../../adaptors/opcua)
- [mqtt](../../adaptors/mqtt)
124 changes: 96 additions & 28 deletions pkg/adaptor/api/v1alpha1/api.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 10 additions & 7 deletions pkg/adaptor/api/v1alpha1/api.proto
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ syntax = 'proto3';
package v1alpha1;

import "github.com/gogo/protobuf/gogoproto/gogo.proto";
import "k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto";

option (gogoproto.goproto_stringer_all) = false;
option (gogoproto.stringer_all) = true;
Expand All @@ -23,11 +24,11 @@ service Registration {
}

message RegisterRequest {
// Name of the adaptor in the form `adaptor-vendor.com/adaptor-vendor`
// Name of the adaptor in the form `adaptor-vendor.com/adaptor-vendor`.
string name = 1;
// Version of the API the adaptor was built against
// Version of the API the adaptor was built against.
string version = 2;
// Name of the unix socket the adaptor is listening on, it's in the form `*.socket`
// Name of the unix socket the adaptor is listening on, it's in the form `*.socket`.
string endpoint = 3;
}

Expand All @@ -38,13 +39,15 @@ service Connection {
}

message ConnectRequest {
// Parameters for the connection, it's in form JSON bytes
// Parameters for the connection, it's in form JSON bytes.
bytes parameters = 1;
// Desired device, it's in form JSON bytes
bytes device = 2;
// Model for the device.
k8s.io.apimachinery.pkg.apis.meta.v1.TypeMeta model = 2;
// Desired device, it's in form JSON bytes.
bytes device = 3;
}

message ConnectResponse {
// Observed device, it's in form JSON bytes
// Observed device, it's in form JSON bytes.
bytes device = 1;
}
8 changes: 5 additions & 3 deletions pkg/suctioncup/connection/connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"

"google.golang.org/grpc"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"

api "github.com/rancher/octopus/pkg/adaptor/api/v1alpha1"
Expand All @@ -17,8 +18,8 @@ type Connection interface {
// GetName returns the name of connection
GetName() types.NamespacedName

// Send sends the parameters and desired data to connection
Send(parameters, desired []byte) error
// Send sends the parameters, device model and desired data to connection
Send(parameters []byte, model *metav1.TypeMeta, device []byte) error

// Stop stops the connection
Stop() error
Expand Down Expand Up @@ -60,9 +61,10 @@ func (c *connection) Stop() error {
return c.stop()
}

func (c *connection) Send(parameters, device []byte) error {
func (c *connection) Send(parameters []byte, model *metav1.TypeMeta, device []byte) error {
return c.conn.Send(&api.ConnectRequest{
Parameters: parameters,
Model: model,
Device: device,
})
}
Expand Down
3 changes: 2 additions & 1 deletion pkg/suctioncup/neurons.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,5 +55,6 @@ func (m *manager) Send(data *unstructured.Unstructured, by *edgev1alpha1.DeviceL
if err != nil {
return errors.Wrapf(err, "could not marshal data as JSON")
}
return conn.Send(parametersBytes, dataBytes)

return conn.Send(parametersBytes, &by.Status.Model, dataBytes)
}
2 changes: 1 addition & 1 deletion test/integration/limb/devicelink_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,6 @@ func (c fakeDummyConnection) Stop() error {
return nil
}

func (c fakeDummyConnection) Send(parameters, device []byte) error {
func (c fakeDummyConnection) Send(parameters []byte, model *metav1.TypeMeta, desired []byte) error {
return nil
}

0 comments on commit fd24433

Please sign in to comment.