Port from Jetty Server instance - jetty

I am writing a service discovery application which will register web applications on a zookeeper node. One of the attribute is the port number on which service is available. In code I got the handle of jetty server instance but how can I find the port number from a Jetty Server instance ?

Walk the connectors, and ask them for their registered host names (so you know what network interfaces they are listening on) and local ports (that they are bound to).
Here's a template you can start with.
for (Connector connector : server.getConnectors())
{
if (connector instanceof NetworkConnector)
{
// we have a network capable connector
NetworkConnector networkConnector = (NetworkConnector) connector;
// What interface?
String interfaceName = networkConnector.getHost();
// What local port is it bound to?
int localPort = networkConnector.getLocalPort();
// What is the declared protocol default for this connector?
String defaultProtocol = networkConnector.getDefaultConnectionFactory().getProtocol();
// What other features does this connector handle?
for (ConnectionFactory connectionFactory : networkConnector.getConnectionFactories())
{
// List of protocols handled by this specific connection factory for this specific connector
connectionFactory.getProtocols();
if (connectionFactory instanceof SslConnectionFactory)
{
// this can handle TLS/SSL based connections
}
if (connectionFactory instanceof HttpConnectionFactory)
{
// this can handle http protocols
// get the http specific configuration
HttpConfiguration httpConfig = ((HttpConnectionFactory) connectionFactory).getHttpConfiguration();
// what port is recognized as secure
httpConfig.getSecurePort();
// what scheme is recognized as secure
httpConfig.getSecureScheme();
}
if (connectionFactory instanceof HTTP2ServerConnectionFactory)
{
// can handle encrypted http/2 protocols (and alpn features)
}
if (connectionFactory instanceof HTTP2CServerConnectionFactory)
{
// this can handle http/2's special clear-text "h2c" protocol (no alpn features)
}
}
}
}

Related

Example of embedded Jetty and using Micrometer for stats (without Spring)

I am new to using Micrometer as a metrics/stats producer and I am having a hard time in getting it configured correctly with my Jersey/Embedded Jetty server. I would like to get Jetty statistics added.
I already have the servlet producing stats for the JVM in a Prometheus format.
Does anyone know of a good working example on how to configure it?
I am not using SpringBoot.
The best way is to look at the Spring Boot code. For example it binds the jetty connections
JettyConnectionMetrics.addToAllConnectors(server, this.meterRegistry, this.tags);
And it uses an ApplicationStartedEvent to find the server reference.
private Server findServer(ApplicationContext applicationContext) {
if (applicationContext instanceof WebServerApplicationContext) {
WebServer webServer = ((WebServerApplicationContext) applicationContext).getWebServer();
if (webServer instanceof JettyWebServer) {
return ((JettyWebServer) webServer).getServer();
}
}
return null;
}
There are other classes that record the thread usage and SSL handshake metrics.

Jetty http/2 add ServerSessionListener to server

i am using embedded Jetty to implement HTTP/2. At the moment i am trying to add a ServerSessionListener (from: org.eclipse.jetty.http2.api.Session.Listener.Adapter) to my Server.
i tried to add it to the Context and Server via: addEventListener with no success.
Maybe someone can give me a hint about what i am doing wrong..
I want to add a session Listener to my HTTP2 Connection to track the connected Sessions (Clients) and their connection duration.
Regards!
You can add an implementation of Connection.Listener as a bean to the connector itself, for example:
http2Connector.addBean(new Connection.Listener()
{
public void onOpened(Connection connection) { ... }
public void onClosed(Connection connection) { ... }
});
Alternatively you can add the Connection.Listener as a bean to the ConnectionFactory.
In both cases, every time a connection is created, the listener is added to the connection and will be invoked when the connection opens and when it closes.
You can use Jetty's ConnectorStatistics class that already gathers a number of statistics about connections and already implements Connection.Listener.

gRPC in CPP providing TLS support

