use of org.eclipse.milo.opcua.stack.core.UaSerializationException in project milo by eclipse.
the class UascClientMessageHandler method encode.
@Override
protected void encode(ChannelHandlerContext ctx, UaTransportRequest request, ByteBuf buffer) {
serializationQueue.encode((binaryEncoder, chunkEncoder) -> {
ByteBuf messageBuffer = BufferUtil.pooledBuffer();
try {
binaryEncoder.setBuffer(messageBuffer);
binaryEncoder.writeMessage(null, request.getRequest());
checkMessageSize(messageBuffer);
EncodedMessage encodedMessage = chunkEncoder.encodeSymmetric(secureChannel, requestIdSequence.getAndIncrement(), messageBuffer, MessageType.SecureMessage);
long requestId = encodedMessage.getRequestId();
List<ByteBuf> messageChunks = encodedMessage.getMessageChunks();
pending.put(requestId, request);
// No matter how we complete, make sure the entry in pending is removed.
// This covers the case where the request fails due to a timeout in the
// transport layer as well as normal completion.
request.getFuture().whenComplete((r, x) -> pending.remove(requestId));
CompositeByteBuf chunkComposite = BufferUtil.compositeBuffer();
for (ByteBuf chunk : messageChunks) {
chunkComposite.addComponent(chunk);
chunkComposite.writerIndex(chunkComposite.writerIndex() + chunk.readableBytes());
}
ctx.writeAndFlush(chunkComposite, ctx.voidPromise());
} catch (MessageEncodeException e) {
logger.error("Error encoding {}: {}", request.getRequest(), e.getMessage(), e);
request.getFuture().completeExceptionally(e);
ctx.close();
} catch (UaSerializationException e) {
logger.error("Error serializing {}: {}", request.getRequest(), e.getMessage(), e);
request.getFuture().completeExceptionally(e);
} finally {
messageBuffer.release();
}
});
}
use of org.eclipse.milo.opcua.stack.core.UaSerializationException in project milo by eclipse.
the class UascClientMessageHandler method checkMessageSize.
private void checkMessageSize(ByteBuf messageBuffer) throws UaSerializationException {
int messageSize = messageBuffer.readableBytes();
int remoteMaxMessageSize = serializationQueue.getParameters().getRemoteMaxMessageSize();
if (remoteMaxMessageSize > 0 && messageSize > remoteMaxMessageSize) {
throw new UaSerializationException(StatusCodes.Bad_RequestTooLarge, "request exceeds remote max message size: " + messageSize + " > " + remoteMaxMessageSize);
}
}
use of org.eclipse.milo.opcua.stack.core.UaSerializationException in project milo by eclipse.
the class AbstractCodec method encodeField.
private void encodeField(SerializationContext context, OpcUaBinaryStreamEncoder encoder, LinkedHashMap<String, MemberT> members, FieldType field) {
String typeName = field.getTypeName().getLocalPart();
String typeNamespace = field.getTypeName().getNamespaceURI();
MemberT member = members.get(field.getName());
boolean typeNamespaceIsUa = Namespaces.OPC_UA.equals(typeNamespace) || Namespaces.OPC_UA_BSD.equals(typeNamespace);
if (fieldIsScalar(field)) {
Object scalarValue = memberTypeToOpcUaScalar(member, typeName);
if (typeNamespaceIsUa && WRITERS.containsKey(typeName)) {
WRITERS.get(typeName).accept(encoder, scalarValue);
} else {
context.encode(typeNamespace, typeName, scalarValue, encoder);
}
} else {
if (field.isIsLengthInBytes()) {
throw new UaSerializationException(StatusCodes.Bad_EncodingError, "IsLengthInBytes=true not supported");
}
if ("Bit".equals(typeName) && typeNamespaceIsUa) {
int length = fieldLength(field, members);
Number number = (Number) memberTypeToOpcUaArray(member, typeName);
BigInteger bi = BigInteger.valueOf(number.longValue());
for (int i = 0; i < length; i++) {
encoder.writeBit(bi.shiftRight(i).and(BigInteger.ONE).intValue());
}
} else {
Object[] valueArray = (Object[]) memberTypeToOpcUaArray(member, typeName);
FieldType lengthField = fields.get(field.getLengthField());
if (lengthField != null) {
int length = valueArray.length;
members.put(lengthField.getName(), opcUaToMemberTypeScalar(lengthField.getName(), length, lengthField.getTypeName().getLocalPart()));
encodeField(context, encoder, members, lengthField);
}
if (valueArray != null) {
if (typeNamespaceIsUa && WRITERS.containsKey(typeName)) {
for (Object value : valueArray) {
WRITERS.get(typeName).accept(encoder, value);
}
} else {
for (Object value : valueArray) {
context.encode(typeNamespace, typeName, value, encoder);
}
}
}
}
}
}
use of org.eclipse.milo.opcua.stack.core.UaSerializationException 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;
}
}
use of org.eclipse.milo.opcua.stack.core.UaSerializationException in project milo by eclipse.
the class SubscriptionManager method modifyMonitoredItem.
private BaseMonitoredItem<?> modifyMonitoredItem(MonitoredItemModifyRequest request, TimestampsToReturn timestamps, Subscription subscription, Map<NodeId, AttributeGroup> attributeGroups) throws UaException {
UInteger itemId = request.getMonitoredItemId();
MonitoringParameters parameters = request.getRequestedParameters();
BaseMonitoredItem<?> monitoredItem = subscription.getMonitoredItems().get(itemId);
if (monitoredItem == null) {
throw new UaException(StatusCodes.Bad_MonitoredItemIdInvalid);
}
NodeId nodeId = monitoredItem.getReadValueId().getNodeId();
UInteger attributeId = monitoredItem.getReadValueId().getAttributeId();
AttributeGroup attributeGroup = attributeGroups.get(nodeId);
if (attributeId.equals(AttributeId.EventNotifier.uid())) {
Object filterObject = request.getRequestedParameters().getFilter().decode(server.getSerializationContext());
MonitoringFilter filter = validateEventItemFilter(filterObject, attributeGroup);
UInteger requestedQueueSize = parameters.getQueueSize();
AtomicReference<UInteger> revisedQueueSize = new AtomicReference<>(requestedQueueSize);
try {
server.getAddressSpaceManager().onModifyEventItem(monitoredItem.getReadValueId(), requestedQueueSize, revisedQueueSize::set);
} catch (Throwable t) {
throw new UaException(StatusCodes.Bad_InternalError, t);
}
monitoredItem.modify(timestamps, parameters.getClientHandle(), monitoredItem.getSamplingInterval(), filter, revisedQueueSize.get(), parameters.getDiscardOldest());
} else {
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 minimumSamplingInterval = -1.0;
try {
minimumSamplingInterval = attributeGroup.getMinimumSamplingInterval();
if (minimumSamplingInterval == null) {
minimumSamplingInterval = server.getConfig().getLimits().getMinSupportedSampleRate();
}
} catch (UaException e) {
long statusCodeValue = e.getStatusCode().getValue();
if (statusCodeValue != StatusCodes.Bad_AttributeIdInvalid && statusCodeValue != StatusCodes.Bad_NodeIdUnknown) {
throw e;
}
}
double requestedSamplingInterval = getSamplingInterval(subscription, minimumSamplingInterval, request.getRequestedParameters().getSamplingInterval());
UInteger requestedQueueSize = parameters.getQueueSize();
AtomicReference<Double> revisedSamplingInterval = new AtomicReference<>(requestedSamplingInterval);
AtomicReference<UInteger> revisedQueueSize = new AtomicReference<>(requestedQueueSize);
try {
server.getAddressSpaceManager().onModifyDataItem(monitoredItem.getReadValueId(), requestedSamplingInterval, requestedQueueSize, (rsi, rqs) -> {
revisedSamplingInterval.set(rsi);
revisedQueueSize.set(rqs);
});
} catch (Throwable t) {
throw new UaException(StatusCodes.Bad_InternalError, t);
}
monitoredItem.modify(timestamps, parameters.getClientHandle(), revisedSamplingInterval.get(), filter, revisedQueueSize.get(), parameters.getDiscardOldest());
}
return monitoredItem;
}
Aggregations