Dropwizard config (yml) behaves strangely - java

I'm working with the Dropwizard sample project from the tutorial and faced the following strange issue:
With the following server config
server:
type: default
applicationConnectors:
- type: http
port: 8080
My resource returns the correct response.
When I change it to:
server:
type: simple
I see (from Jetty's logs) that it was correctly registered and loaded but doesn't work - if I try the same path I see 404 in browser and
GET /wizard-resource/rs 200
in the logs. I've tried to find the difference between simple and default in yaml configs but Google didn't shed much light on the topic.
So, here are two questions:
Why with simple connector do I get a 200 in logs but 404 in browser?
What is the use of simple connector and when it is better than default?

According to Dropwizard Javadocs:
Simple Server
A single-connector implementation of {#link ServerFactory}, suitable
for PaaS deployments (e.g., Heroku) where applications are limited to
a single, runtime-defined port. A startup script can override the
port via {#code -Ddw.server.connector.port=$PORT}.
Default Server
The default implementation of {#link ServerFactory}, which allows for
multiple sets of application and admin connectors, all running on
separate ports. Admin connectors use a separate thread pool to keep
the control and data planes separate(ish).
It's also mentioned (though not thoroughly) in the Configuration Reference documentation.
Not sure why it's logged as 200 while it's 404, it could be a bug; but the reason you're getting 404 could be because the default applicationContextPath config in simple server is /application. So if you try
GET /application/wizard-resource/rs
it should work.

Related

How to specify gRPC server address target on client side when the service is on format <my-service:port>

We are using grpc spring boot starter on our Java application service in order to establish a connection to another 'server' service, so I define in the application.properties the following address:
grpc.client.name.address=static://service-name:port
When tried to connect it I got the following error message:
StatusRuntimeException: UNAVAILABLE: io exception
So I know for sure I have a connectivity issue. On the documentation it says regarding the static scheme:
A simple static list of IPs (both v4 and v6), that can be use connect to the server
So I guess this is not what I need to use. It seems the best option in my case is using the discovery scheme, but it doesn't contains any port...
What is the right scheme configuration I need to use to set the server address?
Wanted to share the resolution for this very annoying issue for those who will encounter the same problem in the future like I did.
So first, the scheme needs to be set indeed of dns type, like the following: grpc.client._name_.address=dns:///<service-name>:26502
but this alone is not enough. (at least in my case) The server was configured to run in PLAINTEXT, while my client, by default, was configured to run with TLS mode, so it must be set with grpc.client.__name__.negotiationType=PLAINTEXT property.
See the following documentation for further information
It caused by gRPC can't resolve addresss service-name:port;
If you use static, the value must be ip:port; The service-name need to be resolved as ip address;
If you are using register center like consul or eureka etc., you should use discovery:///service-name without specify port.
If you didn't use register center, only end to end with server, replace service-name as a ip like 127.0.0.1 which belong to server;
Or modify host config for parse service-name like below, the file on Linux is /etc/hosts
127.0.0.1 service-name

Quarkus / Restclient with proxy configuration

I am using quarkus 1.10.5.Final and need to call web service with web proxy.
Currently my code using microprofile client proxy and put below configuration in application.properties
client/mp-rest/url=https://remote.com
client/mp-rest/scope=javax.inject.Dependent
client/mp-rest/trustStore=classpath:/META-INF/resources/cacerts
client/mp-rest/connectTimeout=5000
client/mp-rest/readTimeout=5000
client/mp-rest/followRedirects=true
client/mp-rest/proxyAddress=http://proxy:8080
but still resulting RESTEASY004655: Unable to invoke request: java.net.UnknownHostException: No such host is known
I tried to use -Dhttp.proxyHost and -Dhttp.proxyPort to test the proxy and it was success.
the problem is I can't use -Dparams since it will break other service calls.
this link where I got config for mp-rest/proxyAddress
https://download.eclipse.org/microprofile/microprofile-rest-client-2.0-RC2/microprofile-rest-client-2.0-RC2.html
but its not mentioned in https://docs.jboss.org/resteasy/docs/4.1.1.Final/userguide/html/MicroProfile_Rest_Client.html
please let me know if I am looking on wrong thing.
May 2021 update
Quarkus 2.0 supports MicroProfile Rest Client 2.0. With it you can use the configuration you mention, namely
# A string value in the form of <proxyHost>:<proxyPort> that specifies the
# HTTP proxy server hostname (or IP address) and port for requests of
# this client to use.
client/mp-rest/proxyAddress=host:port
Or set it programmatically with
ProxiedClient client = RestClientBuilder.newBuilder()
.baseUri(someUri)
.proxyAddress("myproxy.mycompany.com", 8080)
.build(ProxiedClient.class);
Original answer
You should be able to set proxy for your Quarkus Rest client with the following properties:
org.jboss.resteasy.jaxrs.client.proxy.host
org.jboss.resteasy.jaxrs.client.proxy.port
org.jboss.resteasy.jaxrs.client.proxy.scheme
I just run into the same problem and found this issue.
Upgrade to MP Rest Client 2.0 #10520
MP-Rest-Client 2.0 is not available in quarkus 1.10.5.

What causes the DestinationAccessException "Failed to get on-premise proxy headers"?

We are trying to call OData and REST endpoints in an S/4HANA On Premise system from our SAP Cloud Platform Java app. However, our attempts to use the SAP CloudSDK to get an HTTP client for the corresponding destination
Destination destination = DestinationAccessor.getDestination(destinationName);
HttpClient client = HttpClientAccessor.getHttpClient(destination.asHttp());
fails with the exception
com.sap.cloud.sdk.cloudplatform.connectivity.exception.DestinationAccessException:
Failed to get on-premise proxy headers.
We are at a loss at what's causing it. The text also isn't very specific about what is missing. "Proxy headers", okay. But what are they, and where do I maintain them, and for what? None of the blogs 1 2 we've referred to mentions anything of the kind.
Our Destination looks as follows:
Name: ABC
URL: http://abc:445/sap/opu/odata/sap/SOME_ODATA_SRV
Proxy Type: OnPremise
User: MYUSER
Password: ******
sap-client: 123
It points to a Cloud Connector that exposes a back-end system:
Host: abc:445
Protocol: HTTP
Back-End Type: ABAP System
Connection check is successful.
I finally found the piece of code that throws the exception in method getHeadersForOnPremiseSystem of class ConnectivityService in library cloudplatform-connectivity-scp-cf, which apparently fails to resolve headers that are related to the XSUAA service using a PrincipalPropagationStrategy. That makes me wonder: as far as I know, principal propagation is for frontend access to Fiori apps. But we only want to call an OData endpoint, hence neither need nor want to configure that.
What are we missing or doing wrong?
Florian, you'll have to decorate your destination with DefaultErpHttpDestination like
HttpClient client = HttpClientAccessor.getHttpClient(destination.asHttp().decorate(DefaultErpHttpDestination::new));
Thanks for good feedback, we'll be updating our documentation on destination handling and other OData related topics here

http.nonProxyHosts ignored on localhost only

I run a proxy on localhost:2080 for debugging purposes. I can see trafic going through my proxy using either:
curl http://localhost:8888/stuff --proxy localhost:2080
curl http://some.server.com:8888/stuff --proxy localhost:2080
Using a Spring application, or a bare bones HttpURLConnectionExample Java application, I see requests go through the proxy when I call some.server.com, but never on localhost, even though I set http.nonProxyHosts to a random value (to avoid the default of localhost).
I made sure my JVM arguments were taken into accounts by adding the following code:
System.out.println("java.version="+props.getProperty("java.version"));
System.out.println("http.proxyHost="+props.getProperty("http.proxyHost"));
System.out.println("http.proxyPort="+props.getProperty("http.proxyPort"));
System.out.println("http.nonProxyHosts="+props.getProperty("http.nonProxyHosts"));
That produces the following output:
java.version=1.8.0_131
http.proxyHost=localhost
http.proxyPort=2080
http.nonProxyHosts=dummy.snafu.com
https.proxyHost=localhost
https.proxyPort=2080
https.nonProxyHost=dummy.snafu.com
Testing 1 - Send Http GET request
Sending 'GET' request to URL : http://localhost:8888/stuff
Response Code : 200
hello
Why are HTTP requests to localhost not going through my proxy when run with the following JVM arguments?
-Dhttp.proxyHost=localhost
-Dhttp.proxyPort=2080
-Dhttp.nonProxyHosts=dummy.snafu.com
This is a limitation of DefaultProxySelector, It always appends local Uris(localhost, 127.*, etc) to whatever you configure as nonProxyHosts, essentially bypassing proxy for all local Uris(localhost|127. *|[::1]|0.0.0.0|[::0]). Fortunately, there is a workaround by creating your own proxy selector and registering it as default.

ERROR: Running application failed - Spring boot + Boxfuse/AWS

I am trying to run my Spring boot application on AWS using boxfuse.
I have followed the following tutorial from Spring (section 54.4) and the Get Started from Boxfuse aswell.
When i run the following command
boxfuse run target\digigram-0.1.0.jar -env=prod
i get the following lines
Waiting for AWS to boot Instance i-74fe7fc8 and Payload to start at http://52.28.94.159:8080/ ...
WARNING: Healthcheck (http://52.28.94.159:8080/) returned 404 instead of 200. Retrying for the next 120 seconds ...
Terminating instance i-74fe7fc8 ...
And it ends with
Destroying Security Group sg-0ed6f667 ...
ERROR: Deployment of pantera160/digigram:0.0.0.1453900589995 failed in prod:Payload of Instance i-74fe7fc8 came up at http://52.28.94.159:8080/
with HTTP 404 (expected 200) => ensure your application responds with an HTTP 200 at http://52.28.94.159:8080/ or adjust the healthcheck configuration (healthcheck.path, healthcheck.timeout, ...) to fit your application
ERROR: Running pantera160/digigram:0.0.0.1453900589995 failed!
I don't understand where the problem lies. Do I have to change something in AWS or in my application or...
Any help would be greatly appreciated.
NOTE:
I am running on a free plan for AWS, might this be the problem?
Boxfuse ensures that a correct version of your app stays up and running and does not get replaced by a bad one. Only when a new version does pass Boxfuse's health check, does Boxfuse reassign it the application's Elastic IP. Once that is complete Boxfuse terminates the instance of the old version.
To verify that a new version of your app comes up correctly Boxfuse expects the new version's instance's healthcheck path to return HTTP 200.
The default healthcheck path for a regular Spring Boot application without the actuator is /. Your app currently answers 404 there instead of 200.
You have a number of options to fix this:
Add a controller to your app mapped to / that returns HTTP 200 when your app comes up correctly.
Change Boxfuse's healthcheck.path to a different path that does indeed answer HTTP 200 when your app comes up correctly.
Disable Boxfuse's health checks by setting healthcheck to false (not recommended as this effectively prevents Boxfuse from checking whether your application came up correctly)
Pick either one of these options and your app will come up correctly as you would expect.

Categories