Retrieve the Jetty instance in Dropwizard 2.0.0 - java

We have a project made in Dropwizard version 2.0.0-RC, where we use REST-endpoints. After some issues we decided to use gRPC instead of using REST. There is a couple of 3rd party libraries to connect gRPC to Dropwizard, but we believe they are a bit outdated and not useable. So we are thinking about implementing Armeria and their GRPC solution.
To implement this, I need the Jetty instance to attach the GRPC.
This is how I can solve it (Mix between GRPC and Armeria):
Server server = Server.builder()
.http(8080)
.service(GrpcService.builder()...build())
.serviceUnder("/", JettyService.forServer(jettyServer))
.build();
server.start().join();
So I need the jettyServer to be the instance of Jetty with the type of org.eclipse.jetty.server. The rest of the code is Armerias way of embedding Jetty. Link to embedding jetty.
How can I retrieve the instance of Jetty?

I was able to solve this by using Dropwizard lifecycles to get the server.
// variable server is of type org.eclipse.jetty.server.Server
environment.lifecycle().addServerLifecycleListener(new ServerLifecycleListener() {
#Override
public void serverStarted(Server server) {
// ....
}
});
With the instance, you can use Armeria to attach gRPC

I was able to use the links provided in the comments of the other answer and put this PR together in Armeria project for adding a dropwizard module.
https://github.com/line/armeria/pull/2236
It currently targets 1.3.x rather than 2.0, but once a stable release exists, it'll need upgraded
Edit: PR was accepted and merged

Related

Jetty and Dropwizard: KeyStores with multiple certificates are not supported on the base class org.eclipse.jetty.util.ssl.SslContextFactory

I am running into the follow error while upgrading my versions of Jetty for a Dropwizard project:
java.lang.IllegalStateException: KeyStores with multiple certificates are not supported on the base class org.eclipse.jetty.util.ssl.SslContextFactory. (Use org.eclipse.jetty.util.ssl.SslContextFactory$Server or org.eclipse.jetty.util.ssl.SslContextFactory$Client instead)
The tricky part is that I do not directly set up my SslContextFactory in code. Instead, Dropwizard sets it up behind the scenes at application startup, where it quickly runs into this issue and fails.
I see from the Dropwizard documentation that certain environment variables can be set on the Jetty server that it spins up, but I do not see documentation on how to modify specific classes.
If I add a jetty.xml file within $JETTY_HOME$/etc/config, will Dropwizard know how to pick this up?
I just need to understand how Dropwizard picks up settings on Jetty so I can use SslContextFactory.Server and resolve this error at startup.
Your version of Dropwizard is too old.
Dropwizard properly uses the SslContextFactory.Server where appropriate.

How to integrate GraphiQL with Spring-Boot?

My target is to build a GraphQL server on Spring with (1) GraphiQL IDE (2) dynamic GraphQL schema at run-time. My GraphQL engine is GraphQL-Java.
In my first try, I use graphql-java-spring-boot-starter-webmvc and graphiql-spring-boot-starter.
Both the GraphQL server and the GraphiQL work well.
However, under the graphql-java-spring-boot-starter-webmvc framework, a #Bean of GraphQL class is needed. In this bean, the schema is loaded when the server starts so it could not been updated.
In my second try, I don't use graphql-java-spring-boot-starter-webmvc. Instead, I choose spring-boot-starter-web to start the web server and define my own RestController. This is easy to update the GraphQL instance. But I don't find a way to integrate with GraphiQL. I googled GraphiQL+Spring but all solutions are with graphql-java-spring-boot-starter.
Appreciate if anyone could provide me an idea on either approach.
It can be enabled in properties:
graphql.graphiql.enabled=true
It is accessible via the root url +/graphiql example http://localhost:8080/graphiql
You can find a good detailed example here : https://github.com/NoorKrichen/GraphQL-Spring-Boot-Example
Do you have a sample of your setup in git?
It sounds like some configuration problem. But naturally using graphql-java-spring-boot-starter-webmvc all your *.graphql schemas should be picked up in the configured schema resource path. check if you have the path set in your application.yml or if your schema is in the configured path if its already set or by default.
On your second point: "I googled GraphiQL+Spring but all solutions are with graphql-java-spring-boot-starter."
This makes sense for quick guides and demos as using Springboot the plumbing is somehow hidden away from you so that you can focus on the technology at hand being demo'd in this case GraphQl.
On GraphiQL:
Sounds like you are intending to have this embedded with your application, you may not want to do so in production. Depending on your use case there are many other alternatives that are standalone and gives you all the functionality of GraphiQL plus more e.g Altair Graphql Client and Insomnia to name a few.

Amazon Kinesis + Integration Tests

