Generate endpoints in separate classes with swager-codegen - java

I have below YAML for swagger-codegen and I want it to generate this endpoints in two separate classes, by default it generates one api class with both endpoints, is it s way to mark them as separate api?
/tenants:
post:
produces:
- application/json
consumes:
- application/json
parameters:
- name: body
in: body
required: true
schema:
$ref: "#/definitions/TenantRequest"
#################### User ####################
/tenants/{tenantId}/users:
post:
description: Create a User
produces:
- application/json
consumes:
- application/json
parameters:
- name: tenantId
in: path
required: true
type: string
- name: body
in: body
description: User object
required: true
schema:
$ref: "#/definitions/UserRequest"

If you want separate APIs to be created then you need to change /tenants: to /createTenants:
say for example you have 2 operations.
/user/add
/user/delete
If you try to generate API classes for the above operation then it will create class named UserApi with add and delete methods in it.
Now if you want separate API classes for add and delete then you need to change the end point as follows.
/addUser
/deleteUser

Related

How to access request type in RAML file (using webapi-parser)

Library used
webapi-parser 0.5.0
Language library used with
Java
Describe the issue
I am unable to find a method to access the type of request defined in the raml file
Input you have issues with
Below is the relavent section of RAML file
/testEndpoint:
type: rt.Item
post:
is: [t.ReturnsItemCreated, t.ExpectsContext, t.ReturnsNotFound, t.ReturnsBadGateway, t.ReturnsCommonErrors, t.NotCacheable]
body:
application/json:
type: bu.BlockCodeUpdatesRequestType
examples:
de-cards-bc: !include examples/example1.json
responses:
201:
body:
application/json:
type: bu.DeviceManagementResponseType
example: !include examples/ex2.json
Code you have issues with
After going through the documentation, I tried using operation.request().payloads().get(0).mediaType().value() but that returns application/json which isn't what I want, I want the type inside the application/json i.e. bu.BlockCodeUpdatesRequestType. Same is the case with the examples, I am unable to read those, the payloads().get(0).examples() comes up as empty for some reason and I don't know to access these. Getting just the path in the examples is enough.
Additional context
The variables like rt bu are RAML library files defined under uses:
I asked the same thing on Github here.

Error while creating changeset - "DependsOn must be a string or list of strings."

I am using cloudformation to deploy my code. In my yml file I ahve this DependsOn attribute for which I am trying to add value as "AppApiv1Stage". I have tried multiple things, everytime it gives different errors not sure what I am doing wrong. In the below code snippet first I added it in double quotes like this:"AppApiv1Stage" then it showed error. Again I tried with below code, then it showed me error as "DependsOn must be a string or list of strings"
Parameters:
ApiStageSecondDeploymentName:
Description: API Stage name to use
Type: String
Default: v1
Resources:
AppAPI:
Type: AWS::Serverless::Api
DependsOn: AuthFunction
Properties:
Name: !Sub ${AWS::StackName}
StageName: !Ref ApiStageSecondDeploymentName
Variables:
LocalTLD: local # Deploys a Dev stage to use for tests and development
MethodSettings:
- LoggingLevel: ERROR
MetricsEnabled: True
DataTraceEnabled: True
HttpMethod: '*'
ResourcePath: '/*'
ThrottlingBurstLimit: !Ref ApiBurstLimit
ThrottlingRateLimit: !Ref ApiRateLimit
ApiMapping:
DependsOn: !Sub AppAPI !Ref ${ApiStageSecondDeploymentName}Stage
Type: AWS::ApiGateway::BasePathMapping
Properties:
BasePath: !Ref ApiStageSecondDeploymentName
DomainName:
Fn::ImportValue: !Sub ${CustomDomainStack}-DNSName
RestApiId: !Ref AppAPI
I also tried with Join! but showing error again.
not sure what I am doing wrong
DependsOn, as the error says, must be a string, or list of strings. Not an intrinsic function (Sub, Ref).
What's more, intrinsic functions can be only used in few places in a template, none of which is DependsOn. From docs:
You can use intrinsic functions only in specific parts of a template. Currently, you can use intrinsic functions in resource properties, outputs, metadata attributes, and update policy attributes. You can also use intrinsic functions to conditionally create stack resources.

Swagger generating duplicated model classes

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.

Kaitai Struct: pass some field to achieve fault tolerance

