Search in sources :

Example 1 with MonitoredItemNotification

use of org.eclipse.milo.opcua.stack.core.types.structured.MonitoredItemNotification in project milo by eclipse.

the class OpcUaSubscriptionManager method deliverNotificationMessage.

private CompletableFuture<Unit> deliverNotificationMessage(OpcUaSubscription subscription, NotificationMessage notificationMessage) {
    CompletableFuture<Unit> delivered = new CompletableFuture<>();
    subscription.getNotificationSemaphore().acquire().thenAccept(permit -> deliveryQueue.submit(() -> {
        try {
            Map<UInteger, OpcUaMonitoredItem> items = subscription.getItemsByClientHandle();
            List<ExtensionObject> notificationData = l(notificationMessage.getNotificationData());
            if (notificationData.isEmpty()) {
                subscriptionListeners.forEach(listener -> listener.onKeepAlive(subscription, notificationMessage.getPublishTime()));
                subscription.getNotificationListeners().forEach(listener -> listener.onKeepAliveNotification(subscription, notificationMessage.getPublishTime()));
            }
            for (ExtensionObject xo : notificationData) {
                Object o = xo.decode(client.getStaticSerializationContext());
                if (o instanceof DataChangeNotification) {
                    DataChangeNotification dcn = (DataChangeNotification) o;
                    List<MonitoredItemNotification> monitoredItemNotifications = l(dcn.getMonitoredItems());
                    int notificationCount = monitoredItemNotifications.size();
                    logger.debug("Received {} MonitoredItemNotifications", notificationCount);
                    for (MonitoredItemNotification min : monitoredItemNotifications) {
                        logger.trace("MonitoredItemNotification: clientHandle={}, value={}", min.getClientHandle(), min.getValue());
                        OpcUaMonitoredItem item = items.get(min.getClientHandle());
                        if (item != null)
                            item.onValueArrived(min.getValue());
                        else
                            logger.warn("no item for clientHandle=" + min.getClientHandle());
                    }
                    if (notificationCount == 0) {
                        subscriptionListeners.forEach(listener -> listener.onKeepAlive(subscription, notificationMessage.getPublishTime()));
                        subscription.getNotificationListeners().forEach(listener -> listener.onKeepAliveNotification(subscription, notificationMessage.getPublishTime()));
                    } else {
                        if (!subscription.getNotificationListeners().isEmpty()) {
                            List<UaMonitoredItem> monitoredItems = new ArrayList<>();
                            List<DataValue> dataValues = new ArrayList<>();
                            for (MonitoredItemNotification n : monitoredItemNotifications) {
                                UaMonitoredItem item = subscription.getItemsByClientHandle().get(n.getClientHandle());
                                if (item != null) {
                                    monitoredItems.add(item);
                                    dataValues.add(n.getValue());
                                }
                            }
                            subscription.getNotificationListeners().forEach(listener -> listener.onDataChangeNotification(subscription, monitoredItems, dataValues, notificationMessage.getPublishTime()));
                        }
                    }
                } else if (o instanceof EventNotificationList) {
                    EventNotificationList enl = (EventNotificationList) o;
                    List<EventFieldList> eventFieldLists = l(enl.getEvents());
                    for (EventFieldList efl : eventFieldLists) {
                        logger.trace("EventFieldList: clientHandle={}, values={}", efl.getClientHandle(), Arrays.toString(efl.getEventFields()));
                        OpcUaMonitoredItem item = items.get(efl.getClientHandle());
                        if (item != null)
                            item.onEventArrived(efl.getEventFields());
                    }
                    if (!subscription.getNotificationListeners().isEmpty()) {
                        List<UaMonitoredItem> monitoredItems = new ArrayList<>();
                        List<Variant[]> eventFields = new ArrayList<>();
                        for (EventFieldList efl : eventFieldLists) {
                            UaMonitoredItem item = subscription.getItemsByClientHandle().get(efl.getClientHandle());
                            if (item != null) {
                                monitoredItems.add(item);
                                eventFields.add(efl.getEventFields());
                            }
                        }
                        subscription.getNotificationListeners().forEach(listener -> listener.onEventNotification(subscription, monitoredItems, eventFields, notificationMessage.getPublishTime()));
                    }
                } else if (o instanceof StatusChangeNotification) {
                    StatusChangeNotification scn = (StatusChangeNotification) o;
                    logger.debug("StatusChangeNotification: {}", scn.getStatus());
                    subscriptionListeners.forEach(listener -> listener.onStatusChanged(subscription, scn.getStatus()));
                    subscription.getNotificationListeners().forEach(listener -> listener.onStatusChangedNotification(subscription, scn.getStatus()));
                    if (scn.getStatus().getValue() == StatusCodes.Bad_Timeout) {
                        subscriptions.remove(subscription.getSubscriptionId());
                    }
                }
            }
        } finally {
            permit.release();
            delivered.complete(Unit.VALUE);
        }
    }));
    return delivered;
}
Also used : Arrays(java.util.Arrays) ScheduledFuture(java.util.concurrent.ScheduledFuture) BiFunction(java.util.function.BiFunction) CompletableFuture.completedFuture(java.util.concurrent.CompletableFuture.completedFuture) UaSubscriptionManager(org.eclipse.milo.opcua.sdk.client.api.subscriptions.UaSubscriptionManager) LoggerFactory(org.slf4j.LoggerFactory) ExtensionObject(org.eclipse.milo.opcua.stack.core.types.builtin.ExtensionObject) PublishRequest(org.eclipse.milo.opcua.stack.core.types.structured.PublishRequest) DateTime(org.eclipse.milo.opcua.stack.core.types.builtin.DateTime) Unsigned.uint(org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.Unsigned.uint) UaSubscription(org.eclipse.milo.opcua.sdk.client.api.subscriptions.UaSubscription) Unit(org.eclipse.milo.opcua.stack.core.util.Unit) Map(java.util.Map) BigInteger(java.math.BigInteger) CreateSubscriptionResponse(org.eclipse.milo.opcua.stack.core.types.structured.CreateSubscriptionResponse) NodeId(org.eclipse.milo.opcua.stack.core.types.builtin.NodeId) UByte(org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UByte) EventNotificationList(org.eclipse.milo.opcua.stack.core.types.structured.EventNotificationList) RepublishResponse(org.eclipse.milo.opcua.stack.core.types.structured.RepublishResponse) SubscriptionAcknowledgement(org.eclipse.milo.opcua.stack.core.types.structured.SubscriptionAcknowledgement) List(java.util.List) Lists.newArrayList(com.google.common.collect.Lists.newArrayList) Variant(org.eclipse.milo.opcua.stack.core.types.builtin.Variant) EventFieldList(org.eclipse.milo.opcua.stack.core.types.structured.EventFieldList) StatusCode(org.eclipse.milo.opcua.stack.core.types.builtin.StatusCode) UaSession(org.eclipse.milo.opcua.sdk.client.api.UaSession) DataValue(org.eclipse.milo.opcua.stack.core.types.builtin.DataValue) OpcUaClient(org.eclipse.milo.opcua.sdk.client.OpcUaClient) NotificationMessage(org.eclipse.milo.opcua.stack.core.types.structured.NotificationMessage) CompletableFuture(java.util.concurrent.CompletableFuture) DataChangeNotification(org.eclipse.milo.opcua.stack.core.types.structured.DataChangeNotification) AtomicReference(java.util.concurrent.atomic.AtomicReference) Function(java.util.function.Function) ArrayList(java.util.ArrayList) ConcurrentMap(java.util.concurrent.ConcurrentMap) RequestHeader(org.eclipse.milo.opcua.stack.core.types.structured.RequestHeader) Lists(com.google.common.collect.Lists) ImmutableList(com.google.common.collect.ImmutableList) ConversionUtil.l(org.eclipse.milo.opcua.stack.core.util.ConversionUtil.l) UaMonitoredItem(org.eclipse.milo.opcua.sdk.client.api.subscriptions.UaMonitoredItem) StatusCodes(org.eclipse.milo.opcua.stack.core.StatusCodes) FutureUtils.failedUaFuture(org.eclipse.milo.opcua.stack.core.util.FutureUtils.failedUaFuture) SessionActivityListener(org.eclipse.milo.opcua.sdk.client.SessionActivityListener) StatusChangeNotification(org.eclipse.milo.opcua.stack.core.types.structured.StatusChangeNotification) ExecutionQueue(org.eclipse.milo.opcua.stack.core.util.ExecutionQueue) Logger(org.slf4j.Logger) MonitoredItemNotification(org.eclipse.milo.opcua.stack.core.types.structured.MonitoredItemNotification) PublishResponse(org.eclipse.milo.opcua.stack.core.types.structured.PublishResponse) UInteger(org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UInteger) Maps(com.google.common.collect.Maps) TimeUnit(java.util.concurrent.TimeUnit) AtomicLong(java.util.concurrent.atomic.AtomicLong) ModifySubscriptionResponse(org.eclipse.milo.opcua.stack.core.types.structured.ModifySubscriptionResponse) UaException(org.eclipse.milo.opcua.stack.core.UaException) Comparator(java.util.Comparator) Collections(java.util.Collections) UaMonitoredItem(org.eclipse.milo.opcua.sdk.client.api.subscriptions.UaMonitoredItem) MonitoredItemNotification(org.eclipse.milo.opcua.stack.core.types.structured.MonitoredItemNotification) EventNotificationList(org.eclipse.milo.opcua.stack.core.types.structured.EventNotificationList) ExtensionObject(org.eclipse.milo.opcua.stack.core.types.builtin.ExtensionObject) Lists.newArrayList(com.google.common.collect.Lists.newArrayList) ArrayList(java.util.ArrayList) DataChangeNotification(org.eclipse.milo.opcua.stack.core.types.structured.DataChangeNotification) StatusChangeNotification(org.eclipse.milo.opcua.stack.core.types.structured.StatusChangeNotification) Unit(org.eclipse.milo.opcua.stack.core.util.Unit) TimeUnit(java.util.concurrent.TimeUnit) CompletableFuture(java.util.concurrent.CompletableFuture) EventFieldList(org.eclipse.milo.opcua.stack.core.types.structured.EventFieldList) EventNotificationList(org.eclipse.milo.opcua.stack.core.types.structured.EventNotificationList) List(java.util.List) Lists.newArrayList(com.google.common.collect.Lists.newArrayList) EventFieldList(org.eclipse.milo.opcua.stack.core.types.structured.EventFieldList) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList) ExtensionObject(org.eclipse.milo.opcua.stack.core.types.builtin.ExtensionObject) Map(java.util.Map) ConcurrentMap(java.util.concurrent.ConcurrentMap)

