diff options
author | Michael DÜrre <michael.duerre@highstreet-technologies.com> | 2021-04-08 06:34:22 +0200 |
---|---|---|
committer | Michael DÜrre <michael.duerre@highstreet-technologies.com> | 2021-04-08 06:34:46 +0200 |
commit | f3969004c6ccac18e742c5fc48c844e315991023 (patch) | |
tree | f5486a62e842bb16ca7d3af47a8663df08feef55 /sdnr/wt/websocketmanager/model/src/main | |
parent | a252be83694ae33260d99d5371ed48c1558aa2e8 (diff) |
update websocketmanager
update complete notification flow
Issue-ID: CCSDK-3252
Signed-off-by: Michael DÜrre <michael.duerre@highstreet-technologies.com>
Change-Id: I87ba00f615707b942471fcace57bcda50ce37e61
Diffstat (limited to 'sdnr/wt/websocketmanager/model/src/main')
8 files changed, 764 insertions, 0 deletions
diff --git a/sdnr/wt/websocketmanager/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/websocketmanager/model/WebsocketManagerService.java b/sdnr/wt/websocketmanager/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/websocketmanager/model/WebsocketManagerService.java new file mode 100644 index 000000000..bfceb373e --- /dev/null +++ b/sdnr/wt/websocketmanager/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/websocketmanager/model/WebsocketManagerService.java @@ -0,0 +1,88 @@ +package org.onap.ccsdk.features.sdnr.wt.websocketmanager.model; + +import org.opendaylight.mdsal.dom.api.DOMNotification; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime; +import org.opendaylight.yangtools.yang.binding.Notification; +import org.opendaylight.yangtools.yang.common.QName; + +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property. + * All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + * + */ +/** + * + * outgoing message will be wrapped into container: + * <pre> + * {@code + * <notification> + * <eventTime>2017-07-12T12:00:00.0Z</eventTime> + * <problem-notification xmlns="urn:onf:params:xml:ns:yang:microwave-model"> + * <problem>signalIsLostMinor</problem> + * <object-id-ref>LP-MWPS-RADIO</object-id-ref> + * <severity>non-alarmed</severity> + * <counter>$COUNTER</counter> + * <time-stamp>$TIME</time-stamp> + * </problem-notification> + * <node-id>ROADM-A</node-id> + * <eventType></eventType> + * </notification> + * } + * </pre> + * @author jack + * + */ +public interface WebsocketManagerService { + + /** + * Send notification via Websocket to the connected clients. + * eventTime is extracted out of notification if {@link #EventInstantAware } is implemented + * @param notification + * @param nodeId + * @param eventType + */ + void sendNotification(Notification notification, String nodeId, QName eventType); + /** + * Send notification via Websocket to the connected clients. + * @param notification + * @param nodeId + * @param eventType + * @param eventTime + */ + void sendNotification(Notification notification, String nodeId, QName eventType, DateAndTime eventTime); + + /** + * Send notification via Websocket to the connected clients. + * @param notification + * @param nodeId + * @param eventType + */ + void sendNotification(DOMNotification notification, String nodeId, QName eventType); + /** + * Send notification via Websocket to the connected clients. + * @param notification + * @param nodeId + * @param eventType + * @param eventTime + */ + void sendNotification(DOMNotification notification, String nodeId, QName eventType, DateAndTime eventTime); + + + +} diff --git a/sdnr/wt/websocketmanager/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/websocketmanager/model/data/NotificationOutput.java b/sdnr/wt/websocketmanager/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/websocketmanager/model/data/NotificationOutput.java new file mode 100644 index 000000000..5b966ef1e --- /dev/null +++ b/sdnr/wt/websocketmanager/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/websocketmanager/model/data/NotificationOutput.java @@ -0,0 +1,79 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property. + * All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + * + */ +package org.onap.ccsdk.features.sdnr.wt.websocketmanager.model.data; + +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.DateAndTime; +import org.opendaylight.yangtools.yang.binding.Notification; +import org.opendaylight.yangtools.yang.common.QName; + +public class NotificationOutput { + + private DateAndTime eventTime; + private Notification data; + private String nodeId; + private ReducedSchemaInfo type; + + + public NotificationOutput() { + + } + + public DateAndTime getEventTime() { + return eventTime; + } + + public void setEventTime(DateAndTime eventTime) { + this.eventTime = eventTime; + } + + public Notification getData() { + return data; + } + + public String getNodeId() { + return this.nodeId; + } + + public ReducedSchemaInfo getType() { + return this.type; + } + + public void setData(Notification data) { + this.data = data; + } + + public void setNodeId(String nodeId) { + this.nodeId = nodeId; + } + + public void setType(ReducedSchemaInfo type) { + this.type = type; + } + + public NotificationOutput(Notification notification, String nodeId, QName type, DateAndTime eventTime) { + this.data = notification; + this.nodeId = nodeId; + this.eventTime = eventTime; + this.type = new ReducedSchemaInfo(type); + } + +} diff --git a/sdnr/wt/websocketmanager/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/websocketmanager/model/data/ReducedSchemaInfo.java b/sdnr/wt/websocketmanager/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/websocketmanager/model/data/ReducedSchemaInfo.java new file mode 100644 index 000000000..f6e6c5d0d --- /dev/null +++ b/sdnr/wt/websocketmanager/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/websocketmanager/model/data/ReducedSchemaInfo.java @@ -0,0 +1,72 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2021 highstreet technologies GmbH Intellectual Property. + * All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + * + */ +package org.onap.ccsdk.features.sdnr.wt.websocketmanager.model.data; + +import org.opendaylight.yangtools.yang.common.QName; + +public class ReducedSchemaInfo { + private String namespace; + private String revision; + private String type; + + public ReducedSchemaInfo() {} + + + + public ReducedSchemaInfo(QName qname) { + this.namespace = qname.getNamespace().toString(); + this.revision = qname.getRevision().isPresent() ? qname.getRevision().get().toString() : null; + this.type = qname.getLocalName(); + } + + public boolean equals(QName obj) { + return this.namespace.equals(obj.getNamespace().toString()) && this.type.equals(obj.getLocalName()) + && ((this.revision == null && obj.getRevision().isEmpty()) + || (this.revision.equals(obj.getRevision().get().toString()))); + } + + public String getNamespace() { + return namespace; + } + + public void setNamespace(String namespace) { + this.namespace = namespace; + } + + public String getRevision() { + return revision; + } + + public void setRevision(String revision) { + this.revision = revision; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + +} diff --git a/sdnr/wt/websocketmanager/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/websocketmanager/model/data/SchemaInfo.java b/sdnr/wt/websocketmanager/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/websocketmanager/model/data/SchemaInfo.java new file mode 100644 index 000000000..c587a7997 --- /dev/null +++ b/sdnr/wt/websocketmanager/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/websocketmanager/model/data/SchemaInfo.java @@ -0,0 +1,132 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2021 highstreet technologies GmbH Intellectual Property. + * All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + * + */ +package org.onap.ccsdk.features.sdnr.wt.websocketmanager.model.data; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import java.util.ArrayList; +import java.util.List; +import org.opendaylight.yangtools.yang.common.QName; + +public class SchemaInfo { + private String namespace; + private String revision; + private List<String> notification; + + public SchemaInfo() {} + + + + public SchemaInfo(QName qname) { + this.namespace = qname.getNamespace().toString(); + this.revision = qname.getRevision().isPresent() ? qname.getRevision().get().toString() : null; + this.notification = new ArrayList<>(); + this.notification.add(qname.getLocalName()); + } + + public String getNamespace() { + return namespace; + } + + public void setNamespace(String namespace) { + this.namespace = namespace; + } + + public String getRevision() { + return revision; + } + + public void setRevision(String revision) { + this.revision = revision; + } + + public List<String> getNotification() { + return notification; + } + + public void setNotification(List<String> notification) { + this.notification = notification; + } + + @JsonIgnore + public boolean isValid() { + return this.namespace != null + && (this.notification == null || (this.notification != null && this.notification.size() > 0)); + } + + /** + * Check if schema(qname based info of notification) matches into this scope + * @param schema + * @return + */ + @JsonIgnore + public boolean matches(ReducedSchemaInfo schema) { + //if namespace is * placeholder => true + if (this.namespace.equals("*")) { + return true; + } + //if namespace does not match => false + if (!this.namespace.equals(schema.getNamespace().toString())) { + return false; + } + //if revision of scope is set and it does not match => false + if (this.revision != null && !this.revision.equals(schema.getRevision())){ + return false; + } + //if notification of scope is set and is current notification is not in the list + if (this.notification != null && !this.notification.contains(schema.getType())) { + return false; + } + return true; + } + + @JsonIgnore + public boolean equalsNamespaceAndRevision(QName qname) { + if (this.namespace == null) { + return false; + } + if (!this.namespace.equals(qname.getNamespace().toString())) { + return false; + } + if (this.revision == null && qname.getRevision().isEmpty()) { + return true; + } + if (this.revision != null) { + return this.revision.equals(qname.getRevision().isEmpty() ? null : qname.getRevision().get().toString()); + } + return false; + } + + @JsonIgnore + public void addNotification(String notification) { + if(this.notification ==null) { + this.notification = new ArrayList<>(); + } + this.notification.add(notification); + } + + @Override + public String toString() { + return "SchemaInfo [namespace=" + namespace + ", revision=" + revision + ", notification=" + notification + "]"; + } + + +} diff --git a/sdnr/wt/websocketmanager/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/websocketmanager/model/data/Scope.java b/sdnr/wt/websocketmanager/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/websocketmanager/model/data/Scope.java new file mode 100644 index 000000000..b30aed1a6 --- /dev/null +++ b/sdnr/wt/websocketmanager/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/websocketmanager/model/data/Scope.java @@ -0,0 +1,132 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property. + * All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + * + */ +package org.onap.ccsdk.features.sdnr.wt.websocketmanager.model.data; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import org.opendaylight.yangtools.yang.common.QName; + +public class Scope { + + private String nodeId; + private SchemaInfo schema; + + public String getNodeId() { + return nodeId; + } + + public void setNodeId(String nodeId) { + this.nodeId = nodeId; + } + + public SchemaInfo getSchema() { + return schema; + } + + public void setSchema(SchemaInfo schema) { + this.schema = schema; + } + + @JsonIgnore + public boolean isValid() { + if (this.nodeId == null && this.schema == null) { + return false; + } + if (this.nodeId == null && !this.schema.isValid()) { + return false; + } + return true; + } + + @JsonIgnore + public boolean matches(String nodeId, ReducedSchemaInfo reducedSchemaInfo) { + if (this.nodeId == null) { + return this.schema.matches(reducedSchemaInfo); + } else if (this.schema == null) { + return this.nodeId.equals(nodeId); + } + return this.nodeId.equals(nodeId) && this.schema.matches(reducedSchemaInfo); + + } + + public boolean addQname(QName qname) { + if(this.schema==null) { + this.schema = new SchemaInfo(qname); + return true; + } + if(!this.schema.equalsNamespaceAndRevision(qname)) { + return false; + } + this.schema.addNotification(qname.getLocalName()); + return true; + } + + @Override + public String toString() { + return "Scope [nodeId=" + nodeId + ", schema=" + schema + "]"; + } + + public static Scope create(QName qname) { + return create(null, qname); + } + + public static Scope create(String nodeId, QName qname) { + return create(nodeId, qname == null ? null : new SchemaInfo(qname)); + } + + public static Scope create(String nodeId, SchemaInfo schemaInfo) { + Scope scope = new Scope(); + scope.setNodeId(nodeId); + scope.setSchema(schemaInfo); + return scope; + } + + public static Scope create(String nodeId) { + return create(nodeId, (SchemaInfo) null); + } + + public static List<Scope> createList(List<QName> qnames) { + return createList(null, qnames); + } + + public static List<Scope> createList(String nodeId, List<QName> qnames) { + List<Scope> scopes = new ArrayList<>(); + Optional<Scope> listElem = null; + for (QName qname : qnames) { + listElem = scopes.stream().filter(e -> e.schema != null && e.schema.equalsNamespaceAndRevision(qname)) + .findFirst(); + if (listElem.isPresent()) { + if (!listElem.get().addQname(qname)) { + scopes.add(Scope.create(nodeId, qname)); + } + } else { + scopes.add(Scope.create(nodeId, qname)); + } + } + return scopes; + } + + + +} diff --git a/sdnr/wt/websocketmanager/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/websocketmanager/model/data/ScopeRegistration.java b/sdnr/wt/websocketmanager/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/websocketmanager/model/data/ScopeRegistration.java new file mode 100644 index 000000000..b7295f870 --- /dev/null +++ b/sdnr/wt/websocketmanager/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/websocketmanager/model/data/ScopeRegistration.java @@ -0,0 +1,131 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property. + * All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + * + */ +package org.onap.ccsdk.features.sdnr.wt.websocketmanager.model.data; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Message object for registering for notifications + * + * @author jack + * + */ +public class ScopeRegistration { + + private static final String REGEX_RATIO = "^([\\d]+)\\/(min)$"; + private static final Pattern PATTERN_RATIO = Pattern.compile(REGEX_RATIO); + + @Override + public String toString() { + return "ScopeRegistration [data=" + data + ", scopes=" + scopes + ", ratio=" + ratio + ", isvalid=" + + this.validate() + "]"; + } + + private DataType data; + + public DataType getData() { + return data; + } + + public void setData(DataType data) { + this.data = data; + } + + private void setScopes(List<Scope> scopes) { + this.scopes = scopes; + } + + private List<Scope> scopes; + private String ratio; + + @JsonIgnore + private long rationLong; + + public boolean validate() { + return this.data != null && this.validateScopes(); + } + + private boolean validateScopes() { + if (this.scopes == null) { + return false; + } + for (Scope scope : this.scopes) { + if (!scope.isValid()) { + return false; + } + } + return true; + } + + public boolean isType(DataType type) { + return this.data == type; + } + + public List<Scope> getScopes() { + return this.scopes; + } + + public String getRatio() { + return this.ratio; + } + + @JsonIgnore + public boolean hasRatioLimit() { + return this.ratio != null; + } + + @JsonIgnore + public long getRatioPerMinute() { + return this.rationLong; + } + + public void setRatio(String ratio) { + assertRatioExpression(ratio); + this.ratio = ratio; + } + + private void assertRatioExpression(String ratio) { + final Matcher matcher = PATTERN_RATIO.matcher(ratio); + if (!matcher.find()) { + throw new IllegalArgumentException(ratio + " is not a valid ratio expression"); + } else { + this.rationLong = Long.parseLong(matcher.group(1)); + } + } + + public enum DataType { + scopes; + + + } + + public static ScopeRegistration forNotifications(List<Scope> scopes) { + ScopeRegistration reg = new ScopeRegistration(); + reg.setData(DataType.scopes); + reg.setScopes(scopes); + return reg; + } + +} diff --git a/sdnr/wt/websocketmanager/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/websocketmanager/model/data/ScopeRegistrationResponse.java b/sdnr/wt/websocketmanager/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/websocketmanager/model/data/ScopeRegistrationResponse.java new file mode 100644 index 000000000..88cec46f0 --- /dev/null +++ b/sdnr/wt/websocketmanager/model/src/main/java/org/onap/ccsdk/features/sdnr/wt/websocketmanager/model/data/ScopeRegistrationResponse.java @@ -0,0 +1,79 @@ +/* + * ============LICENSE_START======================================================= + * ONAP : ccsdk features + * ================================================================================ + * Copyright (C) 2020 highstreet technologies GmbH Intellectual Property. + * All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + * + */ +package org.onap.ccsdk.features.sdnr.wt.websocketmanager.model.data; + +import java.util.List; + +public class ScopeRegistrationResponse { + + private Status status; + private String message; + private List<Scope> scopes; + + public ScopeRegistrationResponse() { + + } + + private ScopeRegistrationResponse(Status status, List<Scope> scopes, String message) { + this.status = status; + this.scopes = scopes; + this.message = message; + } + + public Status getStatus() { + return status; + } + + public String getMessage() { + return message; + } + + public Object getScopes() { + return scopes; + } + + public void setStatus(Status status) { + this.status = status; + } + + public void setMessage(String message) { + this.message = message; + } + + public void setScopes(List<Scope> scopes) { + this.scopes = scopes; + } + + + public static ScopeRegistrationResponse error(String message) { + return new ScopeRegistrationResponse(Status.error, null, message); + } + + public static ScopeRegistrationResponse success(List<Scope> scopes) { + return new ScopeRegistrationResponse(Status.success, scopes, null); + } + + public enum Status { + success, error + } + +} diff --git a/sdnr/wt/websocketmanager/model/src/main/yang/websocketmanager.yang b/sdnr/wt/websocketmanager/model/src/main/yang/websocketmanager.yang new file mode 100644 index 000000000..18d7bd27a --- /dev/null +++ b/sdnr/wt/websocketmanager/model/src/main/yang/websocketmanager.yang @@ -0,0 +1,51 @@ +module websocketmanager { + + yang-version 1; + namespace "urn:opendaylight:params:xml:ns:yang:websocketmanager"; + prefix websocketmanager; + + import ietf-yang-types { + prefix yang; + } + organization + "highstreet technologies GmbH"; + contact + "Web: <https://highstreet-technologies.com> + ONAP: <https://wiki.onap.org/display/DW/SDN-R+Websocketmanager+Upgrade>"; + + description + "Websocketmanager Api Module + + Copyright 2021 highstreet technologies GmbH Intellectual Property. + All rights reserved. + + Licensed under the Apache License, Version 2.0 (the 'License'); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an 'AS IS' BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License."; + + revision 2021-03-22 { + description + "Initial revision"; + } + + notification items-dropped-notification { + uses items-dropped-notification-g; + description "none"; + } + grouping items-dropped-notification-g { + leaf amount { + type uint32; + default 0; + description "Counts of notifications that were dropped."; + } + description "To be sent when notifications were dropped in fact of a set ratio limit."; + } +} |