You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by sr...@apache.org on 2023/08/03 14:18:51 UTC
[plc4x] branch develop updated: feat(opcua): add support for OpcuaMessageError
This is an automated email from the ASF dual-hosted git repository.
sruehl pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/plc4x.git
The following commit(s) were added to refs/heads/develop by this push:
new b88d4eb300 feat(opcua): add support for OpcuaMessageError
b88d4eb300 is described below
commit b88d4eb3002f898b264bebc1cfed081980d64ce5
Author: Sebastian Rühl <sr...@apache.org>
AuthorDate: Thu Aug 3 16:18:43 2023 +0200
feat(opcua): add support for OpcuaMessageError
---
.../protocols/opcua/readwrite/model/MessagePDU.go | 2 +
.../opcua/readwrite/model/OpcuaMessageError.go | 303 +++++++++++++++++++++
.../plc4x/java/opcua/readwrite/MessagePDU.java | 3 +
protocols/opcua/src/main/xslt/opc-manual.xsl | 6 +
4 files changed, 314 insertions(+)
diff --git a/plc4go/protocols/opcua/readwrite/model/MessagePDU.go b/plc4go/protocols/opcua/readwrite/model/MessagePDU.go
index e5dfe130ff..8ff90105bb 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 0000000000..4a2dba0ba3
--- /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 "<nil>"
+ }
+ 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 628434f0b6..a8a860296d 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 abstract class MessagePDU implements Message {
} 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 3bc21d45c5..036648d7d3 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]
+ ]
]
]