Search in sources :

Example 1 with MonitoredDataItem

use of org.eclipse.milo.opcua.sdk.server.items.MonitoredDataItem in project milo by eclipse.

the class SubscriptionManager method createMonitoredItem.

private BaseMonitoredItem<?> createMonitoredItem(MonitoredItemCreateRequest request, Subscription subscription, TimestampsToReturn timestamps, Map<NodeId, AttributeGroup> attributeGroups) throws UaException {
    NodeId nodeId = request.getItemToMonitor().getNodeId();
    UInteger attributeId = request.getItemToMonitor().getAttributeId();
    QualifiedName dataEncoding = request.getItemToMonitor().getDataEncoding();
    if (!AttributeId.isValid(attributeId)) {
        throw new UaException(StatusCodes.Bad_AttributeIdInvalid);
    }
    if (dataEncoding.isNotNull()) {
        if (!AttributeId.Value.isEqual(attributeId)) {
            throw new UaException(StatusCodes.Bad_DataEncodingInvalid);
        }
        if (!dataEncoding.equals(DEFAULT_BINARY_ENCODING) && !dataEncoding.equals(DEFAULT_XML_ENCODING)) {
            throw new UaException(StatusCodes.Bad_DataEncodingUnsupported);
        }
    }
    AttributeGroup attributeGroup = attributeGroups.get(nodeId);
    if (attributeId.equals(AttributeId.EventNotifier.uid())) {
        UByte eventNotifier = attributeGroup.getEventNotifier();
        // Verify that the SubscribeToEvents bit is set
        if (eventNotifier == null || (eventNotifier.intValue() & 1) == 0) {
            throw new UaException(StatusCodes.Bad_AttributeIdInvalid);
        }
        Object filterObject = request.getRequestedParameters().getFilter().decode(server.getSerializationContext());
        MonitoringFilter filter = validateEventItemFilter(filterObject, attributeGroup);
        UInteger requestedQueueSize = request.getRequestedParameters().getQueueSize();
        AtomicReference<UInteger> revisedQueueSize = new AtomicReference<>(requestedQueueSize);
        try {
            server.getAddressSpaceManager().onCreateEventItem(request.getItemToMonitor(), requestedQueueSize, revisedQueueSize::set);
        } catch (Throwable t) {
            throw new UaException(StatusCodes.Bad_InternalError, t);
        }
        MonitoredEventItem monitoredEventItem = new MonitoredEventItem(server, session, uint(subscription.nextItemId()), subscription.getId(), request.getItemToMonitor(), request.getMonitoringMode(), timestamps, request.getRequestedParameters().getClientHandle(), 0.0, revisedQueueSize.get(), request.getRequestedParameters().getDiscardOldest());
        monitoredEventItem.installFilter(filter);
        return monitoredEventItem;
    } else {
        if (attributeId.equals(AttributeId.Value.uid())) {
            UByte accessLevel = attributeGroup.getAccessLevel();
            if (accessLevel == null)
                accessLevel = ubyte(0);
            UByte userAccessLevel = attributeGroup.getUserAccessLevel();
            if (userAccessLevel == null)
                userAccessLevel = ubyte(0);
            EnumSet<AccessLevel> accessLevels = AccessLevel.fromValue(accessLevel);
            EnumSet<AccessLevel> userAccessLevels = AccessLevel.fromValue(userAccessLevel);
            if (!accessLevels.contains(AccessLevel.CurrentRead)) {
                throw new UaException(StatusCodes.Bad_NotReadable);
            }
            if (!userAccessLevels.contains(AccessLevel.CurrentRead)) {
                throw new UaException(StatusCodes.Bad_UserAccessDenied);
            }
        }
        // Validate the requested index range by parsing it.
        String indexRange = request.getItemToMonitor().getIndexRange();
        if (indexRange != null)
            NumericRange.parse(indexRange);
        Double minimumSamplingInterval = -1.0;
        try {
            minimumSamplingInterval = attributeGroup.getMinimumSamplingInterval();
            if (minimumSamplingInterval == null) {
                minimumSamplingInterval = server.getConfig().getLimits().getMinSupportedSampleRate();
            }
        } catch (UaException e) {
            if (e.getStatusCode().getValue() != StatusCodes.Bad_AttributeIdInvalid) {
                throw e;
            }
        }
        MonitoringFilter filter = MonitoredDataItem.DEFAULT_FILTER;
        try {
            ExtensionObject filterXo = request.getRequestedParameters().getFilter();
            if (filterXo != null && !filterXo.isNull()) {
                Object filterObject = filterXo.decode(server.getSerializationContext());
                filter = validateDataItemFilter(filterObject, attributeId, attributeGroup);
            }
        } catch (UaSerializationException e) {
            logger.debug("error decoding MonitoringFilter", e);
            throw new UaException(StatusCodes.Bad_MonitoredItemFilterInvalid, e);
        }
        double requestedSamplingInterval = getSamplingInterval(subscription, minimumSamplingInterval, request.getRequestedParameters().getSamplingInterval());
        UInteger requestedQueueSize = request.getRequestedParameters().getQueueSize();
        AtomicReference<Double> revisedSamplingInterval = new AtomicReference<>(requestedSamplingInterval);
        AtomicReference<UInteger> revisedQueueSize = new AtomicReference<>(requestedQueueSize);
        try {
            server.getAddressSpaceManager().onCreateDataItem(request.getItemToMonitor(), requestedSamplingInterval, requestedQueueSize, (rsi, rqs) -> {
                revisedSamplingInterval.set(rsi);
                revisedQueueSize.set(rqs);
            });
        } catch (Throwable t) {
            throw new UaException(StatusCodes.Bad_InternalError, t);
        }
        MonitoredDataItem monitoredDataItem = new MonitoredDataItem(server, session, uint(subscription.nextItemId()), subscription.getId(), request.getItemToMonitor(), request.getMonitoringMode(), timestamps, request.getRequestedParameters().getClientHandle(), revisedSamplingInterval.get(), revisedQueueSize.get(), request.getRequestedParameters().getDiscardOldest());
        monitoredDataItem.installFilter(filter);
        return monitoredDataItem;
    }
}
Also used : UaSerializationException(org.eclipse.milo.opcua.stack.core.UaSerializationException) MonitoredEventItem(org.eclipse.milo.opcua.sdk.server.items.MonitoredEventItem) UaException(org.eclipse.milo.opcua.stack.core.UaException) ExtensionObject(org.eclipse.milo.opcua.stack.core.types.builtin.ExtensionObject) QualifiedName(org.eclipse.milo.opcua.stack.core.types.builtin.QualifiedName) AtomicReference(java.util.concurrent.atomic.AtomicReference) MonitoringFilter(org.eclipse.milo.opcua.stack.core.types.structured.MonitoringFilter) AccessLevel(org.eclipse.milo.opcua.sdk.core.AccessLevel) UByte(org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UByte) MonitoredDataItem(org.eclipse.milo.opcua.sdk.server.items.MonitoredDataItem) NodeId(org.eclipse.milo.opcua.stack.core.types.builtin.NodeId) UInteger(org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UInteger) ExtensionObject(org.eclipse.milo.opcua.stack.core.types.builtin.ExtensionObject)

