-
-
Notifications
You must be signed in to change notification settings - Fork 428
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[automation] Ensure unique module IDs for overloaded @RuleAction
methods
#4441
Conversation
Append signature hash to avoid duplicate module ids. Signed-off-by: Florian Hotze <[email protected]>
Signed-off-by: Florian Hotze <[email protected]>
@J-N-K This implements an alternative solution that ensures unique, predictable module IDs for Thing actions by hashing the method signature. Can you please have a look so we can get this into M3 and test it before M3? |
This was wat I meant with #4438 (comment) |
clazz.getSimpleName(), method.getName()); | ||
String signature = Arrays.stream(method.getParameterTypes()).map(Class::getName) | ||
.collect(Collectors.joining(",")); | ||
uid += "#" + signature.hashCode(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.hashCode()
could create collisions, maybe something like
MessageDigest md5 = MessageDigest.getInstance("MD5");
Arrays.stream(methos,getParameterTypes()).forEach(t -> md5.update(t.getName().getBytes()));
uid += String.format("#%032x", new BigInteger(1, md5.digest()));
BTW: Why don't we do that for each method? That would make the need to check if there are overloads unnecessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good question. It is not really required, but thinking about it, it will be beneficial if one adds an overload for a method in the future as the id of the existing method won't change.
I will look into the "real" hashing.
@@ -166,13 +171,12 @@ public Response getActions(@PathParam("thingUID") @Parameter(description = "thin | |||
ThingActions thingActions = thingActionsEntry.getValue(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For performance reasons I would suggest to split this:
- the first part of the loop (l. 174 to 159) which is time-consuming and static (after the methods of a given
ThingActions
will never change) should be done when theThingActions
are added (and stored in something that allows to remove them when theThingActions
is removed) - the second part (checking of action type and condig description) should take place here as it depends on the availability of these in the registries (which is dynamic)
This can be refactored later if you find it too complicated now.
Signed-off-by: Florian Hotze <[email protected]>
@J-N-K I implemented hashing for all methods, now the tests are failing and I can't find the reason. |
I guess the test fails because the action UID now contains the hash and the test is against |
I modified the test to contain the hash in the TEST_ACTION_TYPE_ID. |
I checked out your branch and modified the test:
so the hash is missing in the expected value. |
Signed-off-by: Florian Hotze <[email protected]>
018ba94
to
ca6bdfb
Compare
@J-N-K Fixed this test - did not notice at first that there are two different tests. |
Is the class considered in the hash ? |
No, but we have the method name and the action scope inside the name, so I hope that’s enough. |
Within the same scope there should never be methods with the same signature. Is there any binding where this is the case? |
For the compiler the scope would be class level, for this annotation/PR it would be binding level? So i guess it is a matter of time before a collision occurs, better safe now to add the class name to the hashing. |
Signed-off-by: Florian Hotze <[email protected]>
I added the classname to the hash. I am unavailable this evening, so feel free to revert it if you want to merge tonight. |
For openHAB the scope is not the class but the defined scope ( Adding it doesn't hurt though. I'm finde with that. What has to be investigated though is why the tests seem to be unstable, this time |
Several bindings are doing that. |
Then these bindings should be fixed. |
This reverts commit 33ced98. Signed-off-by: Florian Hotze <[email protected]>
As more than one class per scope will fail in all scripting add-ons and should not be the case, I will revert because not having the class name keeps the code a bit simpler. |
Signed-off-by: Florian Hotze <[email protected]>
@J-N-K I have been able to stabilise the tests, can you please have a look at this PR so we can get it into M3? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@florian-h05 Sorry, just technical questions:
- Should we still use MD5? Today I would assume SHA-256 is standard.... (I know, the data to be protected is nothing critical, but I would assume that performance is not too different on such short strings)
- Does it make sense to cache the instance you get from the MD5.getInstance call? I have no experience here, but it might go deep into the crypto providers to get the instance.
Sorry adding noise.
SHA1/MD5: probably doesn't matter much, but according according to various sources SHA-256 has about 40% of the hash rate compared to MD5. SHA-256 also has a longer hash, so added overhead during REST calls (probably doesn't matter as well). Regarding hash quality and collision rate MD5 is probably already over-kill, but it's a algorithm that is easily available in Java. The instance should not be cached, it is not thread-safe and different |
SHA256 hash is twice longer (256 bit vs 128 bit) and a bit slower. Security doesn't matter in that case, that bit of speed difference is nice though.
Given the small amount of data to be hashed I don't think we need that, and I don't know how that should be done. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, just re-running the CI builds to be sure.
Supersedes #4438.
This appends a method signature hash to
@RuleAction
methods which have overloades to ensure module IDs are unique.It also returns the visibility for Thing actions from the REST API.