How to use bazaarvoice dropwizard configurable assets bundle - bundle

Hi all,
at Can DropWizard serve assets from outside the jar file? I have read, that it is possible to serve static files outside of jar file with dropwizard-configurable-assets-bundle (later only DCAB).
But there are no examples available on the web. The only one, at their github page is not very helpful for me.
Firstly, there is said, that I should implement AssetsBundleConfiguration, but there is no mention where should I use it then.
Next, in service I should put this row:
bootstrap.addBundle(new ConfiguredAssetsBundle("/assets/", "/dashboard/"));
But unfortunately, it is showing me an error, that it is not applicable for that argument.
And in third part there is some yaml, but I don't know, whether it's produced by bundle, or whether I should put it somewhere.
And I noticed, that paths are relative to src/main/resources. Is there also option how to access files outside of that?

So the steps are pretty much like described in the README.md
You start with dependency
dependencies {
compile 'com.bazaarvoice.dropwizard:dropwizard-configurable-assets-bundle:0.2.0-rc1'
}
AssetBundleConfiguration interface needs to be implemented by you standard configuration file. So in my case:
public class BookRespositoryConfiguration extends Configuration
implements AssetsBundleConfiguration {
#Valid
#NotNull
#JsonProperty
private final AssetsConfiguration assets = new AssetsConfiguration();
#Override
public AssetsConfiguration getAssetsConfiguration() {
return assets;
}
}
This configuration is referred in you Application class
public class BooksRepositoryApplication
extends Application<BookRespositoryConfiguration> {
#Override
public void initialize(Bootstrap bootstrap) {
bootstrap.addBundle(new ConfiguredAssetsBundle("/assets/", "/books/"));
}
#Override
public void run(BookRespositoryConfiguration configuration,
Environment environment) throws Exception {
//...
}
}
And finally configuration. The configuration path is relative to the document-root, so in my case the assets are located outside the application folder.
assets:
overrides:
/books: ../book-repository
Now after running the app you can easily navigate to http://localhost:8080/books/some-static-files.html

Look at upto-date dropwizard-configurable-assets-bundle maintained at official dropwizard-bundles.
https://github.com/dropwizard-bundles/dropwizard-configurable-assets-bundle.

Related

Using getProject() with Gradle Configuration Cache

Gradle documentation states that using the getProject() method in the #TaskAction method of a Task class should not be used if you want compatibility with Gradle Configuration Cache. The question I have is that, suppose you have something like this:
public abstract class AbstractMyTask extends DefaultTask {
#Internal
protected abstract DirectoryProperty getRootDirectory();
protected AbstractMyTask() {
getRootDirectory().convention(getProject().getRootProject().getLayout().getProjectDirectory());
}
}
The general intent of the code snippet is to have a Directory property representing the root project directory (ie. a safe replacement for getProject().getRootDir()), and it seems like the getProject() call in the constructor would be okay. I'd like some sober second thought on whether that is the case.

Using Spring repository in static methods for setting up test data