Example 2 with MonitoredDataItem

use of org.eclipse.milo.opcua.sdk.server.items.MonitoredDataItem in project milo by eclipse.

the class DefaultSubscriptionServiceSet method onTransferSubscriptions.

@Override
public void onTransferSubscriptions(ServiceRequest service) throws UaException {
    TransferSubscriptionsRequest request = (TransferSubscriptionsRequest) service.getRequest();
    OpcUaServer server = service.attr(ServiceAttributes.SERVER_KEY).get();
    Session session = service.attr(ServiceAttributes.SESSION_KEY).get();
    List<UInteger> subscriptionIds = l(request.getSubscriptionIds());
    if (subscriptionIds.isEmpty()) {
        throw new UaException(StatusCodes.Bad_NothingToDo);
    }
    List<TransferResult> results = Lists.newArrayList();
    for (UInteger subscriptionId : subscriptionIds) {
        Subscription subscription = server.getSubscriptions().get(subscriptionId);
        if (subscription == null) {
            results.add(new TransferResult(new StatusCode(StatusCodes.Bad_SubscriptionIdInvalid), new UInteger[0]));
        } else {
            Session otherSession = subscription.getSession();
            if (!sessionsHaveSameUser(session, otherSession)) {
                results.add(new TransferResult(new StatusCode(StatusCodes.Bad_UserAccessDenied), new UInteger[0]));
            } else {
                UInteger[] availableSequenceNumbers;
                synchronized (subscription) {
                    otherSession.getSubscriptionManager().sendStatusChangeNotification(subscription, new StatusCode(StatusCodes.Good_SubscriptionTransferred));
                    otherSession.getSubscriptionManager().removeSubscription(subscriptionId);
                    subscription.setSubscriptionManager(session.getSubscriptionManager());
                    subscriptionManager.addSubscription(subscription);
                    subscription.getMonitoredItems().values().forEach(item -> item.setSession(session));
                    availableSequenceNumbers = subscription.getAvailableSequenceNumbers();
                    if (request.getSendInitialValues()) {
                        subscription.getMonitoredItems().values().stream().filter(item -> item instanceof MonitoredDataItem).map(item -> (MonitoredDataItem) item).forEach(MonitoredDataItem::maybeSendLastValue);
                    }
                }
                subscription.getSubscriptionDiagnostics().getTransferRequestCount().increment();
                ApplicationDescription toClient = session.getClientDescription();
                ApplicationDescription fromClient = otherSession.getClientDescription();
                if (Objects.equals(toClient, fromClient)) {
                    subscription.getSubscriptionDiagnostics().getTransferredToSameClientCount().increment();
                } else {
                    subscription.getSubscriptionDiagnostics().getTransferredToAltClientCount().increment();
                }
                results.add(new TransferResult(StatusCode.GOOD, availableSequenceNumbers));
            }
        }
    }
    TransferSubscriptionsResponse response = new TransferSubscriptionsResponse(service.createResponseHeader(), a(results, TransferResult.class), new DiagnosticInfo[0]);
    service.setResponse(response);
}
Also used : StatusCodes(org.eclipse.milo.opcua.stack.core.StatusCodes) MonitoredDataItem(org.eclipse.milo.opcua.sdk.server.items.MonitoredDataItem) UInteger(org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UInteger) Subscription(org.eclipse.milo.opcua.sdk.server.subscriptions.Subscription) TransferResult(org.eclipse.milo.opcua.stack.core.types.structured.TransferResult) TransferSubscriptionsResponse(org.eclipse.milo.opcua.stack.core.types.structured.TransferSubscriptionsResponse) Session(org.eclipse.milo.opcua.sdk.server.Session) OpcUaServer(org.eclipse.milo.opcua.sdk.server.OpcUaServer) ConversionUtil.a(org.eclipse.milo.opcua.stack.core.util.ConversionUtil.a) Objects(java.util.Objects) DiagnosticInfo(org.eclipse.milo.opcua.stack.core.types.builtin.DiagnosticInfo) List(java.util.List) Lists(com.google.common.collect.Lists) ServiceRequest(org.eclipse.milo.opcua.stack.server.services.ServiceRequest) ConversionUtil.l(org.eclipse.milo.opcua.stack.core.util.ConversionUtil.l) StatusCode(org.eclipse.milo.opcua.stack.core.types.builtin.StatusCode) ApplicationDescription(org.eclipse.milo.opcua.stack.core.types.structured.ApplicationDescription) UaException(org.eclipse.milo.opcua.stack.core.UaException) SubscriptionManager(org.eclipse.milo.opcua.sdk.server.subscriptions.SubscriptionManager) SubscriptionServiceSet(org.eclipse.milo.opcua.stack.server.services.SubscriptionServiceSet) TransferSubscriptionsRequest(org.eclipse.milo.opcua.stack.core.types.structured.TransferSubscriptionsRequest) OpcUaServer(org.eclipse.milo.opcua.sdk.server.OpcUaServer) TransferSubscriptionsRequest(org.eclipse.milo.opcua.stack.core.types.structured.TransferSubscriptionsRequest) UaException(org.eclipse.milo.opcua.stack.core.UaException) TransferResult(org.eclipse.milo.opcua.stack.core.types.structured.TransferResult) StatusCode(org.eclipse.milo.opcua.stack.core.types.builtin.StatusCode) ApplicationDescription(org.eclipse.milo.opcua.stack.core.types.structured.ApplicationDescription) MonitoredDataItem(org.eclipse.milo.opcua.sdk.server.items.MonitoredDataItem) UInteger(org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UInteger) TransferSubscriptionsResponse(org.eclipse.milo.opcua.stack.core.types.structured.TransferSubscriptionsResponse) Subscription(org.eclipse.milo.opcua.sdk.server.subscriptions.Subscription) Session(org.eclipse.milo.opcua.sdk.server.Session)

