swagger codegen add #JacksonXmlElementWrapper(useWrapping = false) annotation to a single field - spring

I'm currently using swagger codegen using yml to generate my models However I have one field, that is a List<Object> that needs to have the #JacksonXmlElementWrapper(useWrapping = false). I can see the #JacksonXmlElementWrapper in POJO.mustache but not in model.mustache. Does anyone know what to add in the yaml file or anywhere else so that field gets generated with that annotation? Thanks. I'm using spring-java language with gradle. I need this to be generated during build. so minimal changes are preferred.

According to the readme on their git, Swagger Codegen mention ways to do this:
https://github.com/swagger-api/swagger-codegen/blob/master/README.md
since you're using gradle:
We can use a custom template for the code generation as follows:
// build.gradle
swaggerSources {
inputFile = file('{name of your file}.yaml')
xyz {
language = 'spring'
// template directory path
templateDir = file('templates/{name of your custom directory}')
}
}
inside templates/{name of your custom directory}, you can store your custom mustache files, as in your case, all you have to do is download the required spring templates from git (e.g. this link is for pojo.mustache)
and add in the required changes to the template, along with the project and libraries folder. Run gradle build and it should generate.
There is a much simpler workaround however, where you can just use your own pojo class and add this in your existing config.json and remove the earlier entry for that model in your yaml file (of course):
"importMappings" : {
"{replace with className}": "{replace with packageName}.{replace with className}"
}
Hope this helps.

Related

Can I create a Gradle plugin that adds a dependency or another plugin based on a Gradle extension value?

Can I create a Gradle plugin that adds a dependency based on an extension value?
I have a convention plugin that I use for libraries various projects, which brings in various dependencies, takes care of boilerplate configuration, configures other plugins etc etc. I want to add an extension to the plugin that can tell the plugin whether or not to add a certain dependency, in this case it happens to be Spock, as not every library module needs the Spock dependency.
So far, my plugin looks like this
interface BasePluginExtension {
Property<Boolean> getUseSpock()
}
class BasePlugin implements Plugin<Project> {
#Override
void apply(Project project) {
BasePluginExtension basePluginExtension = project.extensions.create('basePluginConfig', BasePluginExtension)
// If a value was supplied, use it, otherwise assume we want Spock
if (basePluginExtension?.useSpock?.get() ?: true) {
// Printing for debugging purposes
println "I'm using spock! ${basePluginExtension.useSpock.get()}"
// Currently apply a plugin that applies Spock but could also just add a dependency
project.plugins.apply("test-config")
}
}
}
Then in the build.gradle file that I want to pull my plugin into, I have
plugins {
id 'base-plugin'
}
basePluginConfig {
useSpock = true
}
I'm following the docs on configuring an extension but I am getting the following error:
Cannot query the value of extension 'basePluginConfig' property 'useSpock' because it has no value available.
I've also tried the method of making an abstract class for the extension but I want the ability to have multiple configurable parameters in the future.
Is adding a dependency after plugin extension values have been configured not allowed/out of order for how Gradle works? Or am I possibly missing something obvious?

override spring-boot property in dependency jar file

I have a spring boot project that depends on one of the 3rd party SDK libraries which contains a YAML file with some google cloud URLs.
I want to override those values within my YAML, this works for most of my project but for some reason no luck with this perticular dependency lib.
The Dependency Code
#ConfigurationProperties("google")
public class GoogleProperties {
String url;
..
..
}
Yaml file application-google-prod.yaml
google:
url: some url.
Say this is in a jar called google-client-sdk-1.0.0
My Code
Yaml file application-myapp-prod.yaml
spring:
profiles:
include: google-prod
google:
url: OVERRIDE url.
So I am expecting that the OVERRIDE url should be used when the code in the lib is invoked, but instead it continues to use some url from jar file's yaml.
any pointers?
EDIT
The SDK contains another class
class with the following annotations in the SDK
#Configuation
#PropertySource({"classpath:application-google-prod.yaml})
I think this is forcing SDK to pick the value from the specific YAML ignoring overridden value in the YAML from my app.
Disclaimer:
A is have no mean reproducing your issue, this is just a suggestion.
Notice the absence of #Configuration on GoogleProperties.
You have to either add #Configuration on the properties class:
(impossible in this case) or add #EnableConfigurationProperties(GoogleProperties.class) on top of the class where you want to use the properties.
E.g: Your main class if you want to use them in all the app.
As mentioned in the docs, you can also use:
#ConfigurationPropertiesScan({ "com.google.SDK", "org.acme.another" }) on top of your main class or any #Configuration class where you need those props.
Note: As explained here, the fact that as of spring-boot 2.2 we didn't need any more #Configuration or #EnableConfigurationProperties for the configuration properties feature is outdated.

Quarkus Qute template location from another maven module

