Restlet - how to expose a resource with both HTTP/HTTPS? - java

Using restlet 2.3.1. I've a resource exposed via HTTP. Is it possible to expose it via HTTPS as well? The following snippet show how my server looks like today:
final Router router = new Router();
Filter filter = new Filter(){};
filter.setNext( DaemonsResource.class );
router.attach( "daemons/{p1}", filter );
Application myApp = new Application()
{
#Override
public org.restlet.Restlet createInboundRoot()
{
router.setContext(getContext());
return router;
};
};
Component component = new Component();
component.getDefaultHost().attach( "/", myApp );
new Server( Protocol.HTTP, port, component ).start();
I already got the crt from the CA, and built the keystore upon it.
Thanks!

Try something like :
Component component = new Component();
Server server = component.getServers().add(Protocol.HTTPS, 8082);
component.getDefaultHost().attach( "/", myApp );
component.start();
See restlet tutorials
To set your keystore, etc.,
Series<Parameter> parameters = server.getContext().getParameters();
parameters.add("keystorePath","add_keystore_file_path_here"));
parameters.add("keystorePassword", "mypassword");
parameters.add("keyPassword", "mypassword");
parameters.add("keystoreType", "PKCS12");
// Start the component.
component.start();
see restlet mailing list This message is a bit outdated but the parameters should still be the same

Related

How to configure the netty-SocketIO server so that it is accessible from all remote java clients in jelastic