In order to setup test data for my Spring Boot integration tests, I'd like to create some helper classes and methods which populate the data using the repositories.
Here is an example:
#Component
public class TestUtils {
private static TemplateRepository templateRepository;
#Autowired
public TestUtils(TemplateRepository templateRepository) {
TestUtils.templateRepository = templateRepository;
}
public static void createTemplates() {
Template template = Template.builder()
.content("some content")
.build();
templateRepository.save(template);
}
}
Due to a lack of experience, I cannot tell if this approach is fine. It it "safe" to inject the repository as static? Or are there better approaches for setting up test data?
Don't use static. If you want to use Java to initialize the data in the repository, just do so in your test.
What you can do if you need to create a few things in different repositories is create a dedicated component:
#Component
public class DatabaseInitializer {
private final TemplateRepository templateRepository;
private final MyOtherRepository myOtherRepository;
// Add constructor here
public void createInitialData() {
// Use repositories to persist some data
}
#ExtendWith(SpringExtension.class)
#Import(DatabaseInitializer.class)
class MyTest {
#Autowired
private DatabaseInitializer initDb;
#Test
void myTest() {
initDb.createInitialData(); // Or put this in a `#Before..` method
// actual test here
}
}
I use TestContainers and Flyway.
You can make SQL scripts and annotate test methods with #Sql and provide a .sql file and/or statements to be run.
You can store these .sql files in the test/resources folder.
Loading Initial Test Data
There is a very well explained process to initialize the data in docs. I would advice you to refer below
https://docs.spring.io/spring-boot/docs/current/reference/html/howto.html#howto.data-initialization
You just have to manintain Insert statements in predefined sql files.

Load custom properties file in Spring Boot MVC Main

I have created a myApp.properties in resources folder location and mentioned the server.port in this file.
myApp.properties
myApp.server.port=8020
Now I want to read load this property into my application. But I have to read this before I actually a server.
Here I am trying to do like this
#SpringBootApplication
#ComponentScan(basePackages = {"com.myorg.myapp" })
#EnableConfigurationProperties
#PropertySource("classpath:myApp.properties")
#Component
public class MyAppApplication {
#Value("${myApp.server.port}")
private static String serverPort;
public static void main(String[] args) throws Exception{
try {
SpringApplication appCtxt = new SpringApplication(MyAppApplication.class);
appCtxt.setDefaultProperties(Collections
.singletonMap("server.port", serverPort));
appCtxt.run(args);
} catch (Exception e) {
e.printStackTrace();
}
}
But serverPort is coming as null.
I also tried to create a separate Config file like this but it can't be accessed in static main
#Configuration
#PropertySource("myApp.properties")
#ConfigurationProperties
public class MyAppConfig {
#Value("${myApp.server.port}")
private String serverPort;
/**
* #return the serverPort
*/
public String getServerPort() {
return serverPort;
}
}
Any suggestion would be helpful.
Spring boot injects properties during the initialization of the application context.
This happens (gets triggered) in the line:
appCtxt.run(args);
But you try to access the property before this line - that why it doesn't work.
So bottom line, using "#Value" in the main method doesn't work and it shouldn't.
Now from the code snippet, it looks like you could merely follow the "standards" of spring boot and create the file application.properties with:
server.port=1234
The process of starting the embedded web server in spring boot honors this property and bottom line it will have the same effect and Tomcat will be started on port 1234
Update 1
Based on OP's comment:
So, how can I have multiple application.properties.
In the Spring Boot's documentation it is written that application.properties are resolved from the classpath. So you can try the following assuming you have different modules A,B,C and web app D:
Create src/main/resources/application.properties inside each of 4 modules and pack everything together. The configuration values will be merged (hopefully they won't clash)
If you insist on naming properties A.properties, B.properties and C.properties for each of non-web modules, you can do the following (I'll show for module A, but B and C can do the same).
#Configuration
#PropertySource("classpath:A.properties")
public class AConfiguration {
}
Create in Module A: src/main/resources/A.properties
If you need to load the AConfiguration automatically - make the module A starter (using autoconfig feature of spring-boot):
Create src/resources/META-INF/spring.factories file with the following content:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
<package_of_AConfiguration>.AConfiguration
Also this has been the requirement to separate C from entire bundle where it might run as bundle for some and as a separate for some others
Although I haven't totally understood the requirement, but you can use #ConditionalOnProperty for configuration CConfiguration (that will be created just like AConfiguration.java in my previous example) but this times for module C.
If the conditional is met, configuration will run and load some beans / load its own properties or whatever. All in all conditionals (and in particular Profiles in spring) can help to reach the desired flexibility.
By default, the application.properties file can be used to store property pairs, though you can also define any number of additional property files.
If you save myApp.server.port=8020 in application.properties, it will work fine.
To register a custome property file, you can annotate a #Configuration class with the additional #PropertySource annotation:
#Configuration
#PropertySource("classpath:custom.properties")
#PropertySource("classpath:another.properties")
public class ConfigClass {
// Configuration
}
make sure, your class path is correct.

Spring: how to use resourceLoader to inject a file located on the machine but not in the classpath

I want the spring application to be able to go into the localhost and load a given path into the resource loader so it can be read by the server. The code below is trying to access a file a valid .txt file on my computer stored on my desktop.
What follows is my resource-loader implementation.
#Component
#Scope("prototype")
public class CustomResourceLoader implements ResourceLoaderAware {
#Autowired
private ResourceLoader rsld;
#Override
public void setResourceLoader(ResourceLoader rsld) {
// TODO Auto-generated method stub
this.rs = rs;
}
public void showResource(String path) throws IOException{
Resource resour = rsld.getResource("file:"+path);
File fl = resour.getFile();
System.out.println(fl.exists());
System.out.println(fl.getAbsoluteFile());
System.out.println(fl.getName());
}
}
The output to calling the show resource method is as follows:
false
/Users/wes/Documents/workspace/rest-services-AM/{
"/Users/wes/Desktop/wes.txt"}
wes.txt
I understand that this means that my resource is not returning an actual file so i can not use it. Any help would be appreciated.
Thanks.
As nobody seems to be aware of, I found out that it's just necessairy to use double slashes like:
#Value("\\\\MY-MACHINE\\thefile.txt")
private Resource file;
In some cases you may required a file: statement before, like: file:\\MY-MACHINE\thefile.txt"

Robospice Impossible to start SpiceManager as no service of class

I am trying to use following libraries to develop my app.
Robospice
Gson
and Spring for android
To do so, In my gradle file I have following dependencies added
compile 'com.octo.android.robospice:robospice-spring-android:1.4.13'
compile 'com.google.code.gson:gson:2.2.4'
And in manifest file, I have following lines inserted inside application tag.
<service
android:name="com.octo.android.robospice.GsonSpringAndroidSpiceService"
android:exported="false" />
Now, I created a base class that is used as Base Activity. And, I have did this in the following way:
public class BaseSpiceActivity extends Activity {
private SpiceManager spiceManager = new SpiceManager(GsonSpringAndroidSpiceService.class);
#Override
protected void onStart() {
spiceManager.start(this);
super.onStart();
}
#Override
protected void onStop() {
spiceManager.shouldStop();
super.onStop();
}
protected SpiceManager getSpiceManager() {
return spiceManager;
}
}
And then I used that base class to extend my own class where I had to use spice service request.
SimpleTextRequest text = new SimpleTextRequest(placeUrl);
getSpiceManager().execute(text, "place", DurationInMillis.ONE_MINUTE, new RequestListener<String>() {
//Other functions and codes
}
)
But when the above code gets executed, I am getting following error
E/AndroidRuntime﹕ FATAL EXCEPTION: SpiceManagerThread 0
java.lang.RuntimeException: Impossible to start SpiceManager as no service of class : com.octo.android.robospice.SpiceService is registered in AndroidManifest.xml file !
at com.octo.android.robospice.SpiceManager.checkServiceIsProperlyDeclaredInAndroidManifest(SpiceManager.java:1287)
at com.octo.android.robospice.SpiceManager.tryToStartService(SpiceManager.java:1168)
at com.octo.android.robospice.SpiceManager.run(SpiceManager.java:247)
at java.lang.Thread.run(Thread.java:856)
I have been trying to solve the issue from many hours. But unfortunately couldn't. Please help me out.
I am 100% sure you got messed somewhere. Search for new SpiceManager(SpiceService.class); in your code, and you will find out that you do use this service instead of the desired GsonSpringAndroidSpiceService.
You need to declare your service in your manifest.xml
Like this
<service android:name=".SampleRetrofitService"
android:exported="false"/>
Try to find out where using SpiceManager.
In my case, I named a activity SpiceActivity, and others extend it.
But robospice library also offer a activity named SpiceActivity. And it uses new SpiceManager(SpiceService.class)
So activity extends the wrong SpiceActivity which use SpiceService, then cause the error.

Resources