I am trying to make swagger document my API composed of Jersey-spring 2.22.2 with Spring 4.3 and Jackson 2.22.2.
The swagger package I'm using is:
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-jersey2-jaxrs</artifactId>
<scope>compile</scope>
<version>1.5.12</version>
</dependency>
one of endpoint declaration:
#POST
#ApiOperation(
value = "creates folder hierarchy type client|lead",
notes = "creates folder hierarchy type client|lead"
)
#ApiResponses(value = {
#ApiResponse(code = 200, message = "creation successfull")
})
#Path("create_type")
#Consumes(MediaType.MULTIPART_FORM_DATA)
public Response createHierarchy(
#ApiParam(value = "hierarchy type", required = true) #NotNull #FormDataParam("type") EHierarchyType hierarchyType,
#ApiParam(value = "parametric part of the hierarchy", required = true) #NotNull #FormDataParam("params") Map<String, Folder2> folderMap
) throws ItemExistsException, AccessDeniedException, PathNotFoundException, WebserviceException, RepositoryException, DatabaseException, ExtensionException, AutomationException, UnknowException, IOException, UserQuotaExceededException, LockException, VersionException {
StopWatch stopWatch = new StopWatch();
folderCtrl.createHierarchy(folderMap, hierarchyType);
logger.info("create hierarchy took: " + stopWatch.getElapsedTime());
return Response.ok().build();
}
and this is how the generated json looks like for this endpoint:
"/folder/create_type" : {
"post" : {
"tags" : [ "folder" ],
"summary" : "creates folder hierarchy type client|lead",
"description" : "creates folder hierarchy type client|lead",
"operationId" : "createHierarchy",
"consumes" : [ "multipart/form-data" ],
"parameters" : [ {
"name" : "type",
"in" : "formData",
"description" : "hierarchy type",
"required" : true,
"type" : "string",
"enum" : [ "CLIENT", "LEAD" ]
}, {
"name" : "params",
"in" : "formData",
"description" : "parametric part of the hierarchy",
"required" : true,
"type" : "object"
} ],
"responses" : {
"200" : {
"description" : "creation successfull"
}
}
}
}
when I try to parse this output in swagger editor it returns error back, and I think the reason might be that in "paramas" names parameter it has created its type of object instead of schema. My point here is to find out why? Is it some bug in swagger or it's me that missed something?
Also, on the another endpoint I have, there is #FormDataParam that is an pojo model object annotated with #ApiModel. This is translated by swagger as of type 'ref' but it doesn't gives user any other clue of what this object is or which fields it should contain. In Swagger-UI I see just 'undefined' as param type. This is not much informing. What I need to do in order to see the object's structure and to supply it's json definition as an example to try in ui?
Thanks
This answer contains examples of how the final Swagger spec should look like, but I don't know how to express that using Swagger #annotations. Hope this gives you some ideas anyway.
In Swagger 2.0, there is no straightforward way to have file + object in request body – form parameters can be primitive values, arrays and files but not objects, and body parameters support objects but not files (although you can try representing files as type: string – more on that below).
The next version, OpenAPI Specification 3.0 (which is RC at the time of writing) will support request body containing files + objects – check this example. I assume #annotations will be updated to support that too.
For now you have a couple of options.
1) One possible way is to pass the file contents as a binary string as part of the body parameter. Your API spec would look like:
paths:
/something:
post:
consumes:
- application/json
parameters:
- in: body
name: body
required: true
schema:
$ref: '#/definitions/FileWithMetadata'
...
definitions:
FileWithMetadata:
type: object
required: [file_data]
properties:
file_data:
type: string
format: binary # or format: byte
metadata:
type: object
additionalProperties:
type: string
2) Another possible way is to send the metadata names and values as separate arrays, so you would have 3 form parameters: file, array of key names, and array of key values. This is analog to:
curl -F "file=#foo.zip" -F "metadata_keys=description,author" -F "metadata_values=A ZIP file,Helen" https://api.example.com
Your API spec would look like this:
paths:
/something:
post:
consumes:
- multipart/form-data
parameters:
- in: formData
name: file
type: file
required: true
- in: formData
name: metadata_keys
type: array
items:
type: string
- in: formData
name: metadata_values
type: array
items:
type: string
Related
I have a HOCON config file, something like
foo {
[
id: 1
f: abc
],
[
id: 2
f: [xyz , pqr]
]
}
At the backend, I want the field f as a Java list. So wherever the field f is a string, I should be able to convert it to a List. config.resolve() doesn't seem to work here and I need a custom wrapper on top it which I'm unable to think of. Is there any way by which this could be achieved ?
I have a simple requirement of converting input JSON to flat file in Mule 4 but I am unable to find any solid examples online. I started of creating sample schema as follows but it's not working.
test.ffd schema:
form: FLATFILE
id: 'test'
tag: '1'
name: Request Header Record
values:
- { name: 'aa', type: String, length: 10 }
- { name: 'bb', type: String, length: 8 }
- { name: 'cc', type: String, length: 4 }
dataweave:
%dw 2.0
output application/flatfile schemaPath='test.ffd'
---
{
aa : payload.a,
bb : payload.b,
cc : payload.c
}
Input JSON:
{
"a": "xxx",
"b": "yyy",
"c": "zzz"
}
But it fails saying
Message : "java.lang.IllegalStateException - Need to specify structureIdent or schemaIdent in writer configuration, while writing FlatFile at
4| {
| ...
8| }
How do I do this correctly?
Error message tells you what is missed.
Need to specify structureIdent or schemaIdent in writer configuration
Add one of them and it flatfile or fixedwidth should work fine.
For example, add segmentIdent:
%dw 2.0
output application/flatfile schemaPath = "test1.ffd",
segmentIdent = "test1"
---
payload map (a, index) -> {
aa: a.a,
bb: a.b,
cc: a.c
}
Here is example how to use FIXEDWIDTH properly https://simpleflatservice.com/mule4/FixedWidthSchemaTransformation.html
Assuming you are trying to output a fixed width file, which it looks like you are, change
form: FLATFILE
to
form: FIXEDWIDTH
Keep in mind using this FFD will only work if you have a single structure. You could pass in:
payload map {
aa: $.a,
...
}
If you had a set and it would still work, but if you needed multiple structures you won't be able to use the shorthand schema.
And to explain why you were getting this error, take a look at these docs, reading "Writer properties (for Flat File)":
https://docs.mulesoft.com/mule-runtime/4.2/dataweave-formats#writer_properties_flat_file
I try to create plugin with "transform" for my data to kafka-connect and use it with different sink connectors.
When I install plugin, kafka-connect doesn't see my classes.
I used kafka-connect maven plugin to create my bundle zip.
Installation with confluent-hub (from local file) has succeed.
All file are unzip, my worker properties has updated plugin.paths.
I run my connect in distributed mode and try to create new connector with transformer from my package.
My plugin structure looks like:
- mwojdowski-my-connect-plugin-0.0.1-SNAPSHOT
|- manifest.json
|- lib
||- my-connect-plugin-0.0.1-SNAPSHOT.jar
and my manifest.json file:
{
"name" : "my-connect-plugin",
"version" : "0.0.1-SNAPSHOT",
"title" : "my-connect-plugin",
"description" : "A set of transformations for Kafka Connect",
"owner" : {
"username" : "mwojdowski",
"name" : "Marcin Wojdowski<mwojdowski#gmail.com>"
},
"tags" : [ "transform", "field", "topic" ],
"features" : {
"supported_encodings" : [ "any" ],
"single_message_transforms" : true,
"confluent_control_center_integration" : true,
"kafka_connect_api" : true
},
"documentation_url" : "",
"docker_image" : { },
"license" : [ {
"name" : "Confluent Software License",
"url" : "https://www.confluent.io/software-evaluation-license"
} ],
"component_types" : [ "transform" ],
"release_date" : "2019-08-29"
}
Next, I try to create new connector:
curl -XPOST -H 'Content-type:application/json' 'localhost:8083/connectors' -d '{
"name" : "custom-file-sink-with-validation",
"config" : {
"connector.class" : "FileStreamSink",
"tasks.max" : "1",
"topics" : "test_topic",
"file" : "/tmp/my-plugin-test.txt",
"key.ignore" : "true",
"schema.ignore" : "true",
"drop.invalid.message": "false",
"behavior.on.malformed.documents": "warn",
"key.converter":"org.apache.kafka.connect.storage.StringConverter",
"value.converter":"org.apache.kafka.connect.storage.StringConverter",
"transforms" : "Validation",
"transforms.Validation.type" : "org.kafka.connect.my.connector.ValidateId"
}
}'
After restart of kafka connect, when I try to create new connector, exception is thrown:
{
"error_code": 400,
"message": "Connector configuration is invalid and contains the following 2 error(s):\nInvalid value org.kafka.connect.my.connector.ValidateId for configuration transforms.Validation.type: Class org.kafka.connect.my.connector.ValidateId could not be found.\nInvalid value null for configuration transforms.Validation.type: Not a Transformation\nYou can also find the above list of errors at the endpoint `/{connectorType}/config/validate`"
}
I try to install plugin also manually, following doc:
https://docs.confluent.io/current/connect/managing/install.html
But it looks, like Connect doesn't load my jars.
When I copy my jar to share/java/kafka it works, but this is not a solution.
I suspect my plugin is skip, because it not contains connectors.
In this case should I add my jars to classpath manually? (Opposite to https://docs.confluent.io/current/connect/userguide.html#installing-plugins)
Or should I explicitly point in my connector configuration to try use my plugin?
Regards,
M.
Sorry, problem was really trivial.
During refactoring one of the packages get "'s" at the end and I miss to update it in config.
"transforms.Validation.type" : "org.kafka.connect.my.connectors.ValidateId"
instead of
"transforms.Validation.type" : "org.kafka.connect.my.connector.ValidateId"
I refactor it moment before switch from standalone to distributed.
One more time sorry for worrying You and thank You for your support.
Regards,
Marcin
Generating server code for this minimal example using spring or jaxrs-spec creates 2 model classes: Pet.java and InlineResposne200.java. Except for the class name, they are identical.
The controller that responds to /pets returns a List<InlineResponse200> instead of List<Pet> and the class Pet is actually never used anywhere, even though the yaml definition uses $ref: "#/definitions/Pet". Why is this happening?
---
swagger: "2.0"
info:
version: "1.0.0"
title: "Swagger Petstore"
description: "A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification"
termsOfService: "http://swagger.io/terms/"
contact:
name: "Swagger API Team"
license:
name: "MIT"
host: "petstore.swagger.io"
basePath: "/api"
schemes:
- "http"
consumes:
- "application/json"
produces:
- "application/json"
paths:
/pets:
get:
description: "Returns all pets from the system that the user has access to"
produces:
- "application/json"
responses:
"200":
description: "A list of pets."
schema:
type: "array"
items:
$ref: "#/definitions/Pet"
definitions:
Pet:
type: "object"
required:
- "id"
- "name"
properties:
id:
type: "integer"
format: "int64"
name:
type: "string"
tag:
type: "string"
I tried replicating this with swagger-codegen v2.2.2 using both spring and jaxrs-spec, but I was not able to get the InlineResponse200.java.
However, having done some more digging, I have found that this issue was recently reported as a bug. It has not yet been fixed, but the InlineResponse200.java isn't meant to be there.
This file seems to be incorrectly generated when using Swagger Editor v3. I'm guessing that's how you generated your file?
Whilst Swagger Editor v2 does not have this problem, my suggestion for the time being for you would be to install and use the latest stable version of swagger-codegen to generate your code from your Swagger.yaml file.
Hope this helps.
I have a property file like this.
host=192.168.1.1
port=8060
host=192.168.1.2
port=8070
host=192.168.1.3
port=8080
host=192.168.1.4
port=8090
Now I want the unique url so I can pass it to other application.
Example
HostOne : https://192.168.1.1:8060
HostTwo : https://192.168.1.2:8070
HostThree : https://192.168.1.3:8080
HostFour : https://192.168.1.4:8090
How can I get it using Java or any other library. Please help.
Thanks.
EDITED
How about this if I will this type of data.
host=192.168.1.1,8060
host=192.168.1.1,8060
host=192.168.1.1,8060
host=192.168.1.1,8060
Now is there any way to get this. ?
Basically that property file is broken. A property file is a sequence of key/value pairs which is build into a map, so it requires the keys be unique. I suspect that if you load this into a Properties object at the moment, you'll get just the last host/port pair.
Options:
Make this a real properties file by giving unique keys, e.g.
host.1=192.168.1.1
port.1=8060
host.2=192.168.1.2
port.2=8070
...
Use a different file format (e.g. JSON)
Write your own custom parser which understands your current file format, but don't call it a "properties file" as that has a specific meaning to Java developers
Personally I'd probably go with JSON. For example, your file could be represented as:
[
{ "host": "192.168.1.1", "port": 8060 },
{ "host": "192.168.1.2", "port": 8070 },
{ "host": "192.168.1.3", "port": 8080 },
{ "host": "192.168.1.4", "port": 8090 }
]