is there has any way to pass some field when parsing a truncated log in Kaitai Struct?
Because if it read a field (type specify to a enum) but value not in there, it will raise a NullPointer Exception.
So I want ask if any way to achieve that just like default: pass attribute in python library Construct
Here is my ksy file:
meta:
id: btsnoop
endian: be
seq:
- id: header
type: header
- id: packets
type: packet
repeat: eos
types:
header:
seq:
- id: iden
size: 8
- id: version
type: u4
- id: datalink_type
type: u4
enum: linktype
packet:
seq:
- id: ori_len
type: u4
- id: include_len
type: u4
- id: pkt_flags
type: u4
- id: cumu_drop
type: u4
- id: timestamp
type: s8
- id: data
size: include_len
type: frame
frame:
seq:
- id: pkt_type
type: u1
enum: pkttype
- id: cmd
type: cmd
if: pkt_type == pkttype::cmd_pkt
- id: acl
type: acl
if: pkt_type == pkttype::acl_pkt
- id: evt
type: evt
if: pkt_type == pkttype::evt_pkt
cmd:
seq:
- id: opcode
type: u2le
- id: params_len
type: u1
- id: params
size: params_len
acl:
seq:
- id: handle
type: u2le
evt:
seq:
- id: status
type: u1
enum: status
- id: total_length
type: u1
- id: params
size-eos: true
enums: <-- I need to list all possible option in every enum?
linktype:
0x03E9: unencapsulated_hci
0x03EA: hci_uart
0x03EB: hci_bscp
0x03EC: hci_serial
pkttype:
1: cmd_pkt
2: acl_pkt
4: evt_pkt
status:
0x0D: complete_D
0x0E: complete_E
0xFF: vendor_specific
Thanks for reply :)
There are still two questions you're facing here :)
Parsing partial / truncated / damaged data
The main problem here is that normally Kaitai Struct compiles .ksy into a code that does the actual parsing in class constructor. That means if a problem arises, boom, you've got no object at all. In most use cases, it is desired behavior, as it actually allows you to be sure that the object is fully initialized. The problem is usually an EOFException, when format wants to read next primitive, but there's no data in the stream left, or, in some more complicated cases, something else.
However, there are some use-cases as you've mentioned, where having "best effort" parsing would be helpful - i.e. you're ok with having half-filled object. Another popular use case for that is the visualizer: it's helpful to show "best effort" there too, as it's better to show user half-parsed result visualized (to aid in locating at error) rather than no result at all (and leave the user with the guesswork).
There's a simple solution for that in Kaitai Struct - you can compile your class with --debug option. This way you'll get a class that has object creation and parsing separated, parsing would be just another method of an object (void _read()). However, this means that you'll have to call parsing method manually. For example, if your original code was:
Btssnoop b = Btssnoop.fromFile("/path/to/file.bin");
System.out.println(b.packets.size());
after you've compiled it with --debug, you'll have to do extra step:
Btssnoop b = Btssnoop.fromFile("/path/to/file.bin");
b._read();
System.out.println(b.packets.size());
and then you can wrap it up in a try/catch block and actually continue processing even after getting IOException:
Btssnoop b = Btssnoop.fromFile("/path/to/file.bin");
try {
b._read();
} catch (IOException e) {
System.out.println("warning: truncated packets");
}
System.out.println(b.packets.size());
There are a few catches, though:
--debug was not yet available for Java target, as of release v0.3; actually, it's not even in public git repository right now, I hope I'll push it soon though.
--debug also does a few extra things, like writing down positions of every attribute, which imposes pretty harsh performance / memory penalty. Tell me if you'll need a switch to compile "separate constructor/parsing" functionality without the rest of --debug functionality - I can think of additional switch to enable just that.
If you need to do continuous parsing incoming packets as they arrive, probably it's a bad idea to store them all in memory and re-parse them all on every update. We're considering event-based parsing model for that one, please tell me if you'd be interested in that one.
Missing enum values and NPE
Current Java implementation translates enums reading into something like
this.pet1 = Animal.byId(_io.readU4le());
where Animal.byId is translated into:
private static final Map<Long, Animal> byId = new HashMap<Long, Animal>(3);
static {
for (Animal e : Animal.values())
byId.put(e.id(), e);
}
public static Animal byId(long id) { return byId.get(id); }
Java Map's get returns null by contract, when no value was found in the map. You should be able to compare that null with something (i.e. other enum value) and get proper true or false. Can you show me where exactly you have NPE problem, i.e. your code, generated code and stack trace?

Swagger Error Expected type string but found type integer

I started working recently on swagger to generate documentation for our RESTful apis. I use the yamlbeans-1.09.jar to convert my Java DTOs to a yaml file.
Everything works fine and the yaml is even validated properly on the http://www.yamllint.com/ but still while testing it with the Swagger interface, it gives an error "Expected type string but found type integer" and "No enum match for: 2" wherever I mention the swagger : 2.0 in the file.
My sample yml file is:
basePath: /employment
host: api.xxxx.com
schemes:
- https
swagger: 2.0
info:
title: API Doc
description: Description for the info goes here
version: 1.0.0
It always tends to give an error just a line number before the swagger version. Any help will be appreciated.
Edit: I have defined the swagger version as string in the java code and written as described below:
HashMap<String, Object> rootElementsForYml = new HashMap<String, Object>();
rootElementsForYml.put(SWAGGER, "2.0");
rootElementsForYml.put(HOST, "api.xxxx.com");
rootElementsForYml.put(BASEPATH, basePath);
rootElementsForYml.put(SCHEMES, new String[]{"https"});
But still it gives no result and the same error.
That's because the version value is a string and not a number. Just specifying 2.0 is interpreted as a number. Wrap it with quotes like "2.0" and it would work fine.

Categories

Resources