[GitHub] [plc4x] ottobackwards opened a new pull request #150: complex object members should not leak to external entities, add apis…
ottobackwards opened a new pull request #150: URL: https://github.com/apache/plc4x/pull/150 … to plc4_connection and plc4c_system to start clang-format changes add ability to look up an element from a void* fix some bugs around cleanup. logic to destroy connections connections now own copies of their strings so they can destroy them. This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: us...@infra.apache.org
Re: [Introduction] Christofer Dutz
Hi Alls, I am an electrical engineer, graduated from Universidad de Oriente, 50 years old, I live in Barcelona, Venezuela with two daughters and my wife. My first computer, an Atari-800XL. :-) My first automation work was done for the mining area. Mining is very hard work where safety must always come first and it is the first rule that I teach the people who have worked with me. On weekends I had the development of Web pages as a hobby, for the company and to learn some Linux. Much of this fieldwork was with Sy / Max teams from Square D. Then I went to the beverage area (Brewery), where I made my beginnings with Siemens S5 and many of its variants, as well as many of its functions for the development of applications in the Brewery area that are still used (Braumat, Proleit, etc.). Trying to promote at that time in any meeting Linux or open technologies was or is sacrilege or heresy in that corporation. My conclusion was that marketing rules Automation, the example is when a colleague indicated that a KHS inspection machine started with Linux Suse. Fuck! Then with my own company, we developed a Kannel-based Gateway (Open Source) for a telecommunications company also using many high-availability Linux tools. It ran smoothly throughout its lifetime. As partners with Siemens, we carry out many Automation projects for the mining, beverages, food and Oil & Gas areas, also having training in their tools (PCS7, Braumat, TIA, etc). >From these works I remember another Gateway that I developed for the Siemens Apacs and S7 (PCS7) teams, which runs in Java. After evaluating many tools for implementation (Tomcat, JBoss, etc.) the last one was Karaf, my brain exploded, this complies with the maxim of automation, "keep things stupid simple ". The Gateway runs 24/7 only for scheduled maintenance. My area of interest has always been the development of a stack of applications for Automation (from the PLC to the end customer), from there I come to PLC4X, where the concept of maintaining a uniform API seems essential to me. I hate OPC-DA for its DCOM issues and OPC-UA for its fragmentation and implementation difficulties (a lot of Marketing again). In specific my areas of interest: Simatic S7, PCS7, Java, Epics, ControlSystemStudio (CSS), Karaf, S88, PackML, Security systems (SIS). Best regards, PS: In the brewery we had a phrase for the programs that came from Germany. "So that you are going to be easy if you can make it difficult", jeje El mar., 5 may. 2020 a las 7:23, Christofer Dutz () escribió: > Hi all, > > I have noticed that our tram has grown quite a bit in the last year and > most of you I have never met personally. > We have been discussing a lot of things here on the list and on slack, but > I only have little background on who you folks actually are. > > So I would like to ask anyone interested to just introduce himself in this > thread. > > I’ll start: > > My name is Christofer Dutz, I’m currently 42 years old and studied > computer-science at the University of Darmstadt. > I’m the son of an Electro-Engineer and therefore already had contact with > all of this automation stuff when I was a kid, but somehow lost contact > when I discovered my interest in computers. > > Being an IT guy living near Frankfurt (Germany) there is almost no chance > to not work for Banks and Insurance companies. So I guess I’ve been working > for about 12 different Banks and Insurance companies in the last 15 years. > I always like to compare working for a bank like asking Picasso to paint a > portrait, but to have him wear a mental-institution restraining jacket and > have him paint with a brush in his mouth. End of the first quarter of 2017 > it was getting so unbearable for me, that I was thinking about giving up my > profession as an IT specialist and even starting to learn something new. I > was already looking for companies looking for an apprentice as carpenter, > when I had another round of self-reflection. Even if I probably would have > been good as a carpenter, I still love doing my job, just not for Banks and > Insurance companies. > I was seeing the same with a lot of my colleagues. > > It was that time that Industry 4.0 was everywhere … all the problems are > easily addressable with open-source and a lot of the skills I have from the > banking would have been a perfect match. So I had a look at what’s missing > in this big picture and pretty quickly noticed the data-access problem is > the biggest barrier and no solution being available or in sight. > > Luckily at codecentric we have something called “Innovation budget”. Here > if you’ve got an idea, you can pitch in some shark-tank-like session with > the board and if they like it, you get the funds for doing that. My idea > was to build a universal protocol adapter. From the beginning I said I want > this to be a true open-source project at Apache. The benefit for > codecentric would be to eliminate the barriers to offering IIoT solutions > with our
Re: SPI Module - OSGi Bundle
Hey Niclas, While this code seems straight I don't think it is needed, and valid in our case. Main benefit of extender and extender based patterns is centralized processing of drivers. I am keen to keep only interfaces in the API packages and bundles and move active parts of code (such base classes) to another place. It is necessary to avoid creation of implementation dependency. And that's what is in fact, promoted by shared activator class. Best, Łukasz On 06.05.2020 13:47, Niclas Hedhman wrote: > My suggestion was; > 1. Don't do the BundleTracker classes, and instead change to a bundle > activator for each. > 2. Add the "Bundle-Activator: org.apache.plc4x.java.osgi.DriverActivator" > to the driver META/MANIFEST.MF > 3. Do the equivalent for the Transports. > > public class DriverActivator implements BundleActivator { > > private ServiceRegistration reg; > > @Override > public void start( BundleContext context ) throws Exception { > Hashtable props = new Hashtable<>(); > props.put( OsgiDriverManager.PROTOCOL_CODE, driver.getProtocolCode() > ); > props.put( OsgiDriverManager.PROTOCOL_NAME, driver.getProtocolName() > ); > reg = context.registerService( PlcDriver.class, driver, props ); > } > > @Override > public void stop( BundleContext context ) { > context.unregisterService( reg ); > } > } > > > > > > > > > > On Wed, May 6, 2020 at 2:33 PM Etienne Robinet wrote: > >> Hi all, >> So concretely what changes should be done so that a Driver/Transport >> declares itself his service? Beside the changes in the manifest? >> Etienne >> On 2020/05/06 01:26:42, Niclas Hedhman wrote: >>> Łukasz, >>> >>> the reason I say it is not very OSGi-y, is that the principle of OSGi is >>> that the bundle handles its own service registrations. In the case of >> JDBC >>> (I initiated that spec, and I am the founder of OPS4J as well as Pax >>> subproject, 2005), it needed to address the problem that JDBC drivers >>> existed and changing their build and/or manifests was decided to be "not >>> viable". The approach there is a work-around for legacy code, which I and >>> Stuart McCulloch basically invented. IIRC, this happened in 2007. >>> >>> I didn't suggest that bundles require Declarative Services. I suggested >>> that the "inside of the loop" in Etienne's code is put into an Activator, >>> the code residing in the API and SPI bundles respectively, and that each >>> driver/transport has a "Bundle-Activator: ." in the manifest >>> referencing respective activator. It is not more intrusive than the >>> Export-Package, Import-Package that will be required anyway. >>> >>> Advantages; It is more in the spirit of OSGi. But importantly, the >>> driver/transport is now an active bundle, rather than a library bundle, >> and >>> in theory the start/stop of a bundle could (there might be other reasons >>> why not) turn it on/off in runtime. If special needs pop up, maybe to >>> deploy for the OpenHAB project, it is possible to override the >>> driver/transport with hacking the API/SPI bundles. >>> >>> And I can't see any disadvantages other than "need to rework a bit of >> code". >>> >>> But I don't have skin in the game. Not in OSGi, not here, so take my >>> recommendations into consideration or throw them away. I just got the >>> impression that you didn't really get what I suggested. >>> >>> >>> // Niclas >>> >>> >>> >>> On Wed, May 6, 2020 at 4:57 AM Łukasz Dywicki >> wrote: >>> Hey Etienne, that's awesome piece of work. I can test it! :-) I believe that's what Etienne code does it in a valid OSGi way. And I >> do believe not because he mentioned me by name, but due to below argumentation. Proposed code uses extender pattern to grab specific META-INF/services entries and register them in OSGi service registry. If you will take a look on following line: >> https://github.com/apache/plc4x/blob/feature/osgi/plc4j/api/src/main/java/org/apache/plc4x/java/osgi/ApiActivator.java#L63 you will find that bundle is an jar which changes state to ACTIVE. Additionally that bundle classloader is used to find services and that bundle context is used to register services. In the end service which appears looks like one registered by driver/transport module. The main point for above implementation is basic - getting the standard PLC4X driver JAR working in OSGi without forcing it to knowing too much about OSGi. Driver needs to ship manifest with import/export statements and that's it. Additionally driver does not have to have a XML descriptor which registers service. Quite many third parties might be supplying drivers without any or with limited knowledge of OSGi. Do drivers have to be a service? Well, it they can still be a valid >> OSGi service, registered using any other way! OSGi aware driver manager uses OSGi services instead of stat
Scraper
Hello guys, I was looking a bit at the actual Scraper we have in 'tools'. I tested a scheduled Read via YAML file and it worked just fine. However when I try to create a triggered-read, I get an error: [main] INFO org.apache.plc4x.java.PlcDriverManager - Instantiating new PLC Driver Manager with class loader jdk.internal.loader.ClassLoaders$AppClassLoader@77556fd [main] INFO org.apache.plc4x.java.PlcDriverManager - Registering available drivers... [main] INFO org.apache.plc4x.java.PlcDriverManager - Registering driver for Protocol s7 (Siemens S7 (Basic)) [main] INFO org.apache.plc4x.java.transport.tcp.TcpChannelFactory - Configuring Bootstrap with Configuration{local-rack=1, local-slot=1, remote-rack=0, remot-slot=0, pduSize=1024, maxAmqCaller=8, maxAmqCallee=8, controllerType='null'} [main] WARN org.apache.plc4x.java.scraper.triggeredscraper.triggerhandler.collector.TriggerCollectorImpl - The Triggered Scraper is intended to be used with a Pooled Connection. In other situations leaks could occur! [main] INFO org.apache.plc4x.java.PlcDriverManager - Instantiating new PLC Driver Manager with class loader jdk.internal.loader.ClassLoaders$AppClassLoader@77556fd [main] INFO org.apache.plc4x.java.PlcDriverManager - Registering available drivers... [main] INFO org.apache.plc4x.java.PlcDriverManager - Registering driver for Protocol s7 (Siemens S7 (Basic)) [main] INFO org.apache.plc4x.java.scraper.config.triggeredscraper.ScraperConfigurationTriggeredImpl - Assuming job as triggered job because triggerConfig has been set org.apache.plc4x.java.scraper.exception.ScraperConfigurationException: Null plc-trigger variable used at org.apache.plc4x.java.scraper.triggeredscraper.triggerhandler.TriggerConfiguration.validateDataType(TriggerConfiguration.java:167) at org.apache.plc4x.java.scraper.triggeredscraper.triggerhandler.TriggerConfiguration.access$200(TriggerConfiguration.java:37) at org.apache.plc4x.java.scraper.triggeredscraper.triggerhandler.TriggerConfiguration$TriggerElement.convertCompareValue(TriggerConfiguration.java:562) at org.apache.plc4x.java.scraper.triggeredscraper.triggerhandler.TriggerConfiguration$TriggerElement.(TriggerConfiguration.java:545) at org.apache.plc4x.java.scraper.triggeredscraper.triggerhandler.TriggerConfiguration.createConfiguration(TriggerConfiguration.java:386) at org.apache.plc4x.java.scraper.triggeredscraper.TriggeredScrapeJobImpl.(TriggeredScrapeJobImpl.java:42) at org.apache.plc4x.java.scraper.config.triggeredscraper.ScraperConfigurationTriggeredImpl.getJobs(ScraperConfigurationTriggeredImpl.java:99) at org.apache.plc4x.java.scraper.config.triggeredscraper.ScraperConfigurationTriggeredImpl.getJobs(ScraperConfigurationTriggeredImpl.java:88) at org.apache.plc4x.java.scraper.triggeredscraper.TriggeredScraperImpl.(TriggeredScraperImpl.java:95) at Test.main(Test.java:27) After some debugging it seems like the PlcField for the trigger is not set (so it's null). Anyone who worked on this has an idea? Or maybe I'm using the config file wrong, here is what I have: sources: S7: s7://192.168.178.10 jobs: - name: triggered-demo-job1 triggerConfig: (S7_TRIGGER_VAR,10,(%M200.0:BOOL)==(true)) sources: - S7 fields: test2: '%DB1.DBW2:INT' Etienne
Re: SPI Module - OSGi Bundle
My suggestion was; 1. Don't do the BundleTracker classes, and instead change to a bundle activator for each. 2. Add the "Bundle-Activator: org.apache.plc4x.java.osgi.DriverActivator" to the driver META/MANIFEST.MF 3. Do the equivalent for the Transports. public class DriverActivator implements BundleActivator { private ServiceRegistration reg; @Override public void start( BundleContext context ) throws Exception { Hashtable props = new Hashtable<>(); props.put( OsgiDriverManager.PROTOCOL_CODE, driver.getProtocolCode() ); props.put( OsgiDriverManager.PROTOCOL_NAME, driver.getProtocolName() ); reg = context.registerService( PlcDriver.class, driver, props ); } @Override public void stop( BundleContext context ) { context.unregisterService( reg ); } } On Wed, May 6, 2020 at 2:33 PM Etienne Robinet wrote: > Hi all, > So concretely what changes should be done so that a Driver/Transport > declares itself his service? Beside the changes in the manifest? > Etienne > On 2020/05/06 01:26:42, Niclas Hedhman wrote: > > Łukasz, > > > > the reason I say it is not very OSGi-y, is that the principle of OSGi is > > that the bundle handles its own service registrations. In the case of > JDBC > > (I initiated that spec, and I am the founder of OPS4J as well as Pax > > subproject, 2005), it needed to address the problem that JDBC drivers > > existed and changing their build and/or manifests was decided to be "not > > viable". The approach there is a work-around for legacy code, which I and > > Stuart McCulloch basically invented. IIRC, this happened in 2007. > > > > I didn't suggest that bundles require Declarative Services. I suggested > > that the "inside of the loop" in Etienne's code is put into an Activator, > > the code residing in the API and SPI bundles respectively, and that each > > driver/transport has a "Bundle-Activator: ." in the manifest > > referencing respective activator. It is not more intrusive than the > > Export-Package, Import-Package that will be required anyway. > > > > Advantages; It is more in the spirit of OSGi. But importantly, the > > driver/transport is now an active bundle, rather than a library bundle, > and > > in theory the start/stop of a bundle could (there might be other reasons > > why not) turn it on/off in runtime. If special needs pop up, maybe to > > deploy for the OpenHAB project, it is possible to override the > > driver/transport with hacking the API/SPI bundles. > > > > And I can't see any disadvantages other than "need to rework a bit of > code". > > > > But I don't have skin in the game. Not in OSGi, not here, so take my > > recommendations into consideration or throw them away. I just got the > > impression that you didn't really get what I suggested. > > > > > > // Niclas > > > > > > > > On Wed, May 6, 2020 at 4:57 AM Łukasz Dywicki > wrote: > > > > > Hey Etienne, that's awesome piece of work. I can test it! :-) > > > > > > I believe that's what Etienne code does it in a valid OSGi way. And I > do > > > believe not because he mentioned me by name, but due to below > > > argumentation. > > > > > > Proposed code uses extender pattern to grab specific META-INF/services > > > entries and register them in OSGi service registry. If you will take a > > > look on following line: > > > > > > > https://github.com/apache/plc4x/blob/feature/osgi/plc4j/api/src/main/java/org/apache/plc4x/java/osgi/ApiActivator.java#L63 > > > you will find that bundle is an jar which changes state to ACTIVE. > > > Additionally that bundle classloader is used to find services and that > > > bundle context is used to register services. In the end service which > > > appears looks like one registered by driver/transport module. > > > > > > The main point for above implementation is basic - getting the standard > > > PLC4X driver JAR working in OSGi without forcing it to knowing too much > > > about OSGi. Driver needs to ship manifest with import/export statements > > > and that's it. Additionally driver does not have to have a XML > > > descriptor which registers service. Quite many third parties might be > > > supplying drivers without any or with limited knowledge of OSGi. > > > Do drivers have to be a service? Well, it they can still be a valid > OSGi > > > service, registered using any other way! OSGi aware driver manager uses > > > OSGi services instead of static list own classloader to find > > > META-INF/services entries: > > > > > > > https://github.com/apache/plc4x/blob/feature/osgi/plc4j/api/src/main/java/org/apache/plc4x/java/osgi/OsgiDriverManager.java#L62 > > > > > > JDBC JARs are handled in such a way already in pax-jdbc. Take a look > here: > > > > > > > https://github.com/ops4j/org.ops4j.pax.jdbc/blob/master/pax-jdbc/src/main/java/org/ops4j/pax/jdbc/impl/Activator.java#L72 > > > Same or very similar code can be found in apache-camel, which brought > > > hundreds of components to OSGi, so I believe their way
Re: [PLC4C] Summary of API discussion on slack
Hi all, thanks to Otto's efforts now the C-API has it's equivalent to PlcValues ... Also has the API sort of matured to some state I think we no longer have to work on the "feature/c-api" branch and would like to merge this back to develop. In the end it's still in the sandbox alongside a lot of unfinished stuff ... so we're not treating it as a first-class citizen yet. What do you think? Chris Am 04.05.20, 19:44 schrieb "Christofer Dutz" : Ok ... after several days of working in the garden a new day with updates on PLC4C :-) So today I managed to finish and commit some changes that perform a full roundtrip of connection, read, disconnect using the "simulated" driver. Right now that only parses the address strings and returns a random int for every item .. this is not yet on-par with the java version of the simulated driver, but more a preview of the API we are planning to use for PLC4C. All asynchronous operations: - Connect - Read - Disconnect Are implemented using something we call "system-tasks" which I described in my last summary. All seems to be working nicely and I really like the structure of the code ... I know it will need quite a bit of cleaning up and I would be super grateful, if some C professionals could review what I have created. Constructive feedback is essential here for the continued work on this. Chris Am 29.04.20, 19:57 schrieb "Christofer Dutz" : Aaaand another update :-) So today I continued adding code-flesh to the empty API body. I implemented two basic data-structures: List and Queue (Noticing at the end that my queue isn't even needed). Starting from today the functionality for: connecting, reading, writing, etc. is implemented by callback functions generating so-called system_tasks. These are data-structures consisting of 4 properties: - a state-machine-function callback - an int representing the state-machine state the task is currently in - a pointer to a context data-structure (The state-machine controls what's in there) - a completed-flag that tells the system if a task is finished So now if a driver for example is asked to connect, it generates a system-task and that's added to the task-list. Then as soon as the system_loop function is called, this function goes through the list of queued system-tasks and for each calls the state-machine function if comes with and passes in the task as an argument. In the end the system loop checks If after executing the state-machine-function the task is marked as "completed" ... if it is it removes this task form the queue and continues with the next task in the list. The cool thing is that this way we can even ensure the system_loop function doesn't hog too much processing time ... so we could give the loop a maximum execution time and as soon as that's exceeded the function returns and the following tasks will be executed the next time the system_loop function is called. In this case I would probably change the task-list into a ring data-structure. Right now my example hello world program if correctly loading the "simulated" driver and a "dummy" transport and correctly connecting using the above mechanisms. Guess tomorrow I'll be writing string-parsers again to continue working on implementing the read/write operations on the simulated-driver. So far the update from today, Chris Am 28.04.20, 19:38 schrieb "Christofer Dutz" : Hi folks, even if this wasn't discussed as much as the other things we discussed, I still think it's important. So I was a strong advocate of the "promised land" ... I wanted to use promises and register callbacks for async execution. Theoretically this I cool ... however I had to notice it's cool as long as you have someone cleaning up for you. In most of the languages I encountered heavy usage of this pattern there are garbage collection mechanisms in place and then this is a great feature. In C however this is not the case. Here you have to manually free previously allocated memory and if you don't do that, you'll run out of it pretty soon. My main issue was that with promises it is difficulty to explicitly clean them up as you have no means to see which part of the program is still keeping a reference to it. If you clean that up and the other code access it, the failure depends on your OS but in all cases it's pretty bad. So I decided to undo the promises, I just introduced a few days earlier. To keep the code half-clean I decided to instead use some manual state-machine like code. Not much more to report besides the fact that I started implementing the actual logic. Up to now all methods sort of just returned empty or defa