Camel REST DSL set Example Value for Swagger UI - spring-boot

Is it possible and if yes, how to set the Example Value for Swagger UI using Camel REST DSL in Java?
I'm running Swagger UI from org.webjars dependency in Spring Boot.
rest("/test").description("Some description").consumes("application/json").produces("application/json")
.post("/trigger").id("trigger")
.description("Another description")
.type(Map.class).param().name("body").type(body).description("More description"))
.required(true).example(readJson.getJson("json_example.txt")).endParam()
.route().bean(new Service(), "Trigger");
This readJson get JSON as String.
It looks like .example() is ignored and nothing appears in Swagger UI.
It always shows the "string" value inside Example Value like on the picture below.

As a solution, I've created Java POJO class with next code:
public class User{
public String user_id;
public String user_name;
}
Then I linked that class to the Camel REST DSL inside SpringBootRouter class:
...
rest("/test").description("Some description").consumes("application/json").produces("application/json")
.post("/trigger").id("trigger")
.description("Another description")
.type(User.class).param().name("body").type(body).description("More description"))
.required(true).endParam()
.route().bean(new Service(), "Trigger");
...
And this is the result:
If there is a better solution, please tell.
UPDATE:
To replace default value "string" for String or 0 for int or true for Boolean, I've used ApiModelProperty like this:
import io.swagger.annotations.ApiModelProperty;
public class User{
#ApiModelProperty(example = "1165")
public String user_id;
#ApiModelProperty(example = "Bob")
public String user_name;
}
And this is the final result:

In swagger v3 you use
#Model(description = "The user name", example = "Bob")
public String user_name;

Related

How does field mapping happen for a PUT request body?

I am stuck with a basic confusion which I cannot test and cannot find a straightforward answer to as well.
I have an endpoint PUT which expects an object in the body , RequestObject.
It consists of 1 field only.
class RequestObject {
String name;
}
Now from the service from which I am hitting this endpoint, the object that I am supposed to use to send in the request has 2 fields.
class Test {
String firstname;
String age;
}
If I make a request, with age as null,
Will this work ?
Since firstName and name are not the same "spellings", will the mapping happen automatically ?
I am assuming No for both but I am not sure how to confirm.
WIll appreciate if someone can point me in right direction.
Thanks
#JsonIgnoreProperties(ignoreUnknown = true)
class RequestObject {
#JsonProperty("firstname")
String name;
}
By default Spring Boot uses the Jackson library to convert to objects. You can customize it using annotations. See https://github.com/FasterXML/jackson-annotations/wiki/Jackson-Annotations

#Value In Spring MVC is not getting populated

