marat-gainullin / platypus-js

Apache License 2.0
9 stars 9 forks source link

Validator Module #95

Open valeriy-maslov opened 7 years ago

valeriy-maslov commented 7 years ago

Simple questions. Is @validator annotation accept name of datasource defined in context.xml or accept name of platypus entity, e.g. query name? Is it possible to create separated validator for single query?

marat-gainullin commented 7 years ago

No. It is not possible. You can allways inspect entity property of changelog item and select a specific module and call its methods.

valeriy-maslov commented 7 years ago

Understood. I also wanna say that we tried to implement validator last week but it throws an error. I will post stack trace at monday, when will be in office.

valeriy-maslov commented 7 years ago

This is what happens after trying to save any change log in application which contains empty template validator (validate() function just make a log entry, @validator annotation without specified data source name). Tested with making some data changes and sending it back to the server. After that changes are not saved.

12-Sep-2016 09:27:57.068 SEVERE [platypus-worker-pool-1-thread-25] com.eas.client.DatabasesClient.lambda$commit$26 null
 com.eas.script.NoPublisherException: JavaScript API integrity check failed. No publisher function.
    at com.eas.client.changes.Update.getPublished(Update.java:53)
    at com.eas.script.Scripts$Space.toJs(Scripts.java:493)
    at com.eas.script.Scripts$Space.toJs(Scripts.java:502)
    at com.eas.client.ScriptedDatabasesClient.lambda$validate$2(ScriptedDatabasesClient.java:179)
    at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1374)
    at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:580)
    at com.eas.client.ScriptedDatabasesClient.validate(ScriptedDatabasesClient.java:177)
    at com.eas.client.ScriptedDatabasesClient.apply(ScriptedDatabasesClient.java:83)
    at com.eas.client.DatabasesClient.lambda$commit$26(DatabasesClient.java:500)
    at java.util.HashMap$EntrySpliterator.forEachRemaining(HashMap.java:1691)
    at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:580)
    at com.eas.client.DatabasesClient.commit(DatabasesClient.java:498)
    at com.eas.server.handlers.CommitRequestHandler.lambda$handle$1(CommitRequestHandler.java:139)
    at com.eas.server.handlers.CommitRequestHandler$ChangesSortProcess.complete(CommitRequestHandler.java:117)
    at com.eas.server.handlers.CommitRequestHandler.lambda$null$2(CommitRequestHandler.java:161)
    at com.eas.client.queries.LocalQueriesProxy.lambda$getQuery$1(LocalQueriesProxy.java:90)
    at com.eas.script.Scripts$Space.lambda$process$3(Scripts.java:667)
    at com.eas.script.Scripts$Space.lambda$process$4(Scripts.java:703)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
marat-gainullin commented 7 years ago

Ensure please, that you have dependencies from update.js, insert.js, delete.js, command.js modules in your validator. May be we should fix validator module template.

Also, can you clarify if global API is used by your application?

valeriy-maslov commented 7 years ago

Nope, AMD is used right now

marat-gainullin commented 7 years ago

And how about dependencies, mentioned earlier?

valeriy-maslov commented 7 years ago

Dependecies have written down just about 1 minute ago. There was also added @stateless annotation. And it works fine right now. Looks like fixing validator template is the fastest way. Thanks.

marat-gainullin commented 7 years ago

How do you think, should we add auto dependencies injection in Platypus.js code to avoid "unused" dependencies?

valeriy-maslov commented 7 years ago

@marat-gainullin it better to be. But may be there is another way like checking with annotations in specific types of modules like validator. E.g. we have core/update, core/insert etc. dependencies. Is it possible to force platypus inject they stealthy like user never know it's used. Like it happens with global API P.*. Is it possible?

valeriy-maslov commented 7 years ago

Okay, there is another validator issue. Here is stacktrace

