use of org.eclipse.milo.opcua.stack.core.channel.ChunkEncoder.EncodedMessage 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.channel.ChunkEncoder.EncodedMessage in project milo by eclipse.
the class UascServerSymmetricHandler method sendServiceResponse.
private void sendServiceResponse(ChannelHandlerContext ctx, long requestId, UaRequestMessage request, UaResponseMessage response) {
serializationQueue.encode((binaryEncoder, chunkEncoder) -> {
ByteBuf messageBuffer = BufferUtil.pooledBuffer();
try {
binaryEncoder.setBuffer(messageBuffer);
binaryEncoder.writeMessage(null, response);
checkMessageSize(messageBuffer);
EncodedMessage encodedMessage = chunkEncoder.encodeSymmetric(secureChannel, requestId, messageBuffer, MessageType.SecureMessage);
CompositeByteBuf chunkComposite = BufferUtil.compositeBuffer();
for (ByteBuf chunk : encodedMessage.getMessageChunks()) {
chunkComposite.addComponent(chunk);
chunkComposite.writerIndex(chunkComposite.writerIndex() + chunk.readableBytes());
}
ctx.writeAndFlush(chunkComposite, ctx.voidPromise());
} catch (MessageEncodeException e) {
logger.error("Error encoding {}: {}", response, e.getMessage(), e);
UInteger requestHandle = request.getRequestHeader().getRequestHandle();
sendServiceFault(ctx, requestId, requestHandle, e);
} catch (UaSerializationException e) {
logger.error("Error serializing response: {}", e.getStatusCode(), e);
UInteger requestHandle = request.getRequestHeader().getRequestHandle();
sendServiceFault(ctx, requestId, requestHandle, e);
} finally {
messageBuffer.release();
}
});
}
use of org.eclipse.milo.opcua.stack.core.channel.ChunkEncoder.EncodedMessage in project milo by eclipse.
the class UascServerSymmetricHandler method sendServiceFault.
private void sendServiceFault(ChannelHandlerContext ctx, long requestId, UInteger requestHandle, Throwable fault) {
StatusCode statusCode = UaException.extract(fault).map(UaException::getStatusCode).orElse(StatusCode.BAD);
ServiceFault serviceFault = new ServiceFault(new ResponseHeader(DateTime.now(), requestHandle, statusCode, null, null, null));
serializationQueue.encode((binaryEncoder, chunkEncoder) -> {
ByteBuf messageBuffer = BufferUtil.pooledBuffer();
try {
binaryEncoder.setBuffer(messageBuffer);
binaryEncoder.writeMessage(null, serviceFault);
checkMessageSize(messageBuffer);
EncodedMessage encodedMessage = chunkEncoder.encodeSymmetric(secureChannel, requestId, messageBuffer, MessageType.SecureMessage);
CompositeByteBuf chunkComposite = BufferUtil.compositeBuffer();
for (ByteBuf chunk : encodedMessage.getMessageChunks()) {
chunkComposite.addComponent(chunk);
chunkComposite.writerIndex(chunkComposite.writerIndex() + chunk.readableBytes());
}
ctx.writeAndFlush(chunkComposite, ctx.voidPromise());
} catch (MessageEncodeException e) {
logger.error("Error encoding {}: {}", serviceFault, e.getMessage(), e);
} catch (UaSerializationException e) {
logger.error("Error serializing ServiceFault: {}", e.getStatusCode(), e);
} finally {
messageBuffer.release();
}
});
}
use of org.eclipse.milo.opcua.stack.core.channel.ChunkEncoder.EncodedMessage in project milo by eclipse.
the class UascClientMessageHandler method sendOpenSecureChannelRequest.
private void sendOpenSecureChannelRequest(ChannelHandlerContext ctx, SecurityTokenRequestType requestType) {
ByteString clientNonce = secureChannel.isSymmetricSigningEnabled() ? NonceUtil.generateNonce(secureChannel.getSecurityPolicy()) : ByteString.NULL_VALUE;
secureChannel.setLocalNonce(clientNonce);
RequestHeader header = new RequestHeader(null, DateTime.now(), uint(0), uint(0), null, config.getRequestTimeout(), null);
OpenSecureChannelRequest request = new OpenSecureChannelRequest(header, uint(PROTOCOL_VERSION), requestType, secureChannel.getMessageSecurityMode(), secureChannel.getLocalNonce(), config.getChannelLifetime());
serializationQueue.encode((binaryEncoder, chunkEncoder) -> {
ByteBuf messageBuffer = BufferUtil.pooledBuffer();
try {
binaryEncoder.setBuffer(messageBuffer);
binaryEncoder.writeMessage(null, request);
checkMessageSize(messageBuffer);
EncodedMessage encodedMessage = chunkEncoder.encodeAsymmetric(secureChannel, requestIdSequence.getAndIncrement(), messageBuffer, MessageType.OpenSecureChannel);
CompositeByteBuf chunkComposite = BufferUtil.compositeBuffer();
for (ByteBuf chunk : encodedMessage.getMessageChunks()) {
chunkComposite.addComponent(chunk);
chunkComposite.writerIndex(chunkComposite.writerIndex() + chunk.readableBytes());
}
ctx.writeAndFlush(chunkComposite, ctx.voidPromise());
ChannelSecurity channelSecurity = secureChannel.getChannelSecurity();
long currentTokenId = -1L;
if (channelSecurity != null) {
currentTokenId = channelSecurity.getCurrentToken().getTokenId().longValue();
}
long previousTokenId = -1L;
if (channelSecurity != null) {
previousTokenId = channelSecurity.getPreviousToken().map(token -> token.getTokenId().longValue()).orElse(-1L);
}
logger.debug("Sent OpenSecureChannelRequest ({}, id={}, currentToken={}, previousToken={}).", request.getRequestType(), secureChannel.getChannelId(), currentTokenId, previousTokenId);
} catch (MessageEncodeException e) {
logger.error("Error encoding {}: {}", request, e.getMessage(), e);
ctx.close();
} finally {
messageBuffer.release();
}
});
}
use of org.eclipse.milo.opcua.stack.core.channel.ChunkEncoder.EncodedMessage in project milo by eclipse.
the class UascClientMessageHandler method sendCloseSecureChannelRequest.
private void sendCloseSecureChannelRequest(ChannelHandlerContext ctx, CloseSecureChannelRequest request) {
serializationQueue.encode((binaryEncoder, chunkEncoder) -> {
ByteBuf messageBuffer = BufferUtil.pooledBuffer();
try {
binaryEncoder.setBuffer(messageBuffer);
binaryEncoder.writeMessage(null, request);
checkMessageSize(messageBuffer);
EncodedMessage encodedMessage = chunkEncoder.encodeSymmetric(secureChannel, requestIdSequence.getAndIncrement(), messageBuffer, MessageType.CloseSecureChannel);
CompositeByteBuf chunkComposite = BufferUtil.compositeBuffer();
for (ByteBuf chunk : encodedMessage.getMessageChunks()) {
chunkComposite.addComponent(chunk);
chunkComposite.writerIndex(chunkComposite.writerIndex() + chunk.readableBytes());
}
ctx.writeAndFlush(chunkComposite).addListener(future -> ctx.close());
secureChannel.setChannelId(0);
} catch (MessageEncodeException e) {
logger.error("Error encoding {}: {}", request, e.getMessage(), e);
handshakeFuture.completeExceptionally(e);
ctx.close();
} catch (UaSerializationException e) {
logger.error("Error serializing {}: {}", request, e.getMessage(), e);
handshakeFuture.completeExceptionally(e);
ctx.close();
} finally {
messageBuffer.release();
}
});
}
Aggregations