diff --git a/plc4go/protocols/opcua/readwrite/model/MessagePDU.go b/plc4go/protocols/opcua/readwrite/model/MessagePDU.go index e5dfe130ff0..8ff90105bb2 100644 --- a/plc4go/protocols/opcua/readwrite/model/MessagePDU.go +++ b/plc4go/protocols/opcua/readwrite/model/MessagePDU.go @@ -150,6 +150,8 @@ func MessagePDUParseWithBuffer(ctx context.Context, readBuffer utils.ReadBuffer, _childTemp, typeSwitchError = OpcuaMessageRequestParseWithBuffer(ctx, readBuffer, response) case messageType == "MSG" && response == bool(true): // OpcuaMessageResponse _childTemp, typeSwitchError = OpcuaMessageResponseParseWithBuffer(ctx, readBuffer, response) + case messageType == "ERR" && response == bool(true): // OpcuaMessageError + _childTemp, typeSwitchError = OpcuaMessageErrorParseWithBuffer(ctx, readBuffer, response) default: typeSwitchError = errors.Errorf("Unmapped type for parameters [messageType=%v, response=%v]", messageType, response) } diff --git a/plc4go/protocols/opcua/readwrite/model/OpcuaMessageError.go b/plc4go/protocols/opcua/readwrite/model/OpcuaMessageError.go new file mode 100644 index 00000000000..4a2dba0ba39 --- /dev/null +++ b/plc4go/protocols/opcua/readwrite/model/OpcuaMessageError.go @@ -0,0 +1,303 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package model + +import ( + "context" + "fmt" + "github.com/apache/plc4x/plc4go/spi/utils" + "github.com/pkg/errors" + "github.com/rs/zerolog" +) + +// Code generated by code-generation. DO NOT EDIT. + +// OpcuaMessageError is the corresponding interface of OpcuaMessageError +type OpcuaMessageError interface { + fmt.Stringer + utils.LengthAware + utils.Serializable + MessagePDU + // GetChunk returns Chunk (property field) + GetChunk() string + // GetError returns Error (property field) + GetError() OpcuaStatusCode + // GetReason returns Reason (property field) + GetReason() PascalString +} + +// OpcuaMessageErrorExactly can be used when we want exactly this type and not a type which fulfills OpcuaMessageError. +// This is useful for switch cases. +type OpcuaMessageErrorExactly interface { + OpcuaMessageError + isOpcuaMessageError() bool +} + +// _OpcuaMessageError is the data-structure of this message +type _OpcuaMessageError struct { + *_MessagePDU + Chunk string + Error OpcuaStatusCode + Reason PascalString +} + +/////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////// +/////////////////////// Accessors for discriminator values. +/////////////////////// + +func (m *_OpcuaMessageError) GetMessageType() string { + return "ERR" +} + +func (m *_OpcuaMessageError) GetResponse() bool { + return bool(true) +} + +/////////////////////// +/////////////////////// +/////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////// + +func (m *_OpcuaMessageError) InitializeParent(parent MessagePDU) {} + +func (m *_OpcuaMessageError) GetParent() MessagePDU { + return m._MessagePDU +} + +/////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////// +/////////////////////// Accessors for property fields. +/////////////////////// + +func (m *_OpcuaMessageError) GetChunk() string { + return m.Chunk +} + +func (m *_OpcuaMessageError) GetError() OpcuaStatusCode { + return m.Error +} + +func (m *_OpcuaMessageError) GetReason() PascalString { + return m.Reason +} + +/////////////////////// +/////////////////////// +/////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////// + +// NewOpcuaMessageError factory function for _OpcuaMessageError +func NewOpcuaMessageError(chunk string, error OpcuaStatusCode, reason PascalString) *_OpcuaMessageError { + _result := &_OpcuaMessageError{ + Chunk: chunk, + Error: error, + Reason: reason, + _MessagePDU: NewMessagePDU(), + } + _result._MessagePDU._MessagePDUChildRequirements = _result + return _result +} + +// Deprecated: use the interface for direct cast +func CastOpcuaMessageError(structType any) OpcuaMessageError { + if casted, ok := structType.(OpcuaMessageError); ok { + return casted + } + if casted, ok := structType.(*OpcuaMessageError); ok { + return *casted + } + return nil +} + +func (m *_OpcuaMessageError) GetTypeName() string { + return "OpcuaMessageError" +} + +func (m *_OpcuaMessageError) GetLengthInBits(ctx context.Context) uint16 { + lengthInBits := uint16(m.GetParentLengthInBits(ctx)) + + // Simple field (chunk) + lengthInBits += 8 + + // Implicit Field (messageSize) + lengthInBits += 32 + + // Simple field (error) + lengthInBits += 32 + + // Simple field (reason) + lengthInBits += m.Reason.GetLengthInBits(ctx) + + return lengthInBits +} + +func (m *_OpcuaMessageError) GetLengthInBytes(ctx context.Context) uint16 { + return m.GetLengthInBits(ctx) / 8 +} + +func OpcuaMessageErrorParse(ctx context.Context, theBytes []byte, response bool) (OpcuaMessageError, error) { + return OpcuaMessageErrorParseWithBuffer(ctx, utils.NewReadBufferByteBased(theBytes), response) +} + +func OpcuaMessageErrorParseWithBuffer(ctx context.Context, readBuffer utils.ReadBuffer, response bool) (OpcuaMessageError, error) { + positionAware := readBuffer + _ = positionAware + log := zerolog.Ctx(ctx) + _ = log + if pullErr := readBuffer.PullContext("OpcuaMessageError"); pullErr != nil { + return nil, errors.Wrap(pullErr, "Error pulling for OpcuaMessageError") + } + currentPos := positionAware.GetPos() + _ = currentPos + + // Simple Field (chunk) + _chunk, _chunkErr := readBuffer.ReadString("chunk", uint32(8), "UTF-8") + if _chunkErr != nil { + return nil, errors.Wrap(_chunkErr, "Error parsing 'chunk' field of OpcuaMessageError") + } + chunk := _chunk + + // Implicit Field (messageSize) (Used for parsing, but its value is not stored as it's implicitly given by the objects content) + messageSize, _messageSizeErr := readBuffer.ReadInt32("messageSize", 32) + _ = messageSize + if _messageSizeErr != nil { + return nil, errors.Wrap(_messageSizeErr, "Error parsing 'messageSize' field of OpcuaMessageError") + } + + // Simple Field (error) + if pullErr := readBuffer.PullContext("error"); pullErr != nil { + return nil, errors.Wrap(pullErr, "Error pulling for error") + } + _error, _errorErr := OpcuaStatusCodeParseWithBuffer(ctx, readBuffer) + if _errorErr != nil { + return nil, errors.Wrap(_errorErr, "Error parsing 'error' field of OpcuaMessageError") + } + error := _error + if closeErr := readBuffer.CloseContext("error"); closeErr != nil { + return nil, errors.Wrap(closeErr, "Error closing for error") + } + + // Simple Field (reason) + if pullErr := readBuffer.PullContext("reason"); pullErr != nil { + return nil, errors.Wrap(pullErr, "Error pulling for reason") + } + _reason, _reasonErr := PascalStringParseWithBuffer(ctx, readBuffer) + if _reasonErr != nil { + return nil, errors.Wrap(_reasonErr, "Error parsing 'reason' field of OpcuaMessageError") + } + reason := _reason.(PascalString) + if closeErr := readBuffer.CloseContext("reason"); closeErr != nil { + return nil, errors.Wrap(closeErr, "Error closing for reason") + } + + if closeErr := readBuffer.CloseContext("OpcuaMessageError"); closeErr != nil { + return nil, errors.Wrap(closeErr, "Error closing for OpcuaMessageError") + } + + // Create a partially initialized instance + _child := &_OpcuaMessageError{ + _MessagePDU: &_MessagePDU{}, + Chunk: chunk, + Error: error, + Reason: reason, + } + _child._MessagePDU._MessagePDUChildRequirements = _child + return _child, nil +} + +func (m *_OpcuaMessageError) Serialize() ([]byte, error) { + wb := utils.NewWriteBufferByteBased(utils.WithInitialSizeForByteBasedBuffer(int(m.GetLengthInBytes(context.Background())))) + if err := m.SerializeWithWriteBuffer(context.Background(), wb); err != nil { + return nil, err + } + return wb.GetBytes(), nil +} + +func (m *_OpcuaMessageError) SerializeWithWriteBuffer(ctx context.Context, writeBuffer utils.WriteBuffer) error { + positionAware := writeBuffer + _ = positionAware + log := zerolog.Ctx(ctx) + _ = log + ser := func() error { + if pushErr := writeBuffer.PushContext("OpcuaMessageError"); pushErr != nil { + return errors.Wrap(pushErr, "Error pushing for OpcuaMessageError") + } + + // Simple Field (chunk) + chunk := string(m.GetChunk()) + _chunkErr := writeBuffer.WriteString("chunk", uint32(8), "UTF-8", (chunk)) + if _chunkErr != nil { + return errors.Wrap(_chunkErr, "Error serializing 'chunk' field") + } + + // Implicit Field (messageSize) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content) + messageSize := int32(int32(m.GetLengthInBytes(ctx))) + _messageSizeErr := writeBuffer.WriteInt32("messageSize", 32, (messageSize)) + if _messageSizeErr != nil { + return errors.Wrap(_messageSizeErr, "Error serializing 'messageSize' field") + } + + // Simple Field (error) + if pushErr := writeBuffer.PushContext("error"); pushErr != nil { + return errors.Wrap(pushErr, "Error pushing for error") + } + _errorErr := writeBuffer.WriteSerializable(ctx, m.GetError()) + if popErr := writeBuffer.PopContext("error"); popErr != nil { + return errors.Wrap(popErr, "Error popping for error") + } + if _errorErr != nil { + return errors.Wrap(_errorErr, "Error serializing 'error' field") + } + + // Simple Field (reason) + if pushErr := writeBuffer.PushContext("reason"); pushErr != nil { + return errors.Wrap(pushErr, "Error pushing for reason") + } + _reasonErr := writeBuffer.WriteSerializable(ctx, m.GetReason()) + if popErr := writeBuffer.PopContext("reason"); popErr != nil { + return errors.Wrap(popErr, "Error popping for reason") + } + if _reasonErr != nil { + return errors.Wrap(_reasonErr, "Error serializing 'reason' field") + } + + if popErr := writeBuffer.PopContext("OpcuaMessageError"); popErr != nil { + return errors.Wrap(popErr, "Error popping for OpcuaMessageError") + } + return nil + } + return m.SerializeParent(ctx, writeBuffer, m, ser) +} + +func (m *_OpcuaMessageError) isOpcuaMessageError() bool { + return true +} + +func (m *_OpcuaMessageError) String() string { + if m == nil { + return "" + } + writeBuffer := utils.NewWriteBufferBoxBasedWithOptions(true, true) + if err := writeBuffer.WriteSerializable(context.Background(), m); err != nil { + return err.Error() + } + return writeBuffer.GetBox().String() +} diff --git a/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/MessagePDU.java b/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/MessagePDU.java index 628434f0b62..a8a860296d9 100644 --- a/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/MessagePDU.java +++ b/plc4j/drivers/opcua/src/main/generated/org/apache/plc4x/java/opcua/readwrite/MessagePDU.java @@ -133,6 +133,9 @@ public static MessagePDU staticParse(ReadBuffer readBuffer, Boolean response) } else if (EvaluationHelper.equals(messageType, (String) "MSG") && EvaluationHelper.equals(response, (boolean) true)) { builder = OpcuaMessageResponse.staticParseMessagePDUBuilder(readBuffer, response); + } else if (EvaluationHelper.equals(messageType, (String) "ERR") + && EvaluationHelper.equals(response, (boolean) true)) { + builder = OpcuaMessageERR.staticParseMessagePDUBuilder(readBuffer, response); } if (builder == null) { throw new ParseException( diff --git a/protocols/opcua/src/main/xslt/opc-manual.xsl b/protocols/opcua/src/main/xslt/opc-manual.xsl index 3bc21d45c5f..036648d7d37 100644 --- a/protocols/opcua/src/main/xslt/opc-manual.xsl +++ b/protocols/opcua/src/main/xslt/opc-manual.xsl @@ -125,6 +125,12 @@ [simple int 32 requestId] [array byte message count 'messageSize - 24'] ] + ['"ERR"','true' OpcuaMessageError + [simple string 8 chunk ] + [implicit int 32 messageSize 'lengthInBytes'] + [simple OpcuaStatusCode error ] + [simple PascalString reason] + ] ] ]