HEADS-project / training

Training material to get started with the HEADS technologies
10 stars 16 forks source link

Integration with existing code #65

Closed kgiannakakisATC closed 9 years ago

kgiannakakisATC commented 9 years ago

I am still not sure how to integrate existing code. I have Java code that communicates with the Internet, parses XML files and extracts news items information. How am I supposed to add this in the workflow?

Should I generate the ThingML Java code and add it there? And how can I pass data (a String will do) between my code and ThingML?

brice-morin commented 9 years ago

I think the best way is to keep your existing code as it is, pretty much.

Then in ThingML, just define a port with one message (or several ports and messages depending on your needs) which takes a String as parameter.

In you ThingML configuration, just do not bind that port to anything. Then we'll generate automatically a Java (or Node.js) API. Then you can simply send this message to the ThingML generated code by calling a simple Java method (which will take a String as parameter). If you expect an answer from the ThingML generated code, you can also register your code as a listener of the ThingML code. You just need to modify code by implementing an interface (which will be called when the ThingML code sends a message) and update the generated Main to instantiate your own classes and register the listeners.

If you go through tutorial 3, you should get a better idea on how to do that.

So I would suggest (if not already done) that you start with tutorial 3, making sure you read all READMEs in details and do all the steps. And if you need more support, just notify me again.

kgiannakakisATC commented 9 years ago

Thanks for the answer. I have already gone through Tutorial 3 for Java. My ThingML generated code is:

public void doExecute(final Event e) { final Timer_timeoutMessageType.Timer_timeoutMessage ce = (Timer_timeoutMessageType.Timer_timeoutMessage) e; System.out.println("hello\n"); sendNews_item_via_news((String) ("hello")); }

This is where I want to hook my code (sendNews_item_via_news). Is this the correct workflow:

1) Generate ThingML Java code 2) Modify the generated project to add my code 3) Generate the Kevoree code from HEADS IDE

It is the order of 2 and 3 that confuses me.

brice-morin commented 9 years ago

OK, then what I propose:

  1. From your ThingML: Generate Java code, wrap it automatically in Kevoree and DO NOT modify it. Note that your ThingML configuration will be incomplete with one port not connected, but this is fine, as it will be connected later by Kevoree.
  2. Modify (or wrap) manually your existing code to "kevorize" it (add the proper annotations, etc to define your components, ports, etc) as you have learned in Section 3
  3. In your project, which you have kevorized in 2., load the sources of the ThingML/kevoree code defined in 1. by adding:` absolute path to the /java/target/classes of project 1. after you have generated all the code and run mvn clean install ` into its POM.XML file
  4. In project 2. update the kevscript to bing your own component to the component generated by ThingML

Tell me if some steps are not clear or if you have problem implementing them

kgiannakakisATC commented 9 years ago

Thanks again. I have now a question regarding timers, which is an important component of my logic. Should I use a ThingML timer or start a java thread timer in Kevoree?

brice-morin commented 9 years ago

Well, it is both a simple and a complex question :-)

Here are some guidelines:

Hope this helps.

kgiannakakisATC commented 9 years ago

Thanks, I am starting to get the gist of it. This is another question now :-)

In step you are saying to create the ports in the Kevoree project. I assume this means that I won't use the HEADS IDE ThingML to Kevoree functionality.

If I don't do that, how do I connect ThingML ports with Kevoree ports?

brice-morin commented 9 years ago

Yes, you can use the HEADS IDE. All you need is

Then everything is Kevorized and you should be able to connect them together. However, to make both sets of Kevoree components aware of each others, you need to "import" the components generated by ThingML into your other project (as I indicated a few message above, by updating your POM.XML)

kgiannakakisATC commented 9 years ago

OK, I think I understand the how now. However, I am still missing the why. What benefits does working first in ThingML has to offer? Why couldn't we just create everything in Kevoree?

brice-morin commented 9 years ago

I guess @ffleurey could write pages and pages here :-)

The benefits of using ThingML typically show when:

kgiannakakisATC commented 9 years ago

OK I get the point. Regarding our contribution there is the requirement "At least two ThingML configurations should be compiled to two Kevoree components". Does it make a difference if I have all my instances in a single configuration than to have them is separate ones?

brice-morin commented 9 years ago

Yes, it does. See this README which explains how ThingML configurations are mapped to Kevoree components.

Basically, all instances defined in one ThingML configuration are merged into one Kevoree component.

kgiannakakisATC commented 9 years ago

OK, I will have my things in different configurations for maximum flexibility. One more question I have is how to share ports between ThingML and Kevoree. This is my scenario:

My question is how to connect the sender with receiver. I want the server to be able to receive timer events from the ThingML timer. When this happens, I want to call custom code, get a list of news items and forward them to a ThingML port for the Receiver to get them.