Example 2 with MonitoredItemNotification

use of org.eclipse.milo.opcua.stack.core.types.structured.MonitoredItemNotification in project milo by eclipse.

the class Subscription method sendNotifications.

private void sendNotifications(ServiceRequest service, List<UaStructure> notifications) {
    List<MonitoredItemNotification> dataNotifications = Lists.newArrayList();
    List<EventFieldList> eventNotifications = Lists.newArrayList();
    notifications.forEach(notification -> {
        if (notification instanceof MonitoredItemNotification) {
            dataNotifications.add((MonitoredItemNotification) notification);
        } else if (notification instanceof EventFieldList) {
            eventNotifications.add((EventFieldList) notification);
        }
    });
    List<ExtensionObject> notificationData = Lists.newArrayList();
    if (dataNotifications.size() > 0) {
        DataChangeNotification dataChange = new DataChangeNotification(dataNotifications.toArray(new MonitoredItemNotification[0]), new DiagnosticInfo[0]);
        notificationData.add(ExtensionObject.encode(serializationContext, dataChange, dataChange.getBinaryEncodingId(), OpcUaDefaultBinaryEncoding.getInstance()));
        subscriptionDiagnostics.getDataChangeNotificationsCount().add(dataNotifications.size());
    }
    if (eventNotifications.size() > 0) {
        EventNotificationList eventChange = new EventNotificationList(eventNotifications.toArray(new EventFieldList[0]));
        notificationData.add(ExtensionObject.encode(serializationContext, eventChange, eventChange.getBinaryEncodingId(), OpcUaDefaultBinaryEncoding.getInstance()));
        subscriptionDiagnostics.getEventNotificationsCount().add(eventNotifications.size());
    }
    subscriptionDiagnostics.getNotificationsCount().add(notificationData.size());
    UInteger sequenceNumber = uint(nextSequenceNumber());
    NotificationMessage notificationMessage = new NotificationMessage(sequenceNumber, DateTime.now(), notificationData.toArray(new ExtensionObject[0]));
    availableMessages.put(notificationMessage.getSequenceNumber(), notificationMessage);
    while (availableMessages.size() > MAX_AVAILABLE_MESSAGES) {
        Map.Entry<UInteger, NotificationMessage> entry = availableMessages.pollFirstEntry();
        if (entry != null) {
            subscriptionDiagnostics.getDiscardedMessageCount().increment();
            logger.debug("Discarded cached NotificationMessage with sequenceNumber={}", entry.getKey());
        }
    }
    UInteger[] available = getAvailableSequenceNumbers();
    StatusCode[] acknowledgeResults = service.attr(KEY_ACK_RESULTS).get();
    ResponseHeader header = service.createResponseHeader();
    PublishResponse response = new PublishResponse(header, subscriptionId, available, moreNotifications, notificationMessage, acknowledgeResults, new DiagnosticInfo[0]);
    service.setResponse(response);
    logger.debug("[id={}] returning {} DataChangeNotification(s) and " + "{} EventNotificationList(s) sequenceNumber={} moreNotifications={}.", subscriptionId, dataNotifications.size(), eventNotifications.size(), sequenceNumber, moreNotifications);
}
Also used : MonitoredItemNotification(org.eclipse.milo.opcua.stack.core.types.structured.MonitoredItemNotification) EventNotificationList(org.eclipse.milo.opcua.stack.core.types.structured.EventNotificationList) PublishResponse(org.eclipse.milo.opcua.stack.core.types.structured.PublishResponse) ResponseHeader(org.eclipse.milo.opcua.stack.core.types.structured.ResponseHeader) ExtensionObject(org.eclipse.milo.opcua.stack.core.types.builtin.ExtensionObject) DataChangeNotification(org.eclipse.milo.opcua.stack.core.types.structured.DataChangeNotification) StatusCode(org.eclipse.milo.opcua.stack.core.types.builtin.StatusCode) NotificationMessage(org.eclipse.milo.opcua.stack.core.types.structured.NotificationMessage) EventFieldList(org.eclipse.milo.opcua.stack.core.types.structured.EventFieldList) UInteger(org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UInteger) Map(java.util.Map) ConcurrentSkipListMap(java.util.concurrent.ConcurrentSkipListMap)

