File upload - MultipartResolver implementation - grails

I'm dumping the old question content since it's overly complicated.
It's simple now.
How to change the multipartResolver from the standard:
org.springframework.web.multipart.support.StandardServletMultipartResolver
to
org.springframework.web.multipart.commons.CommonsMultipartResolver
?
I'm failing to do so with Grails v3.2.6.
I've tried various things mentioned here (declaring the beans, filters, disabling MultipartAutoConfiguration):
Required MultipartFile parameter 'file' is not present
How to use CommonsMultipartResolver in Spring Boot

Not sure about changing the implementation but I did have to change the respective config settings in application.yml to someting like...
grails:
controllers:
upload:
maxRequestSize: 10000
maxFileSize: 10000
multipart:
maxRequestSize: 5MB
maxFileSize: 5MB

Related

Accessing *Resources.groovy modules via groovy file

The system I maintain is using cached-resources plugin, therefore all of the css/js files are described in Resources.groovy ( stands for my project's name) file.
The usage is normally via *.gsp files, when including resources.
Though, I need to get the list of all files described in there via *.groovy file.
The format of *Resources.groovy file is like this:
modules = {
css {
resource url: 'fileName1.js'
resource url: 'fileName1.js'
...
resource url: 'fileNameN.js'
}
}
How do I get, e.g. "fileName1.js" from service?
Does this work? Given it a quick go in the console for Grails 2.3.4 and it seems to for me, but YMMV:
List urls = grailsApplication.mainContext
.getBean('resourceService') // Instance of [1]
.getModule( 'css' ) // Instance of [2]
.resources // List of [3]
.sourceUrl
ResourceProcessor
ResourceModule
ResourceMeta

Karma + Rails: File structure?

When using the karma javascript test library (née Testacular) together with Rails, where should test files and mocked data go be placed?
It seems weird to have them in /assets/ because we don’t actually want to serve them to users. (But I guess if they are simply never precompiled, then that’s not an actual problem, right?)
Via this post: https://groups.google.com/forum/#!topic/angular/Mg8YjKWbEJ8
I'm experimenting with something that looks like this:
// list of files / patterns to load in the browser
files: [
'http://localhost:3000/assets/application.js',
'spec/javascripts/*_spec.coffee',
{
pattern: 'app/assets/javascripts/*.{js,coffee}',
watched: true,
included: false,
served: false
}
],
It watches app js files, but doesn't include them or serve them, instead including the application.js served by rails and sprockets.
I've also been fiddling with https://github.com/lucaong/sprockets-chain , but haven't found a way to use requirejs to include js files from within gems (such as jquery-rails or angularjs-rails).
We ended up putting tests and mocked data under the Rails app’s spec folder and configuring Karma to import them as well as our tested code from app/assets.
Works for us. Other thoughts are welcome.
Our config/karma.conf.js file:
basePath = '../';
files = [
JASMINE,
JASMINE_ADAPTER,
//libs
'vendor/assets/javascripts/angular/angular.js',
'vendor/assets/javascripts/angular/angular-*.js',
'vendor/assets/javascripts/jquery-1.9.1.min.js',
'vendor/assets/javascripts/underscore-min.js',
'vendor/assets/javascripts/angular-strap/angular-strap.min.js',
'vendor/assets/javascripts/angular-ui/angular-ui.js',
'vendor/assets/javascripts/angular-bootstrap/ui-bootstrap-0.2.0.min.js',
//our app!
'app/assets/javascripts/<our-mini-app>/**',
// and our tests
'spec/javascripts/<our-mini-app>/lib/angular/angular-mocks.js',
'spec/javascripts/<our-mini-app>/unit/*.coffee',
// mocked data
'spec/javascripts/<our-mini-app>/mocked-data/<data-file>.js.coffee',
];
autoWatch = true;
browsers = 'PhantomJS'.split(' ')
preprocessors = {
'**/*.coffee': 'coffee'
}
I found this project helpful as a starting point. https://github.com/monterail/rails-angular-karma-example. It is explained by the authors on their blog.
It's an example rails app with angular.js and karma test runner.

Multi-part form parameters not getting to controller when deployed on JBOSS AS 7.1

I'm trying to deploy a Rails 3.2 app on JBOSS AS 7.1, using JRuby 1.6.6. I think this is almost certainly a JBoss issue.
The app works perfectly under Tomcat and under WebBrick, but not JBoss. When deployed on JBoss, the parameters posted using multi-part forms are stripped before the request arrives at the controller. I suspect there is some JBOSS configuration setting needed to allow uploads of large HTTP packets, but can't figure out where or what to set in JBOSS AS 7.1 to do that.
I don't think the problem is in the Rails controller code, but the easiest way to see the problem is to look at the comments in this code block.
def create
f = params[:uploaded_file]
# ** Under JBOSS, there is no :uploaded_file in the params hash!
# ** Without JBOSS, :uploaded_file is passed in, all is good
data = f.read
# ...
end
The ERB template looks something like:
<%= form_tag xxx_path, :multipart => true do %>
<%= file_field_tag :uploaded_file, :required => true %>
<% end %>
One reason I suspect it involves some size limit, is that if I try uploading very very small files, it works. The file is successfully passed to the controller in the params hash in that case.
Any help would be greatly appreciated.
Here is how I fixed this problem for JBoss 5.1.
Add components.xml file into the root dir of your rails project. Here is the content of this file:
<?xml version="1.0" encoding="UTF-8"?>
<components xmlns="http://jboss.com/products/seam/components"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:security="http://jboss.com/products/seam/security"
xsi:schemaLocation= "http://jboss.com/products/seam/components http://jboss.com/products/seam/components-2.0.xsd
http://jboss.com/products/seam/security http://jboss.com/products/seam/security-2.0.xsd">
<component class="org.jboss.seam.web.MultipartFilter">
<property name="createTempFiles">true</property>
<property name="max-request-size">0</property>
</component>
</components>
Add "components.xml" into config.webinf_files section of your warble.rb config.
For example:
config.webinf_files += FileList["jboss-web.xml", "components.xml"]
I'm not sure whether this is the solution, or just a coincidence, but I increased the heap size and PermGen memory by setting JAVAOPTS and afterwards this problem went away.
The switches that worked were:
JAVA_OPTS=-Xms512m -Xmx1024m -XX:PermSize=128m -XX:MaxPermSize=256m

Grails External Config Read Incorrectly on First Load

Grails 1.3.7
I have some configuration located in an external config file. One of the entires looks like this:
site.maintenance.mode = false
I have a filter which checks for certain config settings for specific URLs. When I do a run-app or deploy a WAR into Tomcat and do:
boolean maintenanceMode = grailsApplication.config.site.maintenance.mode
maintenanceMode is coming back true. If I look at the config object in debug mode, this is what I get:
site={maintenance={mode=false, message="<p>Our trail guides are working hard to get the system back on track.</p><p>We're sorry, the account system is down for maintenance at the moment. We'll get it back online as quickly as we can. Thanks for your patience.</p>"}}
I have a controller that I use to reload this config file dynamically and hitting this controller will fix the issue. But I'm curious as to why it is incorrect on first runs and why the discrepency in what is getting put in the maintenanceMode variable vs what is actually in the config object.
Are you using a Java properties file or a Groovy file? If you're using a properties file then I believe Grails will interpret site.maintenance.mode=false the same way as site.maintenance.mode='false' and since Groovy will interpret:
"false".asBoolean() == true
then that would explain why you would see that initial true value.
I just ran a simple test locally to verify this behavior. When I externalize my properties in a file called test.properties then site.maintenance.mode=false initially gets a boolean value of true, when I use a file called test.groovy then it interprets the boolean value of site.maintenance.mode=false as false. I believe this is because when you use a Groovy file Grails uses ConfigurationSlurper to process it but when you use a properties file Grails interprets everything as String name/value pairs.
What I do is to have an external Config.groovy file, for instance: MyConfig.groovy
At the end of the standard grails Config.groovy file, I have the following:
def ENV_NAME = "MY_EXTERNAL_CONFIG"
if(!grails.config.locations || !(grails.config.locations instanceof List)) {
grails.config.locations = []
}
if(System.getenv(ENV_NAME)) {
grails.config.locations << "file:" + System.getenv(ENV_NAME)
} else if(System.getProperty(ENV_NAME)) {
grails.config.locations << "file:" + System.getProperty(ENV_NAME)
} else {
println "No external Configs found."
}
So now you can have a MyConfig.groovy file anywhere in production environment (for example) and then set an Environment system variable to point to this file (or pass it as parameter to startup.sh), before you start tomcat:
MY_EXTERNAL_CONFIG="/home/tomcat/configs/MyConfig.groovy"
export MY_EXTERNAL_CONFIG
That's it. Now you have an external MyConfig.groovy file. The properties in it are accessible from your grails app as they were part of the standard Config.groovy
import org.codehaus.groovy.grails.commons.*
//...
ConfigurationHolder.config.foo.bar.hello

Dojo custom build with NLS / localisation

I have a problem implementing a cross domain custom build in Dojo.
The situation is as follows: i have a pretty large application, with a good number of localisation bundles, so basicly the directory structures is like
core\ (my module)
nls\
fr\
en\
....
When building my module the result is a big core.js/core.xd.js file, which, bien sur, does not contain the localisations. In the localisation nls directories (en/fr/etc) i find after the build each bundle builded/minified, and a bigger file for each language, core_fr.js/core_en.fs, which contains only Dojo/Dijit related strings.
so my build script is
layers: [
{
resourceName: "core",
name: "../core/trusted.js",
dependencies: [
"dojo.i18n",
//data
"dojox.data.JsonRestStore",
"dojox.data.XmlStore",
"dojox.rpc.Service",
"dojox.form.FileInput",
...
"core.controller.Fusebox"
],
prefixes: [
["dijit","../dijit"],
["dojox","../dojox"],
["core", "../core"]
]
In the core.controller.Fusebox class i try to load 1 nls
dojo["requireLocalization"]("core", "FuseboxContent");
here it will die, however with
availableFlatLocales is undefined
[Break on this error] var locales = availableFlatLocales.split(",");\r\n
My config in the html file is :
// version build
var djConfig = {
baseUrl: 'https://..../',
modulePaths: { 'core': 'core'},
useXDomain: true,
xdWaitSeconds: 10,
parseOnLoad: true,
afterOnLoad: true,
// debugAtAllCosts: true,
isDebug: true,
locale: "fr"
};
and then
<script type="text/javascript" src="http://xd.woopic.com/dojoroot/1.3.2-xd/dojo/dojo.xd.js.uncompressed.js"></script>
<script type="text/javascript" src="https://..../core/trusted.js.uncompressed.js"></script>
I used the uncompressed for debug, of course.
The problem is that, on runtime, Dojo tries to load my bundles and can not find them, and i would like to embed them in my layer file, so no extra loads will be required.
Can this be achieved? And while we're at it, are there any working sites/examples with cross domain localisations?
UPDATE: i continued my analysis and the problem seems to lay in the fact that i am dynamicaly loading nls, so the build parser can not find the requireLocalization() calls. Therefore the project nls file contains only dojo/dijit related content. However, i added a few bundle loads in a dummy file, and the content of core/nls is still ignored by the builder.
Thanks for any info, i am pretty much at the end of my searches, there isn't much on the net on this subject.
I had a similar issue a few days ago. First of all, you can get around the error by setting the available locales as the 4th parameter of the requireLocalization call.
e.g.
dojo.requireLocalization("core", "FuseboxContent", null, "en,fr");
though you should not have to do that.
Did you try including the localization as follows?
dojo.requireLocalization("core", "FuseboxContent"); // and not dojo["require..."]

Resources