TLDR: changes in plc4x which help developing drivers across languages that have 
no effect how plc4x send/receiver data or how you use the API

As of the last mail `Progress on plc4go` from 15.03.2021 I want to give another 
overview what has happened between 1bd132a to f97d36f

Changes on read/write buffers In plc4go and plc4j
Note the below changes don’t have any impact on the API on plc4x nor on the way 
data is written onto the wire
Existing buffers (which were byte base [writing and reading bytes to a 
underlying reader/writer]) had an interface introduced which abstracted the 
interaction from plc4x from the representation (reason for that described in 
point 5).
Write buffer
2 New methods added
PushContext: Indicates that the model is about to write data which is enclosed 
by a logical context
PopContext: Indicates that the model is done writing data which is enclosed by 
a logical context
Every method got a logicalName and a varargs/variadic writerArguments added
LogicalName: indicates the logical name of the data which is about to be 
written (e.g. checksum flag, address)
WriterArguments: are optional hints about the data being written (e.g. name of 
the enum [e.g.ADS_READ] being written, or if a logical context is a list)
The above points are completely ignored by the byte based writers (which got 
renamed with the introduction of the interface to *ByteBased) as the above 
changes don’t have any impact on byte based writing (They could be used for log 
tracing for better debugging in the future)
Read buffer
2 New methods added
PullContext: indicates that the model is about to read data which is enclosed 
by a logical context
CloseContext: Indicates that the model is done reading data which is enclosed 
by a logical context
Every method got a logicalName and a varargs/variadic readerArguments added
LogicalName: indicates the logical name of the data which is about to be read 
(e.g. checksum flag, address)
ReaderArguments: are optional hints about the data being read (e.g. name of the 
enum [e.g.ADS_READ] being written, or if a logical context is a list)
The above points are completely ignored by the byte based readers (which got 
renamed with the introduction of the interface to *ByteBased) as the above 
changes don’t have any impact on byte based writing (They could be used for log 
tracing for better debugging in the future)
On plc4j the old methods are still available as default methods but will be 
deprecated in the future (The buffers are meant to be used in the context of 
the generated models which uses the new interfaces)
In the future I plan on adding new byte/byte[] based methods to better 
encapsulate logical context on byte/byte[] fields which can then be better 
rendered by implementors of the buffer interfaces (mostly required by non byte 
based buffers). See my other mail on the mailing list about bytes 
<https://lists.apache.org/thread.html/r5285838fd0b53d50fca34c2539b2d12ac275361d4faf5df36f3ec804@%3Cdev.plc4x.apache.org%3E>.
Refactoring in golang SPI
Added default implementations for connection and codec
Moved default implementation into a spi/default package
These can be configured with variadic WithOption calls
Moved duplicated codes into commons classes
At the moment these a realized with a cycling dependency for callback which get 
refactored to a non cyclic approach in the future
Added default implementations for request and response
Removed cyclic dependency from request interceptor
Ported the request transaction manager from java
At the moment this is a 1:1 port from java and doesn’t make full use of the 
native golang features. The TM was required by the s7 driver to prevent clients 
from overloading a plc4x (which could lead to a huge RL crash ;) )
Added Ascii/Xml/Json buffers described in point 4 and 5
Updated goDocs
S7 Driver in plc4go
Implemented the S7 driver into plc4go
In the course of this I fixed several bugs and initially with the ads drivers 
lead to many changes described in this mail
Added a s7Io_test.go (will be helpful to visualize 
<https://github.com/apache/plc4x/blob/develop/plc4go/internal/plc4go/s7/s7Io_test.go>
 many changes described in this mail)
AsciiBox/HexWriter in plc4go
During development of ads and s7 driver I had several smaller bugs (e.g. 
padding issues which got fixed) were I had to stare at bytes every day till I 
almost could identify 
<https://github.com/apache/plc4x/blob/develop/plc4go/internal/plc4go/s7/s7Io_test.go#L349>
 a s7Message by looking at the hex at the end of the day 🤪