Example 3 with MonitoredItemNotification

use of org.eclipse.milo.opcua.stack.core.types.structured.MonitoredItemNotification in project milo by eclipse.

the class MonitoredDataItem method wrapQueueValue.

@Override
protected MonitoredItemNotification wrapQueueValue(DataValue value) {
    boolean includeSource = timestamps == TimestampsToReturn.Source || timestamps == TimestampsToReturn.Both;
    boolean includeServer = timestamps == TimestampsToReturn.Server || timestamps == TimestampsToReturn.Both;
    // remove the source timestamp if not requested
    boolean sourceTimeUpdated = false;
    DateTime sourceTime = value.getSourceTime();
    UShort sourcePicoseconds = value.getSourcePicoseconds();
    if (!includeSource && (sourceTime != null || sourcePicoseconds != null)) {
        sourceTime = null;
        sourcePicoseconds = null;
        sourceTimeUpdated = true;
    }
    // remove server timestamp if not requested, add if requested but not present
    boolean serverTimeUpdated = false;
    DateTime serverTime = value.getServerTime();
    UShort serverPicoseconds = value.getServerPicoseconds();
    if (!includeServer && (serverTime != null || serverPicoseconds != null)) {
        serverTime = null;
        serverPicoseconds = null;
        serverTimeUpdated = true;
    } else if (includeServer && serverTime == null) {
        serverTime = DateTime.now();
        serverTimeUpdated = true;
    }
    // create a new DataValue instance if anything changed
    if (sourceTimeUpdated || serverTimeUpdated) {
        value = new DataValue(value.getValue(), value.getStatusCode(), sourceTime, sourcePicoseconds, serverTime, serverPicoseconds);
    }
    return new MonitoredItemNotification(uint(getClientHandle()), value);
}
Also used : MonitoredItemNotification(org.eclipse.milo.opcua.stack.core.types.structured.MonitoredItemNotification) DataValue(org.eclipse.milo.opcua.stack.core.types.builtin.DataValue) UShort(org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UShort) DateTime(org.eclipse.milo.opcua.stack.core.types.builtin.DateTime)