15-Sep-2016 10:38:31.017 SEVERE [platypus-worker-pool-1-thread-15] com.eas.client.DatabasesClient.lambda$commit$26 null
 com.eas.script.NoPublisherException: JavaScript API integrity check failed. No publisher function.
    at com.eas.client.changes.ChangeValue.getPublished(ChangeValue.java:52)
    at jdk.nashorn.internal.scripts.Script$Recompilation$78$1685A$boxing.L:3$boxAsJs(boxing:56)
    at jdk.nashorn.internal.scripts.Script$Recompilation$78$1685A$boxing.L:3$boxAsJs(boxing:70)
    at jdk.nashorn.internal.scripts.Script$Recompilation$77$888$update.L:3$Update$get(core/update:32)
    at jdk.nashorn.internal.runtime.UserAccessorProperty.invokeObjectGetter(UserAccessorProperty.java:290)
    at jdk.nashorn.internal.runtime.UserAccessorProperty.getObjectValue(UserAccessorProperty.java:196)
    at jdk.nashorn.internal.runtime.FindProperty.getObjectValue(FindProperty.java:229)
    at jdk.nashorn.internal.runtime.ScriptObject.get(ScriptObject.java:2860)
    at jdk.nashorn.internal.runtime.ScriptObject.get(ScriptObject.java:2877)
    at jdk.nashorn.internal.objects.NativeJSON.str(NativeJSON.java:214)
    at jdk.nashorn.internal.objects.NativeJSON.JO(NativeJSON.java:290)
    at jdk.nashorn.internal.objects.NativeJSON.str(NativeJSON.java:268)
    at jdk.nashorn.internal.objects.NativeJSON.stringify(NativeJSON.java:196)
    at jdk.nashorn.internal.scripts.Script$Recompilation$75$1237AAAA$GlobalServerValidator.L:8$module_constructor$validate(Сервер/Валидаторы/GlobalServerValidator:22)
    at jdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:645)
    at jdk.nashorn.internal.runtime.ScriptFunction.invoke(ScriptFunction.java:494)
    at jdk.nashorn.internal.runtime.ScriptRuntime.apply(ScriptRuntime.java:393)
    at jdk.nashorn.api.scripting.ScriptObjectMirror.call(ScriptObjectMirror.java:117)
    at com.eas.client.ScriptedDatabasesClient.lambda$validate$2(ScriptedDatabasesClient.java:179)
    at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1374)
    at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:580)
    at com.eas.client.ScriptedDatabasesClient.validate(ScriptedDatabasesClient.java:177)
    at com.eas.client.ScriptedDatabasesClient.apply(ScriptedDatabasesClient.java:83)
    at com.eas.client.DatabasesClient.lambda$commit$26(DatabasesClient.java:500)
    at java.util.HashMap$EntrySpliterator.forEachRemaining(HashMap.java:1691)
    at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:580)
    at com.eas.client.DatabasesClient.commit(DatabasesClient.java:498)
    at com.eas.server.handlers.CommitRequestHandler.lambda$handle$1(CommitRequestHandler.java:139)
    at com.eas.server.handlers.CommitRequestHandler$ChangesSortProcess.complete(CommitRequestHandler.java:117)
    at com.eas.server.handlers.CommitRequestHandler.lambda$null$2(CommitRequestHandler.java:161)
    at com.eas.client.queries.LocalQueriesProxy.lambda$getQuery$1(LocalQueriesProxy.java:90)
    at com.eas.script.Scripts$Space.lambda$process$3(Scripts.java:667)
    at com.eas.script.Scripts$Space.lambda$process$4(Scripts.java:703)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

This happens when I try to access change log inside validator. The funny thing about that is this template code works fine:

this.validate = function (aLog, aDatasource, aOnSuccess, aOnFailure) {
            Logger.info("GlobalServerValidator. aLog.length: " + aLog.length + "; aDatasource: " + aDatasource + ";");
            if (aOnSuccess) {
                // TODO: place your asynchronous validation code here
            } else {
                // TODO: place your synchronous validation code here
            }
        };

This works fine and prints out this:

15-Sep-2016 10:38:30.975 INFO [platypus-worker-pool-1-thread-15] jdk.nashorn.internal.scripts.Script$Recompilation$76$2129A$logger.L:3$value-3 GlobalServerValidator. aLog.length: 1; aDatasource: tk;

But if I try to access aLog, it fails with stacktrace posted at the begining. E.g. eve this simple code fails:

Logger.info(JSON.stringify(aLog[0]));
marat-gainullin commented 7 years ago

It is because aLog is native Java array, not js array. And so it can't be JSONed. Try Java.from(aLog) before JSON.stringify(...). Also, try to add dependency change-value.js to the validator module.

valeriy-maslov commented 7 years ago

Works fine now with core/change-value.

marat-gainullin commented 7 years ago

JSON.stringify doesn't work with non enumerable properties (e.g. Update.keys). It skips such properties and generates '{}' text for objects with none of enumerable properties. The changeling entries have non enumerable properties. So, you should develop your own JSON-er or take one already implemented in Platypus.js low level code.

valeriy-maslov commented 7 years ago

Validator still laughing at me :( This code runs exactly as it is written here.

var log = Java.from(aLog); //Cause aLog is native
var action = log[0]; //First element
Logger.info(JSON.stringify(action)); //This prints 'undefined'
Logger.info(JSON.stringify(action.entity)); //And this prints correct name of entity

How can it be possible?

marat-gainullin commented 7 years ago

It is because JSON.stringify() works only with native JS objects. Anyway this situation is to be investigated.

valeriy-maslov commented 7 years ago

Another funny thing

var log = Java.from(aLog); //Cause aLog is native
Logger.info(JSON.stringify(log)); //Prints correct JSON object structure