This lead me to writing a small tool which would help me to visually segment 
the message into logical context (see Point 1) to better look for flipping 
bytes.
The AsciiBox was born which takes a string and draws a nice box 
<https://github.com/apache/plc4x/blob/develop/plc4go/internal/plc4go/spi/utils/asciiBox_test.go#L79>
 (requires a boxed font which apparently GitHub doesn’t have; on boxed fonts 
these are square 😉) around it (with a optional name)
Implementing this I added a `Box() utils.AsciiBox` to every model which renders 
itself and Childs to a fixed width box (120.) which could overflow a bit if 
required
In the initial version which doesn’t use the new buffers (see point 4) a nice 
hex box could be drawn for bytes arrays.
Requiring to render hexdumps for data segments into a dynamic box required a 
dynamic width hex dump. So I introduced hex.go which could resize to any width. 
(Other than normal hex dumps this tool uses a base 10 byte index [normal use 
hex dumpers and render 16 bytes each line] which made working with them easier 
that hex indexes [most of us count in base 10 anyway])
During later development a BufferBoxedBased was introduced to render the 
messages true to their byte representation.
New xml/json writers in plc4go and plc4j
Important Background info: Implementing the BoxWriter (see point 4.7) I noticed 
that I implemented the serializing/deserializing of message twice (duplicated 
code that does the same but different is never good). I noticed that we already 
had the code for serializing/deserializing messages to/from the wire and it 
might be better to reuse this code for that. This initially this lead to the 
introduction of the interfaces described in Point 1 (This also explains why I 
need a logical name and context for asciibox which will also get now relevant 
for json xml). I also noticed that the xml was imitating the byte 
serializing/deserializing (in golang). Even worse: Between java and golang 
there were differences (Java used annotations and Jackson for rendering / 
golang used a second generated implementation). This made it hard when handling 
language agnostic xml test suites.
I introduced xml/json based writers which implemented the buffer interfaces and 
deterministically (at least the should but at the moment they need a bit 
improvement [e.g. plc4go json writing]) write/read xml/json (xml has a fixed 
element oder json not which requires buffering on json at least when reading). 
The model itself dictates when to read and to write and the 
writing/reading/rendering is decoupled and encapsulated in the concrete 
read/writer implementation (json/xml/ascii[go only]).
Whenever possible existing code was changed to use the new xml readers/writers 
(e.g. point 6)
Updated xml representation for test suites (Parser/Driver)
Having now the new buffer interfaces and their xml read/writer I could change 
<https://github.com/apache/plc4x/commit/8f28d7965555ed1823425e565e5a4f5972f378ef#diff-5579ab196820eb2cdccdd7c7a429b35823e80aacd493038a1c0f13a3c025dce9R503>
 the test suites.
The xml contains now more information (at points a bit too much because there 
is no support for byte/byte[] rendering at the moment see point 1.6).
Remaining java class names from test read request will be removed in future 
changes and replaced by language agnostic representation
Updated xsd for suites to include protocol name and flavor (which is required 
to reliable identify message types in golang and java)
Xml now contains additional attributes describing the basic datatype and bit 
length (these are optional which are not required for parsing as the buffer 
dictates the type on a read operation anyway but helps us humans to get more 
context about the datatype. At the moment these get still validated by the read 
buffers anyway to check for consistency [which will be configurable if not 
already])
Feature update in golang api
Builders are now real chain able builders
Updated examples and documentation for the new chain able builders
Change is non breaking as the return type was changed from void to builder
Added pl4go config package to configure tracing of workers and transactions
Updated most golang docs in the api
Several Bugfixes (see commit messages in Ref compare at the bottom)
Refactored Testsuites to break down the big class in java and add support for 
the buffers described in point 5
Much more
There are more changes contained and if you want to keep reading for whatever 
reason (maybe you like reading long mails 😁) you can check the commit 
descriptions (which are mostly quite verbose) in the GitHub/compare 
<https://github.com/apache/plc4x/compare/1bd132a241ef7f8e6603450514f9d970c8dae91e...f97d36f51b8942b2a4e9f03328ae364edd73aa5d>.
 Also let me know in this tread if I overlooked a important change which isn’t 
self describing or there are required features missing which don’t have a todo 
in the code.

Thats for that and thanks for reading this far 😀

Sebastian

Ps: (Ref compare GitHub/compare 
<https://github.com/apache/plc4x/compare/1bd132a241ef7f8e6603450514f9d970c8dae91e...f97d36f51b8942b2a4e9f03328ae364edd73aa5d>)

Reply via email to