Different ports on spring actuator - java

We have following spring setup:
Our application is running on port 80, but our managment.server.port is set to 8081. And we use multiple checks of the management endpoints from this secured port already.
server.port=80
management.server.port=8081
management.endpoints.web.exposure.include=*
With this settings we can hide any sensitive information from the public interface on port 80.
But now our requirements changed: We need to display the version of our application on the public interface. This information is part of the info-endpoint of our management-server on /actuator/info
Is it possible to move only the info endpoint to port 80, and let all other management.server endpoints still on 8081?
Or is there any other suitable solution for our requirement to only open the info endpoint for external calls.
We prefer to not change any firewall setting: so one port is public, and the other is internal only

No you can't move only one endpoint to different port.
This about the actuator as an application that runs on one specific port (8081) in this case and exposes a bunch of services, so its all-or-nothing from this standpoint.
So you'll have to create a special rest controller that would read the file (or keep the memory) the data just like the info endpoint does.
Its a pretty staightforward code actually, it reads a file available in the spring boot artifact anyway and exposes its content.
You can checkout the source code of the info endpoint of the actuator here

Related

Elasticsearch Client is defaulting to localhost

I am using spring.data.elasticsearch with Elasticsearch 7.14.1 in my Spring Boot (2.5.4) application.
My application.properties is something like this
spring.elasticsearch.rest.uris=elasticsearch:9200
spring.data.elasticsearch.cluster=elasticsearch:9200
spring.data.elasticsearch.repositories.enabled=true
This works fine as long as the invocation is from localhost, no issues. However, when I try to bring up my Spring Boot container, I see a failure with NoReachableHostException
reactor.core.Exceptions$ErrorCallbackNotImplemented: org.springframework.data.elasticsearch.client.NoReachableHostException: Host 'localhost:9200' not reachable. Cluster state is offline.
blah-blah-service
Caused by: org.springframework.data.elasticsearch.client.NoReachableHostException: Host **'localhost:9200'** not reachable. Cluster state is offline.
blah-blah-service
at org.springframework.data.elasticsearch.client.reactive.SingleNodeHostProvider.lambda$lookupActiveHost$3(SingleNodeHostProvider.java:101)
Clearly, my suggestion to use "elasticsearch" host (defined network, that is tested and accessible from within and outside docker containers), hasn't gone well with Spring Data for whatever reason. I have even used
#PropertySource("classpath:mysearch.properties")
in my application to try and coax these properties into the app, but doesn't look like anything works. Is there something I am missing in my Elasticsearch configuration or otherwise?
PS: I have exercised curl http://elasticsearch:9200 from within the container and find no issues
These configurations are Spring Boot specific, Spring Data Elasticsearch does not use them. But as far as I can see, you are configuring the transport client (cluster entry, should not be used anyway) and the imperative REST client, but according to the error message you are using the reactive REST client.
According to the Spring Boot documentation you would need to set spring.data.elasticsearch.client.reactive.endpoints
In the .properties file, I used the below and solved the issue for me;
spring.elasticsearch.rest.uris=http://localhost:<port_number>
spring.data.elasticsearch.client.reactive.endpoints=localhost:<port_number>

Eureka service always registers instances with host name even though i put "prefer-ip-address: true"

I want to register my micro services in Eureka with the IP address instead of host name.
I have tried both prefer-ip-address and eureka.instance.preferIpAddress=true properties. None of those worked for me.
Here is my eureka service application .yml file.
This is my Authorization-server micro-service application.yml
But still eureka console showing my services registered with host name(localhost) instead of IP address
I am using Spring boot 2.2.2 version and Spring cloud Hoxton.RELEASE. I am guessing the properties aren't working properly.
Is anyone experiencing the same problem?
Finally i figured out where i can see preferIpAddress property changes. Hover your mouse to instance. Then in the bottom left corner you can see the IP.
Before applying property preferIpAddress = true
After applying property preferIpAddress = true
Well I am on mobile so do not see everything clearly but seems like a problem In declaration
Correct syntax is
eureka.instance.preferIpAddress
Whereas you are using
eureka.instance.prefer-Ip-Address
See documentation: https://github.com/spring-cloud/spring-cloud-netflix/blob/a7398842078319dcaa353a708c12bb7b9fa85a4e/docs/src/main/asciidoc/spring-cloud-netflix.adoc#prefer-ip-address
eureka.instance.preferIpAddress=true will make instance register to Eureka server with IP address. You do not need to provide IP address in any configuration as that will be automatically picked up from system by the application.
In worst case scenario you can define specific IP address.
if you set either the eureka.instance.hostname or the eureka.instance.ipAddress those will always be used in the EurekaInstanceConfigBean so if those are not making it to the server in the registration we need to look at how it is used to build the InstanceInfo.

checking whether spring boot application is running or not