I am trying to populate an attribute using the #Value annotation in Spring MVC, and it is not getting populated.
I am trying to access the attribute using Struts2 JSP property. my use case looks like that:
public class TransferCreditsAction extends StudentAwareAction {
protected Log logger = LogFactory.getLog(this.getClass());
#Value( "${transfer.credit.url}" )
private String transferCreditUrl;
public void setStates( List<TranslatedValue> states ) {
this.states = states;
}
#Value( "${transfer.credit.url}" )
public String getTransferCreditUrl() {
return transferCreditUrl;
}
}
My property file looks like:
transfer.credit.url
I am accessing this attribute using JSP which looks like:
<s:property value='transferCreditUrl'/>"
I know for a fact that my JSP can access this field, because I tested it when I have this field set for a default value.
However, this field is not getting populated from my property file. I am using Spring 4.1.6
Any help is really appreciated.
Spring can only inject values in its own managed spring beans. That means your TransferCreditsAction should be a spring bean.
There are various ways to declare your TransferCreditsAction class as a spring bean, already answered elsewhere.
You haven't added whats on top of TransferCreditsAction class.
Values will be injected in a Bean Env.
There are many ways of Doing it
Assuming my property file contains
username=Ashish
app.name=Hello
1.
#Service
#PropertySource(value = { "classpath:sample.properties" })
public class PaloAltoSbiClientImpl implements PaloAltoSbiClient {
public static String username;
#Value("${username}")
public void setUrl(String data) {
username = data;
}
...
2.
#Service
public class PaloAltoSbiClientImpl implements PaloAltoSbiClient {
#Value("${username}")
public static String username;
...
3.
#Component
public class TokenHelper {
#Value("${app.name}")
private String APP_NAME;
Just give the properties file reference on top of the class in which you are trying to get.
#PropertySource(value = { "classpath:sample.properties" })
This issue was happening because I was missing <context:annotation-config/> in my applicationContext. Once I added it, it start working with no issues.

Assign a value to a parameter in application properties before use

I have a property in my application.properties file in a SpringBoot project -
app.module.service.url=http://localhost:8090/{DOCID}
I have injected it into my Java file as below -
#Value("${app.module.service.url}")
private String url;
Now I need to replace DOCID with some value in my function(i.e-dynamic). How do I get to do this or am I completely missing it?
I am aware that we can do this in case of message properties in Spring. But here I have nothing to do with Locales.
Edit:
There is some value which I need to put in place of {DOCID} when using it within my Java implementation.
...
public class Sample{
#Value("${app.module.service.url}")
private String url;
public void sampleFunc(){
String str = "random Value" //some dynamic value goes in here
...
Now I need to replace {DOCID} with str in url
Two way binding is not possible in Spring Properties.It can only read run time and environmental variables.
Please refer following link for more information.
https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-Configuration-Binding
You can use spring UriTemplate for this purpose.
In your implementation class:
...
public class Sample{
#Value("${app.module.service.url}")
private String url;
public void sampleFunc(){
String dockId = someValue; // customize according to your need
UriTemplate uriTemplate = new UriTemplate(url);
URI uri = uriTemplate.expand(docId);
new RestTemplate().postForEntity(uri, requestObhect, Responseclass.class);
}
...
For more information, you can refer :
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/util/UriTemplate.html
Try like this ...
app.module.service.url=http://localhost:8090/{{docId}}
And set run configuration as below
-DdocId = 133323 // any number which you want

Customizing Request Header description in Swagger UI using Springfox-Swagger2

I am using Springfox Swagger2 version 2.4.0, Springfox Swagger UI version 2.4.0 and Swagger Annotations version 1.5.0 in my Spring Boot application.
The question here is, I am able to generate swagger UI for my controller's API and I am able to test the same. But I am not able to specify request header description for my request header. I m using #RequestHeader annotation for the same.
The code snippet in my controller API is follows:
#RequestHeader(name = "Api-Key") String apiKey
The Swagger UI for the request header is as follows:
The highlighted rectangular area in the image represents the description of the request header.
Currently it just picks up the data mentioned in the name attribute and shows it. But i wanna give a different description for the same. i.e. "Value of license key"
How can i achieve this in Swagger UI as #RequestHeader annotation only have value, defaultValue, name and required attributes? Any help would be really appreciated.
Update: Looking for a solution out of the box without any custom annotation of my own
Maybe my answer will help somebody.
As mentioned Dilip Krishnan in his answer you could use io.swagger.annotations.ApiParam or io.swagger.annotations.ApiImplicitParam Swagger annotations for fine-tuned custom documentation.
#ApiParam could be used for registered method parameters.
#ApiImplicitParam could be used if API parameter wasn't registered explicitly.
#RestController
#RequestMapping(value = "/v1/test", produces = "application/json")
#Api(value = "/v1/test")
public class TestController {
#ApiOperation(value = "Do Something method", tags = "Test method")
#RequestMapping(value = "/doSomeThing", method = RequestMethod.GET)
public Foo doSomeThing(
#ApiParam(value = "Param1 Description", required = true)
#RequestParam String param) {
throw new UnsupportedOperationException("do Some Things");
}
#ApiOperation(value = "Do Something Another method", tags = "Test method")
#ApiImplicitParams({
#ApiImplicitParam(name = "anotherParam1", value = "Another Param1 Description", paramType = "header"),
#ApiImplicitParam(name = "anotherParam1", value = "Another Param1 Description", paramType = "header")
})
#RequestMapping(value = "/doSomeThingAnother", method = RequestMethod.GET)
public Foo doSomeThingAnother(Bar bar) {
throw new UnsupportedOperationException("do Some Thing Another");
}
}
And in the end you could see following picture
TL;DR is that you would have to build your own plugin to do it.
Basically the only out-of-the-box annotations to augment the description in this case are #ApiParam and to be more accurate #ApiImplicitParam. Unfortunately neither of those annotations support descriptions.
So my suggestion would be to:
Create your own annotation that would look like this
#RequestHeader(name = "Api-Key")
#Description("Value of license key") String apiKey
NOTE: There is already an annotation in spring that is suitable for this.
Create your own ParameterBuilderPlugin
Implement the plugin as shown below
public class Test implements ParameterBuilderPlugin {
#Override
public void apply(ParameterContext parameterContext) {
ResolvedMethodParameter methodParameter =parameterContext.resolvedMethodParameter();
Optional<Description> requestParam = methodParameter.findAnnotation(Description.class);
if (requestParam.isPresent()) {
parameterContext.parameterBuilder()
.description(requestParam.get().value());
}
}
#Override
public boolean supports(DocumentationType documentationType) {
return false;
}
}
Pick a value of the order that is is applied after swagger annotations have been processed.
Also please upgrade your springfox library to the latest version.
We had the same issue, and resolved the problem in the following way:
.. #RequestHeader(value = "..") #ApiParam(value = "Description") String param ..
The idea is to add "description" field into generated swagger. It could look hacky, but it's a quick simple solution which can be useful in your personal case.
Quick, easy valid solution is to use an enum, for example:
#RequestHeader(value = "someval") ALLOWED_VALUES input
private enum ALLOWED_VALUES {A, B, C};
The following will show in swagger:
Available values : A, B, C

Apache Camel fields injection

Using Apache Camel PropertyPlaceHolder I want to inject a property value in a Java Class field using Simple Expression Language:
#Simple("${properties:prop1}")
private String prop1;
#Simple("${properties:prop2}")
private String prop2;
That works fine with method's parameters:
public void test(#Simple(value = "${properties:prop}") String prop) {
//....
}
But in java class fields I keep having null value, nothing is injected.
Any ideas please on how can I do that?
Thank you in advance.
Using
#Simple("${properties:prop2}")
private String prop2;
On fields is not supported in Camel.
There is a JIRA ticket to support this in the future: https://issues.apache.org/jira/browse/CAMEL-3215

Resources