Laravel package config file override/cascade - laravel

I am trying to use a config file I had published from a package I'm using (andrewelkins/cabinet) in order to override the vendor's default config file.
Location of my config file (the file I intend to override the default with):
app/config/packages/andrewelkins/cabinet/config.php
Location of the andrewelkins/cabinet default config file (which I would like to override with the former):
vendor/andrewelkins/cabinet/src/config.php
Am I required to specify the location of my overriding config file somewhere? My initial understanding was that config files automatically cascade based on the folder/filenames, but my experience so far seems to indicate that I need to specify that I would like to override the vendor's config file.
Thanks :)

Just in case anyone else has the same issue, I solved this by extending the class I wanted to use from the package, CabinetUpload, and in it's constructor, called the parent constructor and then added the namespace of (my) package, and where it should look for the configs:
public function __construct()
{
parent::__construct();
Config::addNamespace('administration', 'andrewelkins/cabinet');
}

Related

Spring Boot application to have separated multiple property files

Coming from Play Framework, a handy feature that has helped to organize the application configurations was to use includes (Link) to spilt the various configurations into multiple .conf files as below.
application.conf Content
include "play-http.conf"
include "play-modules.conf"
include "play-i18n.conf"
include "authentication.conf"
include "hbase.conf"
include "custom-caches.conf"
include "custom-filters.conf"
#Any other root level application configurations
Is there an equivalent to this in Spring Boot .properties files?
From Spring 2.4, we can create multiple properties file for each profiles as below.
application-main1.properties
application-sub1.properties
application-sub2.properties
And then in default application.properties file we can group all sub profiles and activate the main profile
spring.profiles.group.main1=sub1,sub2
spring.profiles.active=main1
I am not sure if we can group sub profiles under default profile. You can try out
spring.profiles.group.default=sub1,sub2
This way you don't need to have another file for main profile.
I use yaml configuration files myself but I think that the configuration is mostly similar. You should take a look at the PropertySourcesPlaceholderConfigurer.
I have defined a PropertySourcesPlaceholderConfigurer bean to use a configuration override file located outside of the jar. Anything that is in the override file will be used instead of the default configuration. Anything that is not in the override file is still retrieved from the default configuration file. I think you can create a similar bean to achieve what you are looking for.
Here's my code:
#Bean
static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
var properties = new PropertySourcesPlaceholderConfigurer();
properties.setLocation(new FileSystemResource("./application.yaml"));
properties.setIgnoreResourceNotFound(true);
return properties;
}
For my use case, I only needed to define one properties location, but it is also possible to specify multiple locations:
...
properties.setLocations(Resource... locations);
...
My requirement was simply achieved using the spring.config.import (Link).
I created multiple property files such as hbase.properties, custom-caches.properties etc. And then in my application.properties imported those additional property files as below.
spring.config.import=hbase.properties,custom-caches.properties
#Any other properties in the application.properties file
Thanks

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.

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

Spring boot external config override isnt working

I have an application.yml and application-qa.yml in my resources folder.
I have an external application-qa.yml.
I want the properties in the external application-qa.yml to override the matching ones from the default application.yml and from the internal application-qa.yml, I dont want to override the entire file.
Im adding this VM option (In Intellij): -Dspring.config.additional-location=file:{absolute/path/to/external/ending/with/application-qa.yml}
I also have in env variables (also in Intellij): spring.profiles.active=qa
And for some reason the override doesnt work, I get the value from the internal application-qa.yml instead of the external one.
Tried naming the external file as application.yml, didnt work.
UPDATE:
It does work if I remove application-qa.yml from the end of the path and just give a path to the folder where the file is, but I want to specify a file, I dont want him to take everything thats in the dir.
This is a change in behavior from 1.x to 2.x. The spring.config.location overrides the default instead of adding to it. We need to use spring.config.additional-location to keep the defaults. So if you want to override try spring.config.location instead.

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

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.

Resources