Search in sources :

Example 1 with AccessLevel

use of org.eclipse.milo.opcua.sdk.core.AccessLevel 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 AccessLevel

use of org.eclipse.milo.opcua.sdk.core.AccessLevel in project milo by eclipse.

the class AttributeWriter method writeAttribute.

public static void writeAttribute(AttributeContext context, UaServerNode node, AttributeId attributeId, DataValue value, @Nullable String indexRange) throws UaException {
    AttributeContext internalContext = new AttributeContext(context.getServer());
    NodeClass nodeClass = node.getNodeClass();
    if (attributeId == AttributeId.Value && nodeClass == NodeClass.Variable) {
        Set<AccessLevel> accessLevels = getAccessLevels(node, internalContext);
        if (!accessLevels.contains(AccessLevel.CurrentWrite)) {
            throw new UaException(StatusCodes.Bad_NotWritable);
        }
        Set<AccessLevel> userAccessLevels = getUserAccessLevels(node, context);
        if (!userAccessLevels.contains(AccessLevel.CurrentWrite)) {
            throw new UaException(StatusCodes.Bad_UserAccessDenied);
        }
    } else {
        WriteMask writeMask = writeMaskForAttribute(attributeId);
        Set<WriteMask> writeMasks = getWriteMasks(node, internalContext);
        if (!writeMasks.contains(writeMask)) {
            throw new UaException(StatusCodes.Bad_NotWritable);
        }
        Set<WriteMask> userWriteMasks = getUserWriteMasks(node, context);
        if (!userWriteMasks.contains(writeMask)) {
            throw new UaException(StatusCodes.Bad_UserAccessDenied);
        }
    }
    Variant updateVariant = value.getValue();
    if (indexRange != null) {
        NumericRange range = NumericRange.parse(indexRange);
        DataValue current = node.getAttribute(internalContext, attributeId);
        Variant currentVariant = current.getValue();
        Object valueAtRange = NumericRange.writeToValueAtRange(currentVariant, updateVariant, range);
        updateVariant = new Variant(valueAtRange);
    }
    DateTime sourceTime = value.getSourceTime();
    DateTime serverTime = value.getServerTime();
    value = new DataValue(updateVariant, value.getStatusCode(), (sourceTime == null || sourceTime.isNull()) ? DateTime.now() : sourceTime, (serverTime == null || serverTime.isNull()) ? DateTime.now() : serverTime);
    if (attributeId == AttributeId.Value) {
        NodeId dataType = extract(node.getAttribute(internalContext, AttributeId.DataType));
        if (dataType != null) {
            value = validateDataType(context.getServer(), dataType, value);
        }
        Integer valueRank = extract(node.getAttribute(internalContext, AttributeId.ValueRank));
        if (valueRank == null)
            valueRank = 0;
        if (valueRank > 0) {
            UInteger[] arrayDimensions = extract(node.getAttribute(context, AttributeId.ArrayDimensions));
            validateArrayType(valueRank, arrayDimensions, value);
        }
    }
    node.setAttribute(context, attributeId, value);
}
Also used : AttributeContext(org.eclipse.milo.opcua.sdk.server.nodes.AttributeContext) DataValue(org.eclipse.milo.opcua.stack.core.types.builtin.DataValue) UaException(org.eclipse.milo.opcua.stack.core.UaException) AccessLevel(org.eclipse.milo.opcua.sdk.core.AccessLevel) DateTime(org.eclipse.milo.opcua.stack.core.types.builtin.DateTime) WriteMask(org.eclipse.milo.opcua.sdk.core.WriteMask) Variant(org.eclipse.milo.opcua.stack.core.types.builtin.Variant) NumericRange(org.eclipse.milo.opcua.sdk.core.NumericRange) UInteger(org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UInteger) NodeClass(org.eclipse.milo.opcua.stack.core.types.enumerated.NodeClass) 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 3 with AccessLevel

use of org.eclipse.milo.opcua.sdk.core.AccessLevel in project milo by eclipse.

the class AttributeReader method readAttribute.