I've created a spring boot project and deployed it on a vm. I've added a command in local.rc that starts the spring boot application on reboot. I want to check whether the command got executed and the application is running. How do I do that?
There are two ways
On system level - you can run your project as a service, which is documented in the Official documentation - Deployments. Then you can query the application status service myapp status.
On application level - include Spring Boot Actuator in your app and use the Actuator endpoints such as /actuator/health as per Official documentation - Production Ready Endpoints. These endpoints can be exposed via HTTP or JMX.
Note: prior to spring boot 2.0 the actuator endpoint is /health
If it's a web project, it makes sense to include spring-boot-actuator (just add a dependency in maven and start the microservice).
In this case, it will automatically expose the following endpoint (for example, its actually can be flexibly set up):
http://<HOST>:<PORT>/health
Just issue an HTTP GET request, and if you get 200 - it's up and running.
If using an actuator is not an option (although it should be really addressed as a first bet), then you can merely telnet to http://<HOST>:<PORT>
The ratio behind this is that that PORT is exposed and ready to "listen" to external connections only after the application context is really started.

Spring Eureka server does not find context-path in client url

When a client application is registered into Spring Eureka server the client id appears at dashboard, but the link url only contains the hostname and port without the context-path of client.
If I create the Spring Boot client application without setting a context-path, I mean default root context, Eureka server can access all actuators available in there.
Is there any way to inform Eureka server about it? I tried to set health and info properties, but it did not work.
If your Eureka client is setup via Spring's #EnableEurekaClient, then the client will default the health check and status check to /health and /info respectively. (These paths may be the default values beyond the Spring #EnableEurekaClient setup, but I am unfamiliar with those at this point in time).
You can override these defaults by setting the following properties:
eureka.instance.statusPageUrlPath
eureka.instance.healthCheckUrlPath
The Spring Cloud Documentation contains this information, plus much more.
application.yml
server:
servlet:
context-path: /your-path

Dropwizard - Resources on multiple ports

I have a Dropwizard(v 0.7.1) based Jersey REST service. Currently I use one application connector port (8810) and I have two resources (say "/path1","/path2").
I will be able to access these resources as http:\\localhost:8810\path1 and http:\\localhost:8810\path2 respectively. What am trying to achieve is have a separate port for each resource. (e.g http:\\localhost:8810\path1 and http:\\localhost:8820\path2). I tweaked the yaml file to have the below configuration and when I started the application both resources were available using both ports and am not sure how to configure these resources to use specific ports or is that even possible with Dropwizard?
server:
applicationConnectors:
-
type: http
port: 8810
-
type: http
port: 8820
Appreciate if someone can enlighten.
Thanks
your issue is that the DefaultServerFactory adds all applicationConntectors to the same Handler, see DefaultServerFactory#build:
#Override
public Server build(Environment environment) {
printBanner(environment.getName());
final ThreadPool threadPool = createThreadPool(environment.metrics());
final Server server = buildServer(environment.lifecycle(), threadPool);
LOGGER.info("Registering jersey handler with root path prefix: {}", applicationContextPath);
environment.getApplicationContext().setContextPath(applicationContextPath);
final Handler applicationHandler = createAppServlet(server,
environment.jersey(),
environment.getObjectMapper(),
environment.getValidator(),
environment.getApplicationContext(),
environment.getJerseyServletContainer(),
environment.metrics());
LOGGER.info("Registering admin handler with root path prefix: {}", adminContextPath);
environment.getAdminContext().setContextPath(adminContextPath);
final Handler adminHandler = createAdminServlet(server,
environment.getAdminContext(),
environment.metrics(),
environment.healthChecks());
final RoutingHandler routingHandler = buildRoutingHandler(environment.metrics(),
server,
applicationHandler,
adminHandler);
server.setHandler(addStatsHandler(addRequestLog(server, routingHandler, environment.getName())));
return server;
}
What you need to do is implement your own ServerFactory.
You can extend DefaultServerFactory and overwrite the build method to set up your connectors in the way you want them to be.
Presumably you'll want to add some more configuration that indicates what goes where, since in terms of your yaml it will not be possible to map a resource to a specific connector. How would dropwizard know about that.
For overwriting the behaviour for dropwizard (adding a new ServerFactory) you can see this post I wrote about adding logging: Dropwizard doesn't log custom loggers to file
It basically involves implementing the class and making it discoverable for dropwizard. After that all you need to do is to change the yaml file to point to the correct ServerFactory.
If you don't like that approach, you can overwrite the get/set method on the configuration to return your class. For this, your class MUST extend DefaultServerFactory, since otherwise the yaml mapping won't work anymore. You can overwrite the build method regardless though.
Update:
Looking at it in a bit more detail, you'll run into a second problem:
Your Environment only has one jersey environment that it can use.
You will need to configure a second jersey environment since currently by default each Handler will get the same Jersey config passed to it (the only one that exists). This is why it will be available for all of your http configurations. So in summary:
Create a new Environment that supports multiple jersey configurations
Create a server factory that knows what jersey config belongs to which Handler and instantiates the handlers in that form.
I believe those two steps would be required.
In terms of environment, you will have to create your own ServerCommand (that is the command that starts up dropwizard server).
Looking in EnvironmentCommand#run you can see where the Environment is created. This will be the only place you can overwrite the default Environment (as far as I know) which is what you need to do to support multiple jersey configs.
To be honest with you, looking at this, I do not believe that this is what the dropwizard guys had in mind.

Categories

Resources