I need to to read data from database to be read into Config.groovy.
Is that possible to get data from Database into Config.groovy?
No it is not possible. In the sequence of events when a Grails application is starting up the Config.groovy is processed before the Datasource is made available to the application.
Without knowing what you are trying to accomplish I can't make a suggestion on how else to approach this issue.
Updated (based on comment)
In your comment you explain that you are trying to use the feature switch plugin (which is designed to be run time and not persistent). Looking at the source code for the plugin you should be able to make your own service that will load the settings from the database and toggles/updates the feature switch settings. Here is just a simple sketch/example:
package example
import org.springframework.beans.factory.InitializingBean
class MyExampleService implements InitializingBean {
def grailsApplication
void afterPropertiesSet() {
// here is where you would do whatever you needed to load the settings
grailsApplication.config.features['somefeature'].enabled = true
grailsApplication.config.features['otherfeature'].enabled = false
}
}
That should at least give you an idea.
Alternatively you could just write it all in Bootstrap.groovy which can access the datasource/GORM as well.
Related
In the implementation of repositories, you inject the PersistenceManager interface using #InjectPersistenceManager(). For testing, the docs mention to use RunWithDrivine, and to import Drivine (through the AppModule) into the createTestingModule call. This allows the PersistenceManager to be injected in the repository to be used.
I create a temporary Docker container with a new Neo4j database for the tests to use (using a package called testcontainers). This database needs some data to be used. In the test setup, it is possible to get the PersistenceManager by retrieving it from the testing module using a string which normally the decorator provides: app.get("PersistenceManager:default") as PersistenceManager and while this works, it does not seem like the correct way to do it.
How would I get the PersistenceManager to set up the data (and do other things) properly?
app.get("PersistenceManager:default") as PersistenceManager
This is actually probably what you're looking to do, but need to add { strict: false } as a second parameter to the get method. Seeing as #InjectPersistenceManager() is just #Inject('PersistenceManager:database') and database is default by default, you have the correct token, so you probably just need to tell Nest to dig deeper than the top module, hence the{ strict: false } option
I want to be able, to configure Simple Injector differently for each developer (for prototyping purposes for example).
The default configuration should be hardcoded, of course.
I have used Unity before, and there I was able to overwrite the hardcoded registrations by an XML configuration file. This config file was not under source control, and so other developers could overwrite the hardcoded registrations with their custom registrations without interfering with others.
The developers should not need to submit their configuration to source control.
Is such a scenario supported by Simple Injector ?
Is there any best practice for such a scenario ?
Does this make sense at all, or is there a better way to achieve what I want?
One of the design decisions for Simple Injector is to not support XML based configuration out-of-the-box. This decision is described here but can be summarizes as:
XML based configuration is brittle, error prone and always provides a
subset of what you can achieve with code based configuration. General
consensus is to use code based configuration as much as possible and
only fall back to file based configuration for the parts of the
configuration that really need to be customizable after deployment.
These are normally just a few registrations since the majority of
changes would still require developer interaction (write unit tests or
recompile for instance). Even for those few lines that do need to be
configurable, it’s a bad idea to require the fully qualified type name
in a configuration file. A configuration switch (true/false or simple
enum) is more than enough. You can read the configured value in your
code based configuration, this allows you to keep the type names in
your code. This allows you to refactor easily, gives you compile-time
support and is much more friendly to the person having to change this
configuration file.
This however doesn't completely satisfy your requirements, since you don't want to "customizable after deployment". Instead, you want to customize per developer.
For this particular case, you shouldn't fall back on XML based configuration IMO. Just as you can exclude xml files using .gitignore, you can do the same with code based configuration files that developers can change, and that will compile with the rest of the application. Here's an example:
// Global.cs
public void Application_Start() {
var container = new Container();
// Default configuration here
container.Options.AllowOverridingRegistrations = true;
DeveloperOverrides.ApplyOverrides(container);
container.Options.AllowOverridingRegistrations = false;
DependencyResolver.Current = new SimpleInjectorDependencyResolver(container);
}
// DeveloperOverrides.cs
public static class DeveloperOverrides {
public static void ApplyOverrides(Container container) {
}
}
These two files can be checked in, where the DeveloperOverrides.ApplyOverrides method is left blank. After that you add the exclusion of the DeveloperOverrides.cs to your .gitignore file.
After this, developers can add their own overrides that are checked by the compiler, but are never checked in into source control:
// DeveloperOverrides.cs
public static class DeveloperOverrides {
public static void ApplyOverrides(Container container) {
container.Register<IMailSender, FakeMailSender>(Lifestyle.Singleton);
}
}
I have created a plugin that is responsible for RDBMS access to a secondary datasource this way we hide the domain and service layer from the application that is going to use it (it impedes them from modifying that source). I have the plugn published to artifactory and then imported it successfully into my application. However, the datasource file that the plugin uses got excluded from packaging and when calling the service methods in the plugin it's trying to execute those queries against my default datasource.
Is there a way to tell the grails plugin to not use the default datasource but a secondary datasource? or is there a way to have the plugin not exclude its own DataSource.groovy file?
Thanks
UPDATE
The answer provided below would work, basically that is how multiple data sources work in Grails. The only drawback to that is that when I am developing the plugin itself and I want to run it as an app to make sure it does what I want the datasource that grails expects must be called dataSource so I have to comment out the
static mapping = {
// datasource 'dataSource_lookup'
}
in order to be able to run it. Then when i see that every thing is good as I desire and I want to publish the plugin I have to go trhough all of my domain files and uncomment the line above so that when the plugin is imported into my main app it will have a reference to the secondary data source. However, this is very very painful and slow.
Is there a better way to do this? Why does the default datasource have to be called dataSource? can that be changed?
In Domain Classes of your plugin you have to do something like this
static mapping ={
//if you need to use the second ds only in Production you can use the Environment
if(Environment.PRODUCTION){
datasource('your_sencondary_datasource')
}
}
and in your principal application in your Datasource.groovy you need to map your datasource like this
production{
dataSource {
<'your configs of primary ds'>
}
dataSource_you_secondary_datasource {
<'your configs to secondary ds'>
}
}
I'm using the resources.groovy to declare a service e.g.
aService(com.foo.OrganizationService)
so that I can tie aService to my controllers instead of using organizationService which could change in the future.
I've noticed that the OrganizationService doesn't get treated special like other services "not" declared in the resources.groovy. For example it doesn't get injected with grailsApplication, and likely a hibernateSession etc and other things I've not hit yet....
Now, I know I can manually wire in stuff to my service but I'd rather not have to maintain that...
Is there a special way to declare a service in the resources.groovy so that gets treated like another service that grails loads up?
TIA
The short answer to your question is "no".
Under the covers, Grails services are driven by some intelligent code that is referencing a specific location and expecting certain properties.
Viewing the source code (especially around the ServicesGrailsPlugin.groovy) is a good way to see the "magic" in how these are wired together.
Is there a reason you wouldn't want to use a bonafide Grails service to solve your problem? If you are expecting things like a grailsApplication, it seems like that use is pretty specific to Grails and would be a good candidate for porting over to a "true" Grails service.
Good luck!
So I've come full circle on this. This is a timing problem. Where services haven't been grails initialized yet.
Basically when you use the resources.groovy to do service wiring you run the risk of using a Service that might initialize itself e.g. afterPropertiesSet method or static initializers that use grails services (log, hibernate session, ..) that haven't been injected yet.
So... What I've turned to instead is to create my own BeanBuilder in a BootStrap.groovy file.
BeanBuilder builder = new BeanBuilder(grailsApplication.parentContext)
def bb = builder.beans {
LoginListener(com.foo.LoginListener) {
springSecurityService = ref("springSecurityService")
userService = ref("userService")
}
}
bb.registerBeans(grailsApplication.mainContext)
I have a plugin that relies on a custom url mapping. When i install the plugin i need to copy the content of the UrlMappings.groovy of the plugin and merge it with the one in the application where the plugin is installed
I would like however to register these url mappings directly into the grails framework without copying the content into the application itself. I don't want the user to change these mappings as they are core to how the plugins works.
Anyone can give me hints where to venture to achieve that.
Thank you
-ken
Create another file in grails-app/config/ with a name ending in UrlMappings.groovy and put the customized mappings in there, for example myUrlMappings.groovy
Seems like i need to interface with UrlMappingsHolderFactoryBean directly to be able to do that. I was hoping that there might be an easier way to do that. The code below is taken from the UrlMappingPlugin itself, the only source that i found to help me solve my problem.
if (application.isUrlMappingsClass(event.source)) {
application.addArtefact(UrlMappingsArtefactHandler.TYPE, event.source)
BeanBuilder beans = beans {
grailsUrlMappingsHolderBean(UrlMappingsHolderFactoryBean) {
grailsApplication = application
}
}
ApplicationContext appCtx = event.ctx
beans.registerBeans(appCtx)
HotSwappableTargetSource ts = appCtx.getBean("urlMappingsTargetSource")
ts.swap appCtx.getBean("grailsUrlMappingsHolderBean")
}
Personally I use Java approach and inject mappings form plugin (I have only one plugin for that).
But generally my approach is following:
1.App
class UrlMappings {
static mappings = DimaURLMappings.getMappings()
}
2.Plugin (called "Dima")
class DimaURLMappings {
static def getMappings(){
return {
//Mappings here
}
}
}
Yes I need to add it manually, but on the other hand it's quite obvious where application gets that mappings, and there are no magic.
I use it in such way because I have few applications that use my plugin. If you have few plugins with mappings you will just need to merge them I think it is not hard. you could also return closure from plugin. But don't forget to change "delegate" in application.