brice-morin commented 9 years ago

Well, in the end, everythinv will be Kevoree components. You can just connect ports in the Kevoree editor. Typically, Kevoree components generated from ThingML send and receive a JSON string serializing the message. You can try to insert printlns to see when sending or receiving messge to see how the JSON will look like.

kgiannakakisATC commented 9 years ago

I've decided to implement Timer and Receiver in ThingML and Sender in Kevoree. This is a part of my Kevoree pom.xml:

<plugin>
    <groupId>org.kevoree.tools</groupId>
    <artifactId>org.kevoree.tools.mavenplugin</artifactId>
    <version>${kevoree.version}</version>
    <extensions>true</extensions>
    <executions>
        <execution>
            <goals>
                <goal>generate</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <mergeLocalLibraries>
            <mergeLocalLibrary>C:\Users\KGiannakakis\Documents\GitHub\training\3.Wrapping_ThingML_into_Kevoree\3.3_Contrib\ATC\ThingML\Timer\thingml-gen\java\target\classes</mergeLocalLibrary>
            <mergeLocalLibrary>C:\Users\KGiannakakis\Documents\GitHub\training\3.Wrapping_ThingML_into_Kevoree\3.3_Contrib\ATC\ThingML\Receiver\thingml-gen\java\target\classes</mergeLocalLibrary>
        </mergeLocalLibraries>
        <nodename>node0</nodename>
        <model>src/main/kevs/main.kevs</model>
    </configuration>
</plugin>

I then have this in my kevs file:

add node0 : JavaNode
add node0.Timer : org.thingml.generated.kevoree.KTimer
add node0.Receiver : org.thingml.generated.kevoree.KReceiver
add node0.Sender : gr.atc.heads.Sender

However, when I try to run it, I get:

00:03 WARN: Try to select snapshot in best effort mode for org.thingml.generated.kevoree.KTimer
java.lang.Exception: TypeDefinition not found with : org.thingml.generated.kevoree.KTimer and version null in 0 selected
        at org.kevoree.kevscript.util.TypeDefinitionResolver.resolve(TypeDefinitionResolver.java:124)
kgiannakakisATC commented 9 years ago

Also, do I really need to use absolute paths? Using relative paths would be more convenient.

brice-morin commented 9 years ago

It seems it is now @maxleiko who should help you for the Kevoree part (he will be back from holidays on Monday, I think).

Can you check that in the local libraries that you included in your POM.XML you have a KEV-INF folder in target/classes? If not, make sure you mvn clean install after you have generated the Kevoree code for the ThingML components.

brice-morin commented 9 years ago

@maxleiko : For paths to the library, maybe it should be possible to point to jar installed in the local .m2, which contains all the classes and kevscripts? Then we would just need to specify group-artifactID and version number and Kevoree can seek in the .m2 folder

brice-morin commented 9 years ago

@kgiannakakisATC should we consider this issue closed? Did you get enough information to do what you want to do?

If the paths for the merged libraries is a critical issue, I would recommend opening a separate new one.

maxleiko commented 9 years ago

There is no problem on paths, you can use relative or absolute ones.
Your problem here is that you are using Kevoree 5.2.5 I guess, and the new feature of mergeLocalLibraries is a feature I have made for @sdalgard that I did not released yet.
The only way to use this feature for now is to add sonatype snapshots repositories to your pom.xml and to set the Kevoree plugin version to 5.2.6-SNAPSHOT

Something like:

<build>
    <plugins>
        <!-- Kevoree plugin -->
        <plugin>
            <groupId>org.kevoree.tools</groupId>
            <artifactId>org.kevoree.tools.mavenplugin</artifactId>
            <version>5.2.6-SNAPSHOT</version>
            <extensions>true</extensions>
            <executions>
                <execution>
                    <goals>
                        <goal>generate</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <mergeLocalLibraries>
                    <mergeLocalLibrary>../relative/path/to/another/lib/target/classes</mergeLocalLibrary>
                    <mergeLocalLibrary>/absolute/path/to/yet/another/lib/target/classes</mergeLocalLibrary>
                </mergeLocalLibraries>
            </configuration>
        </plugin>
    </plugins>
</build>

<pluginRepositories>
    <pluginRepository>
        <id>plugin.kevoree-oss</id>
        <url>https://oss.sonatype.org/content/groups/public/</url>
    </pluginRepository>
</pluginRepositories>
maxleiko commented 9 years ago

(I wanted to do some more testing before releasing it in 5.2.6)

kgiannakakisATC commented 9 years ago

Thanks for the help. Should I download a new IDE or do the pom.xml changes suffice?

maxleiko commented 9 years ago

pom.xml changes are enough

kgiannakakisATC commented 9 years ago

Thank you both of you. Of course you can consider the issue as closed.