Any examples of gRPC server using TLS in CPP??
I am trying to build a gRPC application. The server should provide TLS support if client wants to connect over TLS instead of TCP.
This is my server
void RunServer() {
std::string server_address("0.0.0.0:50051");
GreeterServiceImpl service;
ServerBuilder builder;
std::shared_ptr<ServerCredentials> creds;
if(enable_ssl)
{
grpc::SslServerCredentialsOptions::PemKeyCertPair pkcp ={"a","b"};
grpc::SslServerCredentialsOptions ssl_opts;
ssl_opts.pem_root_certs="";
ssl_opts.pem_key_cert_pairs.push_back(pkcp);
creds = grpc::SslServerCredentials(ssl_opts);
}
else
creds=grpc::InsecureServerCredentials();
// Listen on the given address without any authentication mechanism.
builder.AddListeningPort(server_address, creds);
// Register "service" as the instance through which we'll communicate with
// clients. In this case it corresponds to an *synchronous* service.
builder.RegisterService(&service);
// Finally assemble the server.
std::unique_ptr<Server> server(builder.BuildAndStart());
Error:
undefined reference to grpc::SslServerCredetials(grpc::ssl_opts)
I have included all the necessary files..
You code looks right. If you are adapting from examples/cpp/helloworld, you need to change -lgrpc++_unsecure to -lgrpc++ in the Makefile.
For the benefits of others, an example of using the tls/ssl code can be found at https://github.com/grpc/grpc/blob/master/test/cpp/interop/server_helper.cc#L50

CXF Bus for a client within a web service - memory leak

I have a Jax-WS service that needs to call out to another JAX-WS service with a CXF client. Because this client requires additional WS-* features, such as WS-Trust, I create a new CXF bus.
private void startupBus()
{
// if the bus is already active, shut it down to pick up any endpoint changes
if (bus != null) {
bus.shutdown(false);
}
bus = BusFactory.newInstance().createBus();
// Add logging interceptors to log messages to and from the services it calls
...
inBusLog.setPrettyLogging(true);
outBusLog.setPrettyLogging(true);
bus.getInInterceptors().add(inBusLog);
bus.getOutInterceptors().add(outBusLog);
bus.getInFaultInterceptors().add(inBusLog);
bus.getOutFaultInterceptors().add(outBusLog);
BusFactory.setThreadDefaultBus(bus);
...//create service proxy with this bus, setup STS client parameters, etc
}
Both my bus and my service proxy are static instances, and because I want to modify my parameters externally, this method re-runs once per day.
I'm seeing a memory leak, however, when this service stays up and running for a few days. Its relatively slow, so I cannot pinpoint if its something to do with my bus/proxy rotation logic, or if its elsewhere.
Is there any additional cleanup that needs to be done on the proxy( such as a java.io.Closable.close? ) or am I incorrectly configuring/managing my CXF bus instance?
Maybe it will be useful for the future
https://docs.jboss.org/author/display/JBWS/Apache+CXF+integration#ApacheCXFintegration-BusselectionstrategiesforJAXWSclients
try {
Service service = Service.create(wsdlURL, serviceQName);
MyEndpoint port = service.getPort(MyEndpoint.class);
//...
} finally {
BusFactory.setThreadDefaultBus(null);
// OR (if you don't need the bus and the client anymore)
Bus bus = BusFactory.getThreadDefaultBus(false);
bus.shutdown(true);
}

Obtaining public IP address rather than localhost (Boost Asio)

I have the following connection set up, this works correctly. This is part of a larger piece of code which listens (at a free port), for incoming messages. What I am trying to do is publish the uri so that other clients can connect to this. However I cannot figure out a way for the endpoint.address() to appear as the actual IP address on the interface being used rather than "localhost". Any ideas?
tcp::resolver::query query(address, "");
tcp:: endpoint endpoint = *resolver.resolve(query);
acc.open(endp.protocol());
acc.set_option(reuse_address(true));
acc.bind(endp);
acc.listen();
tcp::endpoint endpoint = acc.local_endpoint() ;
string uri = "tcp://" + endpoint.address().to_string() + ":" + lexical_cast<string>(endpoint.port()) ;
Boost ASIO has no way to enum all the interfaces of your computer. resolver query your DNS for your IP, witch is not the same as it can return whatever you have configured in it (even inacurrate information can be retrieved).
If you want to bind to the default interface. you don't need to make a resolve.
Just create the socket with the following endpoint :
boost::asio::ip::tcp::endpoint endpoint =
boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(),port);