Spring cloud config - Share file or his location - java

I have two applications :
one spriig boot config server
the another one a spring boot config client
The client side have to use a file named certificate.json.
I want to store this file in the server side so another microprogram and my client programm who need it can retrieve it from the server side.
I try that :
copy the file certificate.json to classpath:/config
add this line to the application.properties :
certificate.location: classpath:config/certificate.json
call the value from client programm by :
#Value("${certificate.location}")
private String certificateLocation;
But the value of certificateLocation is classpath:config/certificate.json. The value I want is the file location like : /home/user/project/scr/main/resources/config/certificate.json.
Or, are there a way to directly retrieve my file by URI, for example locahost:8889/... (8889 is my config server port).
EDIT 1:
I cannot use absolute path from the server because I'm not the one who run it.
Thank you in advance.

I'd do
#Value("${certificate.location}") private Resource certificateLocation;
that way, your location is already a Resource that you can load, call getURI(), getFile().getAbsolutePath() etc. Since your value is prefixed with classpath:, you would have a ClassPathResource instance, which you can use for lot of things.

The classpath is just a protocol part of the URL. You can use file or any other supported protocol. For example, file://home/user/project/scr/main/resources/config/certificate.json.

Try this url
spring.cloud.config.server.native.searchLocations
=file://${user.home}/CentralRepo/
SPRING_PROFILES_ACTIVE=native
I am also get this way using microservice

OP you need to create a web service and return certificate.json as the response. Then you can send and receive data by sending a GET or POST request to a URI like https://12.12.12.12:8080/getCertificate. Please see:
https://spring.io/guides/gs/rest-service/
As a side note, you should never expose your inner files to the internet because it's very unsecure and opens you up to pirating and hacking.