Aggregations

Map (java.util.Map)2 DataValue (org.eclipse.milo.opcua.stack.core.types.builtin.DataValue)2 DateTime (org.eclipse.milo.opcua.stack.core.types.builtin.DateTime)2 ExtensionObject (org.eclipse.milo.opcua.stack.core.types.builtin.ExtensionObject)2 StatusCode (org.eclipse.milo.opcua.stack.core.types.builtin.StatusCode)2 UInteger (org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UInteger)2 DataChangeNotification (org.eclipse.milo.opcua.stack.core.types.structured.DataChangeNotification)2 EventFieldList (org.eclipse.milo.opcua.stack.core.types.structured.EventFieldList)2 MonitoredItemNotification (org.eclipse.milo.opcua.stack.core.types.structured.MonitoredItemNotification)2 ImmutableList (com.google.common.collect.ImmutableList)1 Lists (com.google.common.collect.Lists)1 Lists.newArrayList (com.google.common.collect.Lists.newArrayList)1 Maps (com.google.common.collect.Maps)1 BigInteger (java.math.BigInteger)1 ArrayList (java.util.ArrayList)1 Arrays (java.util.Arrays)1 Collections (java.util.Collections)1 Comparator (java.util.Comparator)1 List (java.util.List)1 CompletableFuture (java.util.concurrent.CompletableFuture)1