public static DataValue readAttribute(AttributeContext context, UaServerNode node, AttributeId attributeId, @Nullable TimestampsToReturn timestamps, @Nullable String indexRange, @Nullable QualifiedName encodingName) {
    try {
        AttributeContext internalContext = new AttributeContext(context.getServer());
        NodeClass nodeClass = node.getNodeClass();
        if (attributeId == AttributeId.Value && nodeClass == NodeClass.Variable) {
            Set<AccessLevel> accessLevels = getAccessLevels(node, internalContext);
            if (!accessLevels.contains(AccessLevel.CurrentRead)) {
                throw new UaException(StatusCodes.Bad_NotReadable);
            }
            Set<AccessLevel> userAccessLevels = getUserAccessLevels(node, context);
            if (!userAccessLevels.contains(AccessLevel.CurrentRead)) {
                throw new UaException(StatusCodes.Bad_UserAccessDenied);
            }
        }
        if (encodingName != null && encodingName.isNotNull()) {
            if (attributeId != AttributeId.Value) {
                throw new UaException(StatusCodes.Bad_DataEncodingInvalid);
            }
            NodeId dataTypeId;
            if (node instanceof VariableNode) {
                dataTypeId = ((VariableNode) node).getDataType();
            } else if (node instanceof VariableTypeNode) {
                dataTypeId = ((VariableTypeNode) node).getDataType();
            } else {
                throw new UaException(StatusCodes.Bad_DataEncodingInvalid);
            }
            boolean structured = isStructureSubtype(context.getServer(), dataTypeId);
            if (!structured) {
                throw new UaException(StatusCodes.Bad_DataEncodingInvalid);
            }
        }
        final DataValue.Builder dvb = node.getAttribute(context, attributeId).copy();
        // Maybe transcode the structure...
        if (dvb.value.isNotNull()) {
            final Object valueObject = dvb.value.getValue();
            Class<?> valueClazz = valueObject.getClass();
            if (valueClazz.isArray() && ArrayUtil.getType(valueObject) == ExtensionObject.class) {
                Object newValue = transformArray(valueObject, (ExtensionObject xo) -> transcode(context, node, xo, encodingName), ExtensionObject.class);
                dvb.setValue(new Variant(newValue));
            } else if (valueClazz == ExtensionObject.class) {
                ExtensionObject xo = (ExtensionObject) valueObject;
                Object newValue = transcode(context, node, xo, encodingName);
                dvb.setValue(new Variant(newValue));
            }
        }
        // Apply index range if provided...
        if (indexRange != null) {
            NumericRange range = NumericRange.parse(indexRange);
            Object valueAtRange = NumericRange.readFromValueAtRange(dvb.value, range);
            dvb.setValue(new Variant(valueAtRange));
        }
        // Add or remove timestamps based on TimestampsToReturn...
        if (timestamps != null) {
            dvb.applyTimestamps(attributeId, timestamps);
        }
        return dvb.build();
    } catch (UaException e) {
        return new DataValue(e.getStatusCode());
    }
}
Also used : AttributeContext(org.eclipse.milo.opcua.sdk.server.nodes.AttributeContext) DataValue(org.eclipse.milo.opcua.stack.core.types.builtin.DataValue) UaException(org.eclipse.milo.opcua.stack.core.UaException) ExtensionObject(org.eclipse.milo.opcua.stack.core.types.builtin.ExtensionObject) AccessLevel(org.eclipse.milo.opcua.sdk.core.AccessLevel) Variant(org.eclipse.milo.opcua.stack.core.types.builtin.Variant) NumericRange(org.eclipse.milo.opcua.sdk.core.NumericRange) NodeClass(org.eclipse.milo.opcua.stack.core.types.enumerated.NodeClass) VariableNode(org.eclipse.milo.opcua.sdk.core.nodes.VariableNode) NodeId(org.eclipse.milo.opcua.stack.core.types.builtin.NodeId) ExtensionObject(org.eclipse.milo.opcua.stack.core.types.builtin.ExtensionObject) VariableTypeNode(org.eclipse.milo.opcua.sdk.core.nodes.VariableTypeNode)

Aggregations

AccessLevel (org.eclipse.milo.opcua.sdk.core.AccessLevel)3 UaException (org.eclipse.milo.opcua.stack.core.UaException)3 ExtensionObject (org.eclipse.milo.opcua.stack.core.types.builtin.ExtensionObject)3 NodeId (org.eclipse.milo.opcua.stack.core.types.builtin.NodeId)3 NumericRange (org.eclipse.milo.opcua.sdk.core.NumericRange)2 AttributeContext (org.eclipse.milo.opcua.sdk.server.nodes.AttributeContext)2 DataValue (org.eclipse.milo.opcua.stack.core.types.builtin.DataValue)2 Variant (org.eclipse.milo.opcua.stack.core.types.builtin.Variant)2 UInteger (org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UInteger)2 NodeClass (org.eclipse.milo.opcua.stack.core.types.enumerated.NodeClass)2 AtomicReference (java.util.concurrent.atomic.AtomicReference)1 WriteMask (org.eclipse.milo.opcua.sdk.core.WriteMask)1 VariableNode (org.eclipse.milo.opcua.sdk.core.nodes.VariableNode)1 VariableTypeNode (org.eclipse.milo.opcua.sdk.core.nodes.VariableTypeNode)1 MonitoredDataItem (org.eclipse.milo.opcua.sdk.server.items.MonitoredDataItem)1 MonitoredEventItem (org.eclipse.milo.opcua.sdk.server.items.MonitoredEventItem)1 UaSerializationException (org.eclipse.milo.opcua.stack.core.UaSerializationException)1 DateTime (org.eclipse.milo.opcua.stack.core.types.builtin.DateTime)1 QualifiedName (org.eclipse.milo.opcua.stack.core.types.builtin.QualifiedName)1 UByte (org.eclipse.milo.opcua.stack.core.types.builtin.unsigned.UByte)1