dropwizard: read configuration from a non-file source - java

What's the right way to read configuration in dropwizard from something like a database, or a REST call? I have a use case where I cannot have a yml file with some values, and should retrieve settings/config at startup time from a preconfigured URL with REST calls.
Is it right to just invoke these REST calls in the get methods of the ApplicationConfiguration class?

Similar to my answer here, you implement the ConfigurationSourceProvider interface the way you wish to implement and configure your dropwizard application to use it on your Application class by:
#Override
public void initialize(Bootstrap<MyConfiguration> bootstrap){
bootstrap.setConfigurationSourceProvider(new MyDatabaseConfigurationSourceProvider());
}
By default, the InputStream you return is read as YAML and mapped to the Configuration object. The default implementation
You can override this via
bootstrap.setConfigurationFactoryFactory(new MyDatabaseConfigurationFactoryFactory<>());
Then you have your FactoryFactory :) that returns a Factory which reads the InputStream and returns your Configuration.
public T build(ConfigurationSourceProvider provider, String path {
Decode.onWhateverFormatYouWish(provider.open(path));
}

elaborating a bit further on Nathan's reply, you might want to consider using the UrlConfigurationSourceProvider , which is also provided with dropwizard, and allows to retrieve the configuration from an URL.
Something like:
#Override
public void initialize(Bootstrap<MyRestApplicationConfiguration> bootstrap) {
bootstrap.setConfigurationSourceProvider(new UrlConfigurationSourceProvider());
}

Related

Mocking REST API calls with SpringBoot profiles

I have recently started out with Spring and am unsure about how to approach this issue. I have a Spring boot program which makes calls to remote REST APIs. For example an AddressService class with getAddress(String user) method, which makes a HTTP call and returns a JSON response. I would like to set up Spring profiles for development purposes local, dev, uat, prod.
When the program is running with the local profile, I would like to "mock" these external API calls with an expected JSON response, so I can just test logic, but when it is run in any of the other profiles I would like to make the actual calls. How can I go about doing this? From what I read, there's many ways people approach this, using WireMock, RestTemplate, Mockito etc. I'm confused about which is the way to go.
Any advice would be greatly appreciated. Thanks.
WireMock,Mockit is for unittest, to mock the real request. Example here:
How do I mock a REST template exchange?
When you need a running implementation with a mock, i think the easiest way is that you have a interface
public interface AdressAdapter {
public List<Adress> getAddress(String name);
}
And two different implementations depending on the profile.
#Profile("local")
public class DummyAdress implements AdressAdapter{
#Override
public List<Adress> getAddress(String name) {
//Mock here something
return null;
}
}
! means NOT locale profile in this case.
#Profile("!local")
public class RealAdress implements AdressAdapter{
#Override
public List<Adress> getAddress(String name) {
//Make Restcall
return null;
}
}
What you could do is use different application.properties files depending on your profile. That way, you just change the url to a mock server for your local profile.
So what you have to do is :
Create another application.properties in your resources folder named : application-local.properties.
Change the url of the desired service.
Start your application with the VM option -Dspring.profiles.active=local.
Here is a link that describe well what you want to achieve.
For your mock server, you could use Wiremock, Mountebank, Postman,... that can be start separately and mock specific endpoints to return what you want.

Spring cache/fallback framework

My use case is that I want to cache certain request:response in my service caller classes:
public class Abc{
public Response serviceCall(Request r){}
}
public class Memcached{
public Response get(Request r){}
public void put(Request r, Response rs){}
}
I want to use memcached for caching . The request would be the key and value would be the response. Whenever serviceCall() is called I want to check if request is already present in cache if so then return response from the cache.
If not then actually execute serviceCall() method and put request:response key:value in memcached
Is there any way in spring to achieve the same.
I did look into #Cacheable here http://www.baeldung.com/spring-cache-tutorial
But I am unable to understand how I make spring use my "Memcached" class, more specifically where do I wire my "Memcached" class so that it is available to class "Abc" in above example
Could you please help . I am working in spring boot completely annotation based and looking for annotation based solution
Spring caching doesn't support Memcached by out-of-the-box (Supported Cache Providers).
If you want to use Memcached in your project please check out Memcached Spring Boot caching library.
There is also an example Java project of how to use Memcached with Spring.
You don't need the memcached class. Just put the #Cacheable annotation on Abc.serviceCall as per the baeldung tutorial.

Is there a SelfAttachingServerResource for Restlet?

I'm trying to create a Framework on top of Restlet and my question would be, is it possible to have a ServerResource to be "injected" from outside the org.restlet.Application code?
The standard way is to have a resource injected here:
public class FrameworkApplication extends Application {
private static final String ROOT_URI = "/";
/**
* Creates a root Restlet that will receive all incoming calls.
*/
#Override
public Restlet createInboundRoot() {
Router router = new Router(getContext());
router.attach(ROOT_URI, RootServerResource.class);
return router;
}
}
However since I am building a framework the use of FrameworkApplication is through including it as a dependency:
<dependency>
<groupId>com.mycompany</groupId>
<artifactId>myframework</artifactId>
<version>0.0.1</version>
</dependency>
Going back to the question, I want to know if it is possible to have a ServerResource to be added in the Restlet routing like this:
public class PluggableResource extends ServerResource {
#Get("json")
public String represent() {
// stuff
return resp;
}
}
In the case of dependency injection, the solution was to do, SelfInjectingServerResource now can I make such a SelfAttachingServerResource?
I don't know what you exactly want to do but auto-discovering support of server resources isn't supported in Restlet. You need to implement by your own within a dedicated implementation of the class Application of Restlet. The method createInboundRoot would be responsible to scan the classpath to detect server resources. Moreover you need to add more metadata for server resources (with annotations for instance) to specify the attachement path.
However, the JAX-RS support provides this feature. It provides a set of annotations to make easy to identify server resources and provide metadata like attachement path, methods and exchanged media types for methods. Here is a sample of use: http://restlet.com/technical-resources/restlet-framework/guide/2.3/extensions/jaxrs. The classes for server resources need to be register by hand but you can go further. As a matter of fact, you can scan the classpath to detect classes having the annotation Path. See this link for the way to implement such ferature: Scanning Java annotations at runtime. In this case, they will be autodetected based on annotations. Is something can suit your needs?
Hope it helps.
Thierry

Using Spring Solr Data or Not for Flexible Requests as Like Backup?

I want to implement an application at Spring that interacts with my current Solr or SolrCloud. I consider of using Spring Data Solr or not. However I think that there is no CloudSolrServer implemented at it yet on the other hand if I just run a query like that:
http://localhost:8983/solr/replication?command=backup
and check whether backup is completed or not(I will do a get request, parse JSON and will see that last backup time is changed or not) How I can integrate it with Spring Data Solr?
I mean is it more meaningful using Spring + Solrj instead of Spring Data Solr at my situation (that is I want to do more flexible things that just CRUD operations on Solr with Spring)?
True, there is no support for CloudSolrServer yet. What you can do is provide you own SolrServerFactory.
public class CloudSolrServerFactory implements SolrServerFactory {
private final CloudSolrServer solrServer;
public CloudSolrServerFactory(String zkHost) throws MalformedURLException{
this.solrServer = new CloudSolrServer(zkHost);
}
#Override
public SolrServer getSolrServer() {
return this.solrServer;
}
#Override
public String getCore() {
return "";
}
}
Next you can add custom behavior to all your repositories as described in Section 1.3 of Spring Data Commons documentation. Have a look at this (not an implementation of your issue, rather general usage of custom repositories) to get the idea of how it might work.
Please feel free to open a feature request as this is definitely something missing Spring Data Solr.

How do I inject a dependency into a Jersey resource?

I'm using Jersey to build a REST API, with Grizzly. I'm not using any dependency injection framework like Google Guice.
One of the resources needs to retrieve data from a Map in response to a GET request.
I can't figure out how I can inject this Map into the resource, since with Jersey I don't control how the resource is initialized.
I realize I could just declare the Map as static but that seems like a very ugly solution.
I eventually found the solution, I need to create a "Provider", as follows:
#Provider
public class DBPoolInjectableProvider extends SingletonTypeInjectableProvider<Context, BoneCPDataSource> {
public DBPoolInjectableProvider() throws SQLException {
super(BoneCPDataSource.class, APIMain.getDBPool());
}
}
As you can see, in this case I actually needed to get access to a database connection pool, but the same idea will work for any other type of object.
I just put this provider in a package that is scanned by Jersey and it picks it up and uses it whenever it sees a method like this in a Jersey resource:
public TestResponse testGet(#Context final BoneCPDataSource ds) throws SQLException {
...
}
(Personally I think that this kind of "action at a distance" is an anti-pattern, but I've got it working now so I'll shut up)
You can do the following:
Create a filter which has access to a map which you need.
Declare a thread local variable in the Filter
Before processing request, put a map into the variable
In your resource, when you need to have access to the map, access that local variable
After processing request, clean this map.
It's actually, almost the same as declaring a session per request with Hibernate/JPA.

Categories