I'm currently working on a series of web-services which we need to integrate with Kinesis - the implementation has been done, however we have a series of integration tests (our web-services are all using Spring Boot so we use the #WebIntegrationTest annotation on our test classes to start up a local instance of the server and then call our resources with a TestRestTemplate) which are currently trying and failing to connect to the real Kinesis.
Although in ordinary unit tests it's not a problem to mock out calls to the methods within the Kinesis library, we can't really do this in the integration tests as the whole application stack is wired up with Spring. For a few other things (such as OAuth2 and calls to our other web-services) we've been able to use WireMock to mock out the actual endpoints - what I'd really like to do is use WireMock in this fashion to mock out the call to the AmazonKinesisClient but I can't find any advice on how to do this.
Alternatively I have seen that some AWS components have test libraries written by third parties which allow you to run a local version of it (e.g.: DynamoDbLocal) but can't find such a solution for Kinesis.
Is anyone able to give me some advice on how to run integration tests with Kinesis?
It might already be too late to give the solution but I will add what my team has done to replicate AWS resources locally as we use a lot of Kinesis, DynamoDb, S3 and cloudWatch.
We have created wrappers around Localstack -> https://github.com/localstack/localstack that allow us to spin up local instances of the necessary services as docker containers using docker-compose.
A typical docker-compose.yml file for us looks like:
version: '2'
services:
localstack:
image: "localstack/localstack"
environment:
- SERVICES=kinesis,dynamodb,cloudwatch
ports:
- "4568"
- "4569"
- "4582"
Then during the setup phase for the integration-tests, our wrapper fires up docker-compose up and runs the tests against the local infrastructure.
Later during tear-down, the wrapper kills the containers.
I ran into the same issue and the only mock implementation I found so far was a nodejs one: https://github.com/mhart/kinesalite
It does the trick - I managed to run my Java Kinesis client against it, just had to set the endpoint on the kinesis.properties:
kinesisEndpoint=http://localhost:4567
The downside is that it is not trivial to use it during build time tests - need to figure a way to start the mock kinesis before the test (using a maven plugin or something), didn't get to it yet..
Just a small addition to the existing answers. BTW, they are great, you should really use tools like localstack to start fake AWS services before the test during the test phase.
If you're using JUnit 5 in your tests, your life could be even simpler with JUnit 5 extensions for AWS, a few JUnit 5 extensions that could be useful for testing AWS-related code. These extensions can be used to inject clients for AWS service mocks provided by tools like localstack. Both AWS Java SDK v 2.x and v 1.x are supported:
#ExtendWith(DynamoDB.class)
class AmazonDynamoDBInjectionTest {
#AWSClient(
endpoint = Endpoint.class
)
private AmazonDynamoDB client;
#Test
void test() throws Exception {
Assertions.assertNotNull(client);
Assertions.assertEquals(
Collections.singletonList("table"),
client.listTables().getTableNames().stream().sorted().collect(Collectors.toList())
);
}
}
Here, client will be just injected in your test class and configured according to the Endpoint configuration class.

Manually setting up Spring WebSocket STOMP support

I'm trying to set up a STOMP WS endpoint using spring-websocket and spring-messaging. I am trying to do this manually: no application context is involved at all, and certainly no dispatcher. My goal is to wire up the appropriate Spring components in code inside a ServletContextListener, then register the wired up components directly with the javax.websocket.server.ServerContainer in my JSR 356 compatible container (Tomcat 7). At first, I would like to get this working with the "simple" broker built into spring-messaging; secondly, I would like to implement my own "broker" to directly integrate with an in-process ActiveMQ using the VM transport. This would be in contrast to the STOMP relay which spring-messaging also provides.
The Spring documentation states (http://docs.spring.io/spring/docs/current/spring-framework-reference/html/websocket.html):
"...Spring’s WebSocket support does not depend on Spring MVC. It is relatively simple to integrate a WebSocketHandler into other HTTP serving environments with the help of WebSocketHttpRequestHandler."
However, I am not finding it to be simple. Essentially, I started with:
public void contextInitialized(ServletContextEvent sce) {
ServerContainer websocketContainer = (ServerContainer) sce.getServletContext().getAttribute("javax.websocket.server.ServerContainer");
???
websocketContainer.addEndpoint(???);
}
And ended up with an incoherent mess of assorted spring-websocket and spring-messaging constructor invocations which do not compile and are certainly not worth reproducing here.
I realize this is a bit vague, this is because I'm a bit lost! Has anyone done something like this, or has some general guidance to contribute?
Did you try sample application - tests for the stock portfolio. (This link is at the very end of the spring documentation link).
It says
Demonstrates 3 approaches to testing a Spring STOMP over WebSocket application:
Server-side controller tests that load the actual Spring configuration (context sub-package)
Server-side controller tests that test one controller at a time without loading any Spring configuration (standalone sub-package)
End-to-end, full integration tests using an embedded Tomcat and a simple STOMP Java client (tomcat sub-package)
See the Javadoc of the respective tests for more details.
Second option is probably what you need.

Servlets + JAX-WS

I'm trying to expose a web service method via JAX-WS annotations. Many examples I've seen reference the EndPoint.publish() method to quickly stand up the service in a standalone app (ex from Java Web Services: Up and Running, 1st Edition):
public class TimeServerPublisher {
public static void main(String[ ] args) {
// 1st argument is the publication URL
// 2nd argument is an SIB instance
Endpoint.publish("http://127.0.0.1:9876/ts", new TimeServerImpl());
}
}
One thing that I'm missing is how to accomplish essentially the same thing but in an existing app. Would I make a servlet to handle this? What is the proper way to publish this service in an existing WAR file?
In a container you don't have to publish like this. The container will do the publish. If you plan to use it in JBoss server try JBossWS otherwise for Tomcat or any other server Axis2 may be the better choice.
Read more from the following links.
http://jbossws.jboss.org/mediawiki/index.php?title=JBossWS
http://ws.apache.org/axis2/
This depends on what WS stack you are using.
If you are using Java 6 then that includes the JAX-WS reference implementation, then you can consult the documentation about JAX-WS RI WAR contents.
As #Jerrish and #andri coments, there are different aproaches and solutions, depending on your concerns.
The idea behind is that you don't need to set the configuration (port, etc) when will be published your web service. The best approach could be to set this via configuration files (XML, properties, etc) or using #Annotations.
For example, if you're accustomed to use frameworks like Guice or Spring, you know that is possible/recommended to start the context of your application publishing or initializing some objects, factories, datasources, etc and publishing webservices is another task that can be done in this time, because will be available when you will start your application, isn't?.
By the way, I've good experiences with CXF and another solution could be Spring Web Services another powerful solution for creating web services.

Categories

Resources