Open style95 opened 7 years ago
yes it is badly needed.
Using the Openwhisk swagger definition I tried to create a Java Client Library myself, details can be found here
Unfortunately Swagger code generation can not cope with properties having no type, as in:
"KeyValue": {
"required": [
"key",
"value"
],
"properties": {
"key": {
"type": "string"
},
"value": {
"description": "Any JSON value"
}
}
}
The resulting KeyValue class only has a key
and no value
.
So I probably need to customize a swagger template file to achieve a usable KeyValue class.
@misl if we just "fix" the swagger by adding types do you think the swagger-codegen will work?
I've looked at this a bit and I can't find a way to correctly specify the type here that works for all clients. You can specify a type of "object" that works for the Java client but fails some of the existing schema validation specs because a Swagger object is really a bit different than allowing any valid JSON type. If we upgrade to OpenAPI 3 here instead of Swagger 2 some of the new anyOf/oneOf keywords may help. Or, we could try to "fix" and/or try a newer version of swagger-codegen to see if this is an issue they've fixed.
I partially agree with @bbrowning. OpenAPI 3 has extra features (anyOf / oneOf) to better specify the KeyValue structure. But the Swagger CodeGen for OpenAPI 3 has not yet been released. I don't when this will be finished.
Swagger 2 however still can be used. It is possible to customize the underlying template. Since KeyValue is the only structure with type Object in there. There will probably be no side effects.
Is my custom Openwhisk Java Client I gave the following a try:
"KeyValue": {
"required": [
"key",
"value"
],
"properties": {
"key": {
"type": "string"
},
"value": {
"type": "object",
"description": "Any JSON value"
}
}
},
Unfortunately every action invocation gives me a bad request. But this is due to retrofit automatically URL encoding the slash after the package name in the actionName:
@POST("namespaces/{namespace}/actions/{actionName}")
Call<Activation> invokeAction(
@Path("namespace") String namespace, @Path("actionName") String actionName, @Body KeyValue payload, @Query("blocking") String blocking, @Query("result") String result, @Query("timeout") Integer timeout
);
I see 2 possible option around this:
encoding = false
to the @Path annotation. Side effect would be that other special characters in the actionName are no longer URL encoded. (Question: are special characters allowed in package and action names?)@POST("namespaces/{namespace}/actions/{actionName}")
to
@POST("namespaces/{namespace}/actions/{packageName}/{actionName}")
What would be the best option? Currently I favor 2.
Separating packageName (see change) like mentioned in my previous comment results in a genarated openwhisk java client which allows me to invoke (no argument) actions. This time I get back a 202.
I am still investigation whether sending arguments resutls in expected behaviour.
Hmm, I seem to be able to invoke an action but somehow it does not show up in my activation log :-(
I get the following response from my invocation:
Response{
protocol=http/1.1,
code=202,
message=Accepted,
url=https://openwhisk.ng.bluemix.net/api/v1/namespaces/waitr_DEV/actions/traeckit.tenants/debug
}
My request looks just fine:
Request{
method=POST,
url=https://openwhisk.ng.bluemix.net/api/v1/namespaces/waitr_DEV/actions/traeckit.tenants/debug,
tag=Request{
method=POST,
url=https://openwhisk.ng.bluemix.net/api/v1/namespaces/waitr_DEV/actions/traeckit.tenants/debug,
tag=null
}
body={
content={"key":"params","value":"hallo"}
type=application/json; charset=UTF-8
}
}
Anyone a clue?
If you have an activation id, you can fetch by id. If you're using wsk activation list
or using the UI, indexing the new activations may take a little bit of time.
Note that for actions not in packages, the URL is
@POST("namespaces/{namespace}/actions/{actionName}")
and not this
@POST("namespaces/{namespace}/actions/{packageName}/{actionName}")
Made packageName optional, but still have to test.
Okay I got another step further. The reason I got a 202 is because I didn't tell it to do a blocking request. I figured this out by comparing wsk -v results with my own output: wsk -v --> https://openwhisk.ng.bluemix.net/api/v1/namespaces/waitr_DEV/actions/traeckit.tenants/debug?blocking=true&result=true java api --> https://openwhisk.ng.bluemix.net/api/v1/namespaces/waitr_DEV/actions/traeckit.tenants/debug
Modifying the request:
openwhisk.actions().invokeAction( namespace, packageName, actionName, parameters, null, null, null)
into
openwhisk.actions().invokeAction( namespace, packageName, actionName, parameters, "true", "true", null)
Gave me a 200 response, yeah!
The next thing troubling me is the actual response message. The wsk based invoke gives response data that I can NOT find in my java api based invoke.
The expected data was not received due to setting the result query parameter to true
. According to swagger definition:
...
{
"name": "result",
"in": "query",
"description": "Return only the result of a blocking activation. Default is false.",
"required": false,
"type": "string",
"enum": [
"true",
"false"
]
},
...
Even though I was doing a blocking call, I still had to set it to false
to get the activation details.
This brought a little further, but parsing the activation/response resulted into an exception. For this to parse correctly I had to make another modification to the swagger file.
"logs": {
"type": "array",
"description": "Logs generated by the activation",
"type": "string"
}
Had to become:
"logs": {
"type": "array",
"description": "Logs generated by the activation",
"items": {
"type": "string"
}
}
Doing this in 2 different places made the response parse correctly.
Looking at the response in more details it looks like there is another mismatch in the api specification. The activation.result
(from the specification) is not present in the response but activation.response
(unspecified) is. Below is an example response I got during testing:
"response":{
"result":{
"id":"123",
"Name":"name"
},
"success":true,
"status":"success"
}
Any news about this? Any published artifacts?
There isn't any official Java client yet, but as a followup to updating the Swagger spec in #3878 I'm hoping we can get an autogenerated via Swagger Codegen Java client working soon.
I am really expecting this, so we can start creating some integration tools for openwhisk such as maven, gradle plugins, arquillian cube integration, ....
I wanted to give a heads up that I’m starting work on building out a java client based on the swagger spec as part of the work we’re doing at Red Hat. The repo can be found here for now: https://github.com/projectodd/openwhisk-client-java it’s fairly bare bones at the moment but has working action invocation via the generated swagger client. Now that I have some of the pieces in place, i hope to iterate very quickly on it.
@evanchooly is your repo usable? It seems the Maven artifacts don't contain any jar
it was last I tried it. Where are you looking for jars?
https://search.maven.org/artifact/org.projectodd.openwhisk/openwhisk-client-java/0.5/pom
Thanks for the swift reply! I looked here: http://central.maven.org/maven2/org/projectodd/openwhisk/openwhisk-client-java/0.5/
looks like there are some weird warts in those poms. check here: http://central.maven.org/maven2/org/projectodd/openwhisk/client/0.5/
Ah, that's because that's not the same artifact name. Thanks a lot!
@evanchooly I started a Gradle plugin based on your Java client: https://github.com/vic-cw/openwhisk-gradle-plugin. Hope that makes you happy :)
@lordofthejars I also wanted to give you a heads up since you previously voiced the idea of such a tool.
Feel free to take a look at this first version. I would love to have your thoughts on it!
Hrm. Perhaps I should work on this then. :) Last I checked the openapi spec was woefully out of sync with the actual implementation, though.
@evanchooly I made a few pull requests on your repo, to fix some bugs and add support for some features
We need OpenWhisk java client library. It will provide features just like other libraries. (ex: javascript client sdk)