EdgeLab-FHDO / Edge-Diagnostic-Platform

MIT License
0 stars 2 forks source link

Rest refactor #73

Closed juan-castrillon closed 3 years ago

juan-castrillon commented 3 years ago

Initial commit ot eventually solving #57

There are still things missing, but as of right now I've implemented:

Right now, is too much of a sketch, names will be changed and the past implementation is still there. Also tests are missing. However, is working (I did manual tests with postman).

I would like to know which feature I am missing. For example the thing we discussed with replacement strings in the input is not clear to me, could you maybe give me an example of how that would look like @alyhasansakr ?

alyhasansakr commented 3 years ago

@juan-castrillon That is the first part of what we agreed to do, the other part is to allow providing JSON elements as replacement strings. So instead of just test $json you should be able to write test $id $name where id and name are elements of the sent JSON string. Of course it is limited to just the basic types (no objects and no arrays), but most use cases are just like that.

juan-castrillon commented 3 years ago

In these last commits:

Right now the desired functionality is working. With configuration as shown below, and sending the following request to the path localhost:4897/post_test:

{
  "name": "example",
  "number": 874
}

Configuration:

{
  "ioData": {
      "inputs": [
        {"type": "ConsoleInput","name": "console_in"},
        {"type": "GenericPOST","name": "rest_in","address": "/post_test","port": 4897,
          "command" :  "test $name $number",
          "information": ["name", "number"],
          "@IOType" : "CustomCommand"
        }
      ],
      "outputs": [
        {"type": "ConsoleOutput","name": "console_out"},
        {"type": "GenericGET","name": "get", "address": "/get_test","port": 4897},
        {"type": "MasterUtility","name": "util"}
      ]
    },
  "connections" : [
    {
      "in" : "console_in",
      "out" : "util",
      "commands" : {
        "exit" : "util exit",
        "start_rest_server" : "util runRunner RestServer",
        "start_runner $runner_name" : "util runRunner $runner_name"
      }
    },
    {
      "in" : "console_in",
      "out" : "get",
      "commands" : {
        "get_test" : "toGet resource {\"name\": \"example\",\n\"number\": 874}"
      }
    },
    {
      "in" : "rest_in",
      "out" : "console_out",
      "commands" : {
        "test $name $number" : "console $name $number"
      }
    }
  ]
}

The result on the console is

example 874

Missing are of course the automated test, but before that I wanted to make sure, nothing else is missing 😄

alyhasansakr commented 3 years ago

It looks good, but how do we define more than one resource here? lets say I want another resource on address "/post_test_1" on the same port, do I just write another input?

juan-castrillon commented 3 years ago

Right now, yes, although I will have to modify the code to make sure the rest server is just started once. Is that ok? Or should it just be one input and make possible different paths?

I decided for this way, as it allows to refer to each input separately in the connections, so we dont need to connect all rest inputs to one output but just the one it needs.

alyhasansakr commented 3 years ago

For now that should be enough, but after Modules are implemented we should have another look here.

juan-castrillon commented 3 years ago

It is almost ready for review. New features and things done in these commits include:

Missing are: -Testing correctly the configuring via run argument in the master

alyhasansakr commented 3 years ago

I don't believe a FIFO at the output is necessary, once a resource is put there it should stay until next modification.

juan-castrillon commented 3 years ago

In the last commits, I did all that was missing in my last comment (Except for cleaning the master, which I figured will do after the review)

I believe is ready for review

juan-castrillon commented 3 years ago

@alyhasansakr You are probably right but just for the sake of me learning would you mind helping me understand why? After doing some research, The way I see it both ways are ensuring mutual exclusive access to the resource and the only difference I can see is that semaphores would eventually allow more threads to access but a binary semaphore takes that away.

alyhasansakr commented 3 years ago

@juan-castrillon Correct, they are exactly the same in our case. Actually, Semaphores implementation potentially uses synchronized blocks. Semaphores add fairness and multi-access (for non-binary), but this is not the reason. The reason is that you don't need to implement the waiting logic (while loops and stuff) you just need to call acquire and release functions. In short, synchronized blocks is the low level solution while Semaphores is the high level solution.

juan-castrillon commented 3 years ago

Thanks for the help @alyhasansakr. In the last commits I changed the sync blocks (both in the blocking inputs and in the syncronization with the RestServer and IOs) to semaphores. You were right, it simplifies the code.

On a side note I realize that now MasterInput can be an abstract class instead of an interface and the semaphore (and blocking methods) can be abstracted there, however, as we still have components that are both MasterInput and MasterOutput and java doesnt allow multi-inheritance, I say we wait to do this until implementing the modules refactor where that (both I and O) will no longer be the case. What do you say?

alyhasansakr commented 3 years ago

Yes, this changes and more should be done as part of the new modules refactoring.