I am developing a Spring-Boot project which also includes a socketIO server based on netty-socket Io. And therefore two clients: a web client and an android client!
all of them work wonderfully locally! But when I deploy online server in Jelastic only the web client which accesses netty-SocketIO server, but android client fails to connect to netty-SocketIO server. someone could help me configure the netty-socketIO server to accept all requests from any address on port 8888
Server configuration
Configuration config = new Configuration();
//config.setHostname("sec.j.layershift.co.uk");
config.setHostname("0.0.0.0");
config.setPort(8888);
final SocketIOServer server = new SocketIOServer(config);
// Listen for client connections
server.addConnectListener(client -> {
System.out.println("************ Client: " + getIpByClient(client) + " Connected ************");
});
Web client configuration
#CrossOrigin("*")
#RestController
public class ClientLocation {
Socket socket =null;
EventBuilder eventBuilder =null;
Gson gs = new Gson();
//................................
socket = IO.socket("http://sec.j.layershift.co.uk:8888");
socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
#Override
public void call(Object... args) {
ChatObject co = new ChatObject("ADMIN", "");
String infUser = gs.toJson(co);
System.out.println("\n"+infUser);
JSONObject jb = new JSONObject();
try {
// jb.put("userName", co.getUserName());
// jb.put("message", co.getMessage());
jb = new JSONObject(infUser);
socket.emit("username", jb);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Configuration of the java or android client
private void clientIO(){
try {
socket = IO.socket("http://aug-sec.j.layershift.co.uk:8888");
socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {
Nb. the configuration of the java or android client is identical to that of the web because all use the Socket.IO v1.0.0. But only the web client works from the Jelastic host because it is in the same folder as the server and the java clients do not succeed, so everything works in localhost or in LAN
There are 2 possible solutions
You can use the public IP (the way suggested by #Ruslan)
Also, the Jelastic platform resolver supports the WebSocket proxying (if the "Upgrade: websocket" header is present). You can use the JELASTIC_EXPOSE variable to forward the requests from port 80 to 8888 (more info here https://docs.jelastic.com/container-ports/#ports-auto-redirect) inside your container and then just access the app by your environment domain and port 80

Set SSLSocketFactory to JAX-WS web service call on Weblogic 12c

I need to call an external web service endpoint through HTTPS, using an SSL certificate. The right way should be setting a custom SSLSocketFactory using the BindingProvider, but I'm not able to get it working. To get the connection working I have to set a default SSLSocketFactory:
public void secureStoreSignedOffPdf(String filename, byte[] signedOffPdf, URL endpoint, String applicationEnvironmentId) {
final SSLSocketFactory defaultSslSocketFactory = HttpsURLConnection.getDefaultSSLSocketFactory();
final SSLSocketFactory wsSslSocketFactory = SslHelper.buildWebServiceSslSocketFactory(applicationEnvironmentId);
// TODO Fix: this should work only setting the property with BindingProvider (see below)
HttpsURLConnection.setDefaultSSLSocketFactory(wsSslSocketFactory);
final StoragePortService storagePortService = new StoragePortService();
final StoragePort storagePort = storagePortService.getStoragePortSoap11();
final BindingProvider bindingProvider = (BindingProvider) storagePort;
bindingProvider.getRequestContext()
.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, endpoint.toString());
bindingProvider.getRequestContext()
.put("com.sun.xml.ws.transport.https.client.SSLSocketFactory", wsSslSocketFactory);
final StorageRequest storageRequest = new StorageRequest();
final Document document = new Document();
document.setContent(new DataHandler(new ByteArrayDataSource(signedOffPdf, PDF_CONTENT_TYPE)));
document.setName(filename);
storageRequest.setOverwrite(true);
storageRequest.setBaseDocument(document);
final StorageResponse storageResponse = storagePort.storage(storageRequest);
HttpsURLConnection.setDefaultSSLSocketFactory(defaultSslSocketFactory);
if (!storageResponse.getReturnCode()
.equalsIgnoreCase(RESPONSE_OK)) {
throw new IllegalStateException("Web service failed with error: "
+ storageResponse.getReturnCode()
+ " - "
+ storageResponse.getReturnMessage());
}
}
If I remove this line:
bindingProvider.getRequestContext().put("com.sun.xml.ws.transport.https.client.SSLSocketFactory", wsSslSocketFactory);
The code still works (because I'm using the HttpsURLConnection.setDefaultSSLSocketFactory method). But if in that line I put a wrong SSLSocketFactory, it fails, so it means that putting the factory attribute does something.
What I don't get is the call working without setting the default SSLSocketFactory:
HttpsURLConnection.setDefaultSSLSocketFactory(...)
FYI: I've already tried with:
bindingProvider.getRequestContext().put("com.sun.xml.internal.ws.transport.https.client.SSLSocketFactory", wsSslSocketFactory);
but it doesn't do anything.

T3 client with custom SSLSocketFactory

I have my T3 client code like this:
private InitialContext initContext() {
Properties p = new Properties();
p.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
p.put(Context.PROVIDER_URL, context.providerURL);
for (Map.Entry<String, String> entry : getEnvironmentProperties().entrySet()) {
p.put(entry.getKey(), entry.getValue());
}
InitialContext res = null;
try {
res = new InitialContext(p);
} catch (NamingException e) {
e.printStackTrace();
}
return res;
}
My t3 client deployed on Tomcat (uses wlthint3client-12.1.3.jar) and trying to lookup remote bean of external system which deployed on Weblogic.
However when I trying to perform new InitialContext(p) I receive SSLHandshake exception, because it gets standart SSLSocketFactory with standart SSLConext and standart java trust store.
My question - is there any way to give to InitialContext some property which will override SSLSocketFacory. My aim is to populate my cutom trust store to this t3 client.
Changing standart trust store like this
System.setProperty("javax.net.ssl.trustStore", "pathToTrustStore");
works fine, however in case if my t3 client is used to communicate with 2 different external systems, it might be a problem in doing so.
Is there some property that I can populate?
Properties p = new Properties();
p.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
**p.put("CUSTOM SSL SOCKET FACTORY, "MY CLASS");**
Problem was solved by adding few parameters on application side
export JAVA_OPTS ="$JAVA_OPTS -Djavax.net.ssl.trustStore=path/truststore.jks"
export JAVA_OPTS ="$JAVA_OPTS -Djavax.net.ssl.trustStorePassword=changeIT"

two contexts one server jetty

i have two jetty embedded servers,
localhost:9001/WebApp1 and localhost:9002/WebApp2,
as you can see they're on different ports.
I'd like them to share the same port during creation of server
is it possible? (BTW they are two separate jar files as well).
so can i do something like this instead
localhost:9001/WebApp1 and localhost:9001/WebApp2
or am I stuck with producing war files then having them
contained by a tomcat/glassfish server
during creation of server i usually see this
ContextHandler context = new ContextHandler();
context.setContextPath("/WebApp1");
context.setHandler(new WebApp1());
Server server = new Server(9001);
server.setHandler(context);
server.start();
server.join();
on second app i'd like to have something that looks like this
ContextHandler context = new ContextHandler();
context.setContextPath("/WebApp2");
context.setHandler(new WebApp2());
Server server = getExistingServer(9001);
server.addHandler(context);
i see that there is such method server.getHandlers(); which returns an array of handlers how do i add new handler to the existing list, or get the existing jetty server running at port 9001
Jetty is a standard servlet container and can of course handle different contexts.
See section Embedding Contexts in Chapter 24 of the Jetty documentation.
Here is the ManyContexts example (part of Jetty docs):
public class ManyContexts
{
public static void main( String[] args ) throws Exception
{
Server server = new Server(8080);
ContextHandler context = new ContextHandler("/");
context.setContextPath("/");
context.setHandler(new HelloHandler("Root Hello"));
ContextHandler contextFR = new ContextHandler("/fr");
contextFR.setHandler(new HelloHandler("Bonjoir"));
ContextHandler contextIT = new ContextHandler("/it");
contextIT.setHandler(new HelloHandler("Bongiorno"));
ContextHandler contextV = new ContextHandler("/");
contextV.setVirtualHosts(new String[] { "127.0.0.2" });
contextV.setHandler(new HelloHandler("Virtual Hello"));
ContextHandlerCollection contexts = new ContextHandlerCollection();
contexts.setHandlers(new Handler[] { context, contextFR, contextIT, contextV });
server.setHandler(contexts);
server.start();
server.join();
}
}

How to gracefully shutdown embeded jetty

I have an application runs on an embedded jetty server. Now i want to start/stop the server as a service.
I use a script to start the server.
java $JAVA_OPTS -DREQ_JAVA_VERSION=$JAVA_VERSION -jar myjetty.jar
Main Class
Server server = new Server();
SelectChannelConnector connector = new SelectChannelConnector();
connector.setPort(PORT);
server.addConnector(connector);
HandlerCollection handlers = new HandlerCollection();
NCSARequestLog requestLog = new NCSARequestLog();
requestLog.setFilename(home + "/logs/access_" + logFileDateFormat
+ ".log");
requestLog.setFilenameDateFormat(logFileDateFormat);
requestLog.setRetainDays(10);
requestLog.setAppend(true);
requestLog.setExtended(false);
requestLog.setLogCookies(false);
requestLog.setLogTimeZone(TimeZone.getDefault().getID());
RequestLogHandler requestLogHandler = new RequestLogHandler();
requestLogHandler.setRequestLog(requestLog);
handlers.addHandler(requestLogHandler);
server.setHandler(handlers);
server.start();
server.join();
This starts the server.Stopping and/or Restarting an embedded Jetty instance via web call can be used to stop server but,
How to stop the server from the script? and what changes should i make to shout down server in the main class.
Since Jetty 7.5.x you can use org.eclipse.jetty.server.handler.ShutdownHandler in your code:
Server server = new Server(8080);
HandlerList handlers = new HandlerList();
handlers.setHandlers(new Handler[]
{ someOtherHandler, new ShutdownHandler("secret_password", false, true) });
server.setHandler(handlers);
server.start();
... which will allow you to shut down your jetty by issuing the following http POST request:
curl -X POST http://localhost:8080/shutdown?token=secret_password
You can call setStopTimeout(long timeout) to shutdown Jetty in a relatively graceful way. A statisticsHandler must be configured when calling this method.
Referencing: Jetty Server.class setStopTimeout(long)
e.g.
YourServletHandler servletHandler = new YourServletHandler();
StatisticsHandler statsHandler = new StatisticsHandler();
statsHandler.setHandler(servletHandler);
Server server = new Server(80);
server.setHandler(statsHandler);
server.setStopTimeout(3000L);
//...
server.start();
//...
server.stop();
There is no predefined solution to shut-down the Jetty server. The only ordered way to shut-down the Jetty server is to call the method stop() on the running server instance. You must implement the way how this method is called yourself.
You could achieve this (for example) by...
implementing an RMI server thread and invoke the method from a RMI client
implementing a JMX MBean and from a client call a method on that MBean
implementing a custom handler like described in the link you have posted
If you only want to find a way which does not depend on additional tools like curl, than you could solve it for example like below (it's your own code with small modifications)
public class MyJetty {
public static void main(String[] args) throws Exception {
int PORT = 9103;
String home = System.getProperty("user.home");
String logFileDateFormat = "yyyy_MM_dd";
// execute a request to http://localhost:9103/stop
// instead of `curl -v http://localhost:9103/stop`
if (args.length == 1 && "stop".equalsIgnoreCase(args[0])) {
URL url = new URL("http", "localhost", PORT, "/stop");
try (InputStream in = url.openStream()) {
int r;
while ((r = in.read()) != -1) {
System.out.write(r);
}
return;
} catch (IOException ex) {
System.err.println("stop Jetty failed: " + ex.getMessage());
}
}
Server server = new Server();
SelectChannelConnector connector = new SelectChannelConnector();
connector.setPort(PORT);
server.addConnector(connector);
HandlerCollection handlers = new HandlerCollection();
NCSARequestLog requestLog = new NCSARequestLog();
requestLog.setFilename(home + "/logs/access_" + logFileDateFormat + ".log");
requestLog.setFilenameDateFormat(logFileDateFormat);
requestLog.setRetainDays(10);
requestLog.setAppend(true);
requestLog.setExtended(false);
requestLog.setLogCookies(false);
requestLog.setLogTimeZone(TimeZone.getDefault().getID());
RequestLogHandler requestLogHandler = new RequestLogHandler();
requestLogHandler.setRequestLog(requestLog);
handlers.addHandler(requestLogHandler);
// the class YourHandler is the one from your link
handlers.addHandler(new YourHandler(server));
server.setHandler(handlers);
server.start();
server.join();
}
}
start the server with java MyJetty
stop the server with java MyJetty stop
I don't know why (or if it is a bug) but in my case I had to set shutdownAtStart argument to false to get it working. If I set it as true the Server connector never starts, so it doesn't attend external requests like http://localhost:8888/shutdown?token=secret
new ShutdownHandler("secret", false, false);

Categories