Having a maven module that declares a Qute template and REST endpoint to render it, I wanted to include this module on another maven project. The problem is, at it seems, the destination module does not compile since it does not have / find the template in it's resources/templates location (the template is included in the jar of the included module).
Is there any way to instruct Qute (at build time) to read templates from other locations or disable this build check (since the template is in the classpath at the correct location?
The only way I can make it work roght now is to copy my template to the destination project at resources/templates but it doesn't seem the right solution.
Thanks in advance
Yes, by default only the templates located in src/main/resources/templates are validated and can be injected.
You can parse any template content manually via Engine.parse() or even add a custom template locator via io.quarkus.qute.EngineBuilder.addLocator(), e.g. something like:
import io.quarkus.qute.EngineBuilder;
class MyEngineConfig {
void configureEngine(#Observes EngineBuilder builder) {
builder.addLocator(path -> Optional.of(new TemplateLocation() {
#Override
public Reader read() {
return new BufferedReader(new InputStreamReader(FlowChartResource.class.getResourceAsStream(path)));
}
#Override
public Optional<Variant> getVariant() {
return Optional.empty();
}
}));
}
}
The disadvantage is that Quarkus can't validate/inject such templates.
See also related issues https://github.com/quarkusio/quarkus/issues/12084 and https://github.com/quarkusio/quarkus/issues/10376.
Ok, I found another solution, using "low-level" engine instance and parsing the template "manualy":
engine.parse(new BufferedReader(new InputStreamReader(FlowChartResource.class.getResourceAsStream([PATH to My Template]))).lines().collect(Collectors.joining("\n")))

spring boot app cannot load bundle properties files

I am building an app that mostly provide REST services, nothing fancy. since my data consumed by the app can have multiple languages I thought about using the bundle files.
I created 3 files, one with the default file name and another two with specific languages. The files created using intellij IDE I am using.
I followed this guide https://www.baeldung.com/java-resourcebundle however on each run I am getting:
MissingResourceException: Can't find bundle for base name tp_app_strings, locale en_US
I tried numerous articles but none of them seems to resolve the issue.
One fun fact is that if I am using the #Value("classpath:tp_app_strings.properties") on a 'Resource' field I am able to get a reference to that file, so it spring is able to find it.
Additional thing that I tried was to create a WEB-INF directory and place the files there (read it in some article) but still no positive affect
The project structure is quite straight forward:
Spring boot version 2.2 running tomcat.
Any suggeestions would be highly appriciated
You can load the .properties file to the application context using #PropertySource annotation instead using #Value to load the .properties file to a org.springframework.core.io.Resource instance.
The usage;
#Configuration
#PropertySource("classpath:tp_app_strings.properties")
public class DefaultProperties {
#Value("${property1.name}") // Access properties in the above file here using SpringEL.
private String prop1;
#Value("${property2.name}")
private String prop2;
}
You wouldn't need java.util.ResourceBundle access properties this way. Use different or same class to load other .properties files as well.
Update 1:
In order to have the functionality of java.util.ResourceBundle, you can't just use org.springframework.core.io.Resource class. This class or non of it sub-classes don't provide functions to access properties by its name java.util.ResourceBundle whatsoever.
However, if you want a functionality like java.util.ResourceBundle, you could implement something custom like this using org.springframework.core.io.Resource;
#Configuration
public class PropertyConfig {
#Value("classpath:tp_app_strings.properties")
private Resource defaultProperties;
#Bean("default-lang")
public java.util.Properties getDefaultProperties() throws IOException {
Properties props = new Properties();
props.load(defaultProperties.getInputStream());
return props;
}
}
Make sure to follow correct naming convention when define the property file as java.util.Properties#load(InputStream) expect that.
Now you can #Autowire and use this java.util.Properties bean wherever you want just like with java.util.ResourceBundle using java.util.Properties#getProperty(String) or its overloaded counterpart.
I think it's problem of you properties file naming convention. use underline "_" for specifying locale of file like
filename_[languageCode]_[regionCode]
[languageCode] and [regionCode] are two letters standard code that [regionCode] section is optional
about code abbrivation standard take a look on this question
in your case change file name to tp_app_strings_en_US.properties

REST Client Grails Groovy unable to resolve class RestClientBuilder

I have an empty project created using GGTS, my app runs fine, I can see the views and navigate through them fine.
I need con call a REST api and consume the data provided, I read and added the necessary plug in to the BuildConfig file under the dependencies and then under the plugins section, none of them seem to work.
compile ":rest-client-builder:2.0.0"
I've created a controller, I'm not sure where to add the import here, so I've tried:
package myapp
class UserController {
def index() {
import grails.plugins.rest.client.RestBuilder
String url = "https://foo.com/batch/$id"
def resp = new RestBuilder().get(url) { header 'Authorization', 'Basic base64EncodedUsername&Password' }
render resp
}
but I get the error: unable to resolve class....
The API is returning JSON data, what I;ve done so far is just to create a new Grails project, add controller, add view and then the dependency.
I've cleaned an built the project several times but the error remains.
Thanks for your help.
Import goes at the top
After the package line
And before the class line
Also, depending on your version of grails, you might want to move of ggts... Not sure it's supported any more...
I think that the problem is in your build.gradle dependency definition.
Insert the next line to your build.gradle file and I think that will be helpful:
compile "org.grails.plugins:rest-client-builder:2.1.1"
For more information follow the grails plugin documentation.
Please be aware that all the business logic should be placed in the service layer and not in the controller. It is a best practice to keep your controller lean as possible.
Another best practice is to define the following line:
String url = "https://foo.com/batch/$id"
in the beggining of the controller as static final String
static final String url = "https://foo.com/batch/"
and add the $id when needed in the code.
Here is how that should be called inside the method:
String url = "${url}/{$id}"

Resources