Aggregations

MonitoredDataItem (org.eclipse.milo.opcua.sdk.server.items.MonitoredDataItem)2 UaException (org.eclipse.milo.opcua.stack.core.UaException)2 UInteger (org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UInteger)2 Lists (com.google.common.collect.Lists)1 List (java.util.List)1 Objects (java.util.Objects)1 AtomicReference (java.util.concurrent.atomic.AtomicReference)1 AccessLevel (org.eclipse.milo.opcua.sdk.core.AccessLevel)1 OpcUaServer (org.eclipse.milo.opcua.sdk.server.OpcUaServer)1 Session (org.eclipse.milo.opcua.sdk.server.Session)1 MonitoredEventItem (org.eclipse.milo.opcua.sdk.server.items.MonitoredEventItem)1 Subscription (org.eclipse.milo.opcua.sdk.server.subscriptions.Subscription)1 SubscriptionManager (org.eclipse.milo.opcua.sdk.server.subscriptions.SubscriptionManager)1 StatusCodes (org.eclipse.milo.opcua.stack.core.StatusCodes)1 UaSerializationException (org.eclipse.milo.opcua.stack.core.UaSerializationException)1 DiagnosticInfo (org.eclipse.milo.opcua.stack.core.types.builtin.DiagnosticInfo)1 ExtensionObject (org.eclipse.milo.opcua.stack.core.types.builtin.ExtensionObject)1 NodeId (org.eclipse.milo.opcua.stack.core.types.builtin.NodeId)1 QualifiedName (org.eclipse.milo.opcua.stack.core.types.builtin.QualifiedName)1 StatusCode (org.eclipse.milo.opcua.stack.core.types.builtin.StatusCode)1