Skip to content

Commit

Permalink
Merge branch 'release-1.116.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
dpoltavets committed Mar 10, 2022
2 parents 53d6b6d + b227a47 commit d2f8309
Show file tree
Hide file tree
Showing 107 changed files with 3,070 additions and 1,636 deletions.
25 changes: 25 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,30 @@
# Changelog

## v1.116.0 (04/03/2022)

### Features:
- [#4698](https://github.com/telstra/open-kilda/pull/4698) Added sync switch on connect toggle [**storm-topologies**]

### Bug Fixes:
- [#4709](https://github.com/telstra/open-kilda/pull/4709) Fix: add inaccurate flag to MeterSpeakerData.
- [#4714](https://github.com/telstra/open-kilda/pull/4714) Fix unmetered bw for noviflow switches
- [#4444](https://github.com/telstra/open-kilda/pull/4444) GRPC: Fixed changing of logical port type (Issues: [#4693](https://github.com/telstra/open-kilda/issues/4693) [#4694](https://github.com/telstra/open-kilda/issues/4694))
- [#4701](https://github.com/telstra/open-kilda/pull/4701) Fix the minimum bandwidth value for the flow
- [#4702](https://github.com/telstra/open-kilda/pull/4702) Fix excess y-flow meters (proper building & handing of DeleteSpeakerCommandsRequest) [**floodlight**]

### Improvements:
- [#4680](https://github.com/telstra/open-kilda/pull/4680) LAG logical port update operation
- [#4699](https://github.com/telstra/open-kilda/pull/4699) Rework events routing inside SwitchManagerHub [**storm-topologies**]
- [#4700](https://github.com/telstra/open-kilda/pull/4700) Ignore leading and trailing spaces in a string for the SwitchId class.


For the complete list of changes, check out [the commit log](https://github.com/telstra/open-kilda/compare/v1.115.2...v1.116.0).

### Affected Components:
flow-monitor, network, grpc, flow-hs, swmanager, fl

---

## v1.115.2 (02/03/2022)

### Improvements:
Expand Down
125 changes: 111 additions & 14 deletions docs/design/LAG-for-ports/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,33 +6,130 @@ Link aggregation provides ability to combine multiple physical connections into

## API

* Get existing LAG logical ports on the switch `GET /v2/switches/{switch_id}/lags`. Response example:
~~~
[
{
"logical_port_number": 2001,
"port_numbers": [1, 2, 3]
},
...
]
Shell variables required by API examples:
~~~shell
nb_host="localhost:8080"
switch_id="00:00:00:00:00:00:00:01"
auth_login="kilda"
auth_password="kilda"
~~~

* Create LAG logical port on the switch `POST /v2/switches/{switch_id}/lags` with body:
### Create new LAG

Request format:

~~~shell
curl -X POST --location "http://${nb_host}/api/v2/switches/${switch_id}/lags" \
-H "accept: */*" \
-H "correlation_id: ${request_id:-dummy_correlation_id}" \
-H "Content-Type: application/json" \
--basic --user "${auth_login}:${auth_password}" \
-d @- << POST_DATA
{ "port_numbers": [ 40, 41 ] }
POST_DATA
~~~

Response example:

~~~json
{
"port_numbers": [1, 2, 3]
"logical_port_number": 2891,
"port_numbers": [
40,
41
]
}
~~~


### Read all LAGs on specific switch

Request format:

~~~shell
curl -X GET --location "http://${nb_host}/api/v2/switches/${switch_id}/lags" \
-H "accept: */*" \
-H "correlation_id: ${request_id:-dummy_correlation_id}" \
--basic --user "${auth_login}:${auth_password}"
~~~

Response example:

~~~json
[
{
"logical_port_number": 2891,
"port_numbers": [
40,
41
]
},
{
"logical_port_number": 2198,
"port_numbers": [
22,
27
]
}
]
~~~


### Update specific LAG on specific switch

Request format:

~~~shell
port_number=2198

curl -X PUT --location "http://${nb_host}/api/v2/switches/${switch_id}/lags/${port_number}" \
-H "accept: */*" \
-H "correlation_id: ${request_id:-dummy_correlation_id}" \
-H "Content-Type: application/json" \
--basic --user "${auth_login}:${auth_password}" \
-d @- << PUT_DATA
{ "port_numbers": [ 35, 36 ] }
PUT_DATA
~~~

Response example:

~~~json
{
"logical_port_number": 2001,
"port_numbers": [1, 2, 3]
"logical_port_number": 2198,
"port_numbers": [
35,
36
]
}
~~~

* Delete LAG logical port on the switch `DELETE /v2/switches/{switch_id}/lags/{logical_port_number}`.

### Delete specific LAG on specific switch

Request format:

~~~shell
port_number=2198

curl -X DELETE --location "http://${nb_host}/api/v2/switches/${switch_id}/lags/${port_number}" \
-H "accept: */*" \
-H "correlation_id: ${request_id:-dummy_correlation_id}" \
-H "Content-Type: application/json" \
--basic --user "${auth_login}:${auth_password}"
~~~

Response example:

~~~json
{
"logical_port_number": 2198,
"port_numbers": [
35,
36
]
}
~~~

## Details
All logical port related commands are sent to the switches using gRPC speaker.
Expand Down
95 changes: 95 additions & 0 deletions docs/design/messaging/message-cookie.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# Message cookie

## Concept
The goal of this approach is to be able to route response into specific handler (the handler that have produced request)
into specific service into specific application/storm-bolt.

The message producer must include into the message info unambiguously describing the sender (into hierarchical manner) -
the message cookie object. Message recipient must produce response and copy message cookie from request. So the only
task for message recipient in this approach is to copy message cookie from request into response.

Message cookie hierarchy represent/mirror code hierarchy that produce this cookie - for example, from innermost to
outermost layers: `unique-request-id => unique-handler-id => service-id`. During message producing each code layer must
add corresponding cookie layer.

Message cookie must be placed into message envelope (`BaseMessage` and inheritors in our terminology). It will simplify
its copying on recipient side - message cookie will not be passed into code that handle request itself but copied on the
level responsible for message decoding/encoding. At same time on request producer side, carrier decorators can add
extra message cookie layers during delivering message payload into message ejecting level without any interaction with
message payload object.

Keeping all dispatch info into request/response objects relief from keeping it somewhere on request side and as result
no need to track it for invalidation and obsolescence.

![route trip time sequence diagram](message-round-trip.png)

## Wrapping process

Cookie wrapping or layer adding process can be done by carrier(objects responsible for communication with transport layer)
decorators. I.e. application produce service and provide carrier object decorated with object that will add service
name cookie layer to each produced requests.

For example, we have an interface defining some carrier that will be used by service and by handlers inside service:

```java
public interface SomeCarrier {
void sendCommandToSpeaker(CommandData command, @NonNull MessageCookie cookie);
}
```

We can define a decorator that adds some cookie layer during request to the `sendSpeakerCommand`.

```java
public class SomeCarrierDecorator implements SomeCarrier {
private final SomeCarrier target;
private final String layerValue;

public SomeCarrierDecorator(SomeCarrier target, String layerValue) {
this.target = target;
this.layerValue = layerValue;
}

public void sendCommandToSpeaker(CommandData command, @NonNull MessageCookie cookie) {
target.sendCommandToSpeaker(command, new MessageCookie(layerValue, cookie));
}
}
```

And on application init we will create service in this way:

```java
public class App {
Map<Sting, ServiceBase> services = new Map<>();

public void init() {
SomeService someService = new SomeService(new SomeCarrierDecorator(carrier, "some_service_name"));
serivces.put("some_service_name", someService);
}
}
```

So on response we can locate required service in this way:

```java
public class App {
Map<Sting, ServiceBase> services = new Map<>();

public void dispatch(MessageData payload, MessageCookie cookie) {
ServiceBase service = services.get(cookie.getValue());
if (service != null) {
service.dispatch(payload, cookie.getNested());
} else {
log.error("dispatch error");
}
}
}
```

Service itself can add one more decorator to the carrier, responsible for adding handler unique id cookie layer. And
dispatching can be continued inside service. So each code layer process it's own message cookie layer and fully control
the meaning of cookie value (on specific layer).

## Some possible tooling improvements

`MessageCookie` can define equals/hash methods that do not take into account value of nested field/cookie. In this case
cookie object itself can be used as `Map` key during dispatch.
Binary file added docs/design/messaging/message-round-trip.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
52 changes: 52 additions & 0 deletions docs/design/messaging/message-round-trip.puml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
@startuml
title message round trip

collections handler
collections service
participant application
participant transport
participant remote
collections remote_handler

activate handler
handler -> handler : produce message payload\nand message cookie\nwith unique request id\n[payload, cookie[0]]
handler -> service : [payload, cookie[0]]
deactivate handler
service -> application : add handler-id layer\n[payload, cookie[1]]
application -> transport : add service name layer\n[payload, cookie[2]]

activate transport
transport -> transport : [payload, cookie[2]] => [request_message]
transport -> remote: [request_message]
deactivate transport

activate remote
remote -> remote : [request_message] => [payload, cookie[2]]
remote -> remote_handler : [payload]
activate remote_handler
remote_handler -> remote : [response]
deactivate remote_handler
remote -> remote : response + cookie[2] => [response_message]
remote -> transport : [response_message]
deactivate remote

activate transport
transport -> transport : [response_message] => [response, cookie[2]]
transport -> application : [response, cookie[2]]
deactivate transport

activate application
application -> application : select service by cookie[2]\nunwrap
application -> service : [response, cookie[1]]
deactivate application

activate service
service -> service : select handler by cookie[1]\nunwrap
service -> handler : [response, cookie[0]]
deactivate service

activate handler
handler -> handler : identify request by cookie[0]\nhandle response
deactivate handler

@enduml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;

/**
* Class represents high level view of every message used by any service.
Expand All @@ -47,31 +49,41 @@ public class Message extends BaseMessage {
@JsonProperty(DESTINATION)
protected Destination destination;

@Getter
@Setter
@JsonProperty("cookie")
protected MessageCookie cookie;

/**
* Instance constructor.
*
* @param timestamp message timestamp
* @param correlationId message correlation id
* @param destination message destination
*/
@JsonCreator
public Message(@JsonProperty(TIMESTAMP) final long timestamp,
@JsonProperty(CORRELATION_ID) final String correlationId,
@JsonProperty(DESTINATION) final Destination destination) {
super(timestamp);
this.correlationId = correlationId;
this.destination = destination;
public Message(final long timestamp, final String correlationId) {
this(timestamp, correlationId, null);
}

public Message(final long timestamp, final String correlationId, MessageCookie cookie) {
this(timestamp, correlationId, null, cookie);
}

/**
* Instance constructor.
*
* @param timestamp message timestamp
* @param correlationId message correlation id
* @param destination message destination
*/
public Message(final long timestamp, final String correlationId) {
@JsonCreator
public Message(@JsonProperty(TIMESTAMP) final long timestamp,
@JsonProperty(CORRELATION_ID) final String correlationId,
@JsonProperty(DESTINATION) final Destination destination,
@JsonProperty("cookie") MessageCookie cookie) {
super(timestamp);
this.correlationId = correlationId;
this.destination = destination;
this.cookie = cookie;
}

/**
Expand Down Expand Up @@ -109,6 +121,7 @@ public String toString() {
return toStringHelper(this)
.add(TIMESTAMP, timestamp)
.add(CORRELATION_ID, correlationId)
.add("cookie", cookie)
.add(DESTINATION, destination)
.toString();
}
Expand Down
Loading

0 comments on commit d2f8309

Please sign in to comment.