What I would do in this case is
Add configuration for static folder
#SpringBootApplication public class DemoStaticresourceApplication extends WebMvcConfigurerAdapter {
public static void main(String[] args) {
SpringApplication.run(DemoStaticresourceApplication.class, args);
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/files/**").addResourceLocations("file:/fileFolder/")
.setCachePeriod(0);
}
}
Place certificate.json in fileFolder and try http://localhost:8080/files/certificate.json and it will be served directly from file system for you.
And now every file you add in this folder will be served only if called using /files/ path

Related

How to get applicationContextPath in dropwizard 1.0.0

We are using server configuration in yml file which looks like as below
server:
type: simple
connector:
type: http
port: 8061
applicationContextPath: /administration
adminContextPath: /admin
#disable the registration of default Jersey ExceptionMappers
registerDefaultExceptionMappers: false
I want to get "applicationContextPath" when I start my dropwizard service.
I am trying to get it using
environment.getApplicationContext().getContextPath();
but I am getting "/" i.e. default value. Is there anyway to get this.
In order get applicationContextPath we need to get ServerFactory from Configuration and parse it to SimpleServerFactory as below:
((SimpleServerFactory) getConfiguration().getServerFactory()).getApplicationContextPath()
This works for me:
#Override
public void run(CustomAppConfiguration customAppConfiguration , Environment environment) throws Exception {
DefaultServerFactory factory = (DefaultServerFactory) customAppConfiguration .getServerFactory();
System.out.println("CONTEXT PATH: "+factory.getApplicationContextPath());
...
}
If it's in your config file and you want to just read the value in as it exist in your config.yml, then I'd suggest making it part of your Configuration class. Values in your config can always be accessed this way regardless of whether dropwizard uses and treats those key/values in special manner internally.
The following worked for me in dropwizard 1.0.0:
MyApp.java:
public class MyApp extends Application<MyConfig> {
//...
#Override
public void run(MyConfig configuration, Environment environment) throws Exception {
System.out.println(configuration.contextPath);
//...
MyConfig.java
public class MyConfig extends Configuration {
//...
#JsonProperty("applicationContextPath")
public String contextPath;
//...
If I understood your question correctly what you can do in Dropwizard version 1.3.8 if you are using simple server (without https) you can get applicationContextPath in following way:
server:
type: simple
rootPath: /*
applicationContextPath: /administration
adminContextPath: /admin
connector:
type: http
port: 8080
More info about rootPath can be found in Dropwizard Configuration Reference. So if you want to access:
Application REST endpoint /books (which is value of GET,
POST or similar annotation in one of your Resource class methods) you can
type URL like this http://localhost:8080/administration/books
Metrics (only accessible via admin context path) of your Dropwizard application then you create URL like this: http://localhost:8080/admin/metrics
Hope that helps. Cheers!

dropwizard: read configuration from a non-file source

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());
}

RestEasy TJWS base path

I'm creating an embedded server using JBoss RestEasy's embedded TJWS. The limited documentation is inaccurate, but I was able to create a server instance with a test JAX-RS resource:
#Path("test")
public class TestResource {
public static void main(String[] args) throws Exception {
TJWSEmbeddedJaxrsServer tjws = new TJWSEmbeddedJaxrsServer();
tjws.setPort(8080);
tjws.start();
tjws.getDeployment().getRegistry().addPerRequestResource(TestResource.class);
}
...
That allows me to browse to http://localhost:8080/test to test the GET method implementation (not shown here).
But how do I specify that the embedded server should be mounted at some other base path? For example, how do I get the test resource mounted to http://localhost:8080/example/test? Sure, I could hard code this into the #Path designation, but the base path shouldn't be part of the resource---I should be able to redeploy this resource class in a J2EE server at any base path.
I'm guessing there is something like a tjws.getDeployment().setBasePath("example") that I haven't found, yet. (If anybody has some in-depth documentation for this please let me know as well!) Thanks in advance.
So far I've found that I can simulate this by specifying a prefix when adding resources to the server:
tjws.getDeployment().getRegistry().addPerRequestResource(TestResource.class, "example");
That's not quite the same as I was looking for, but it does allow me to access the resource as http://localhost:8080/example/test without being forced to indicate this base path in the resource definition.

Spring application URL in scheduled job

Is it possible to get the application URL in spring scheduled job (#Scheduled annotated)?
I want to create a job which sends an email with URL to specific page on the application, let's say on http://localhost:8080/appName/some/specific/url. The problem is that the part http://localhost:8080/ will be different in each environment (local,dev,production etc).
Is there any simple way to get a base URL in server-side method which is executed by spring scheduler?
I do that with a properties file. This tutorial tells you how you can do it.
The only complex part is you need a way to change the value the properties file is referencing for each of your different environments.
There is no direct way to get the base url within your scheduler. You may want to look at work arounds for this, like
Use a properties file to store url for each environment
Have a Configurartion bean which implements ServletContextAware. This bean would be automatically notified when a web context is initialised.
public class AppConfig implements ServletContextAware{
private String baseUrl;
public String getBaseUrl(){
return baseUrl;
}
public void setServletContext(ServletContext servletContext){
this.baseUrl=servletContext.getRealPath("/");
}
}

Serve images outside web application

I want to access static files, which are outside my web application in a known directory. I have read many options over the www, but I have still some questions about this.
Basically I want to declare a context for the defaultservlet of my application server. In my case I'm trying with the Tapestry Tutorial, which is a Maven based project and imported to eclipse.
The idea was to create a httpservlet, which gets the file from the location. Do someone of you know where I can grab an example of such a servlet and how I can call him? I know that the servlet must be probably declared as a service, because all pages of the application need to access the files, but I could also be mistaken and it is enough to import it, let say, in the layout page (All pages use the layout.tml file). I basically don't have any clue how to do it with a servlet. Can someone show me the light?
Tank you very much.
Another simpler solution is to create a page which returns a stream response
public class StaticFile {
StreamResponse onActivate(String fileName) {
return new StaticFileStreamResponse(fileName);
}
}
Then in another component / page
#Inject ComponentResources resources;
public Link getStaticFileLink() {
return resources.createPageRenderLinkWithContext("StaticFile", "path/to/myFile.jpg");
}
TML
<img src="${StaticFileLink}" />
But then you won't take advantage of tapestry's 304 NOT_MODIFIED response as in my other solution.
The tapestry way of doing this is by contributing an AssetRequestHandler and an AssetFactory.
AppModule.java
public static void contributeAssetDispatcher(
MappedConfiguration<String, AssetRequestHandler> config,
ResourceStreamer streamer)
{
config.add("staticfile", new StaticFileAssetRequestHandler(streamer));
}
public void contributeAssetSource(
MappedConfiguration<String, AssetFactory> config)
{
config.add("staticfile", new StaticFileAssetFactory());
}
Then in your tml you can use
<img src="${asset:staticfile:path/to/myFile.jpg}" />
Take a look at the ContextAssetRequestHandler, ClasspathAssetRequestHandler, ContextAssetFactory and ClasspathAssetFactory for inspiration.
Be careful not to open up a security hole where a hacker can access any file on your server by passing file paths prefixed with ../../

Categories