Run Spring Boot server and HttpServer on single application? - java

I have init method which starts HttpServer with controller:
public void init() {
GatewayServer server = new GatewayServer("some_host", 8080);
server.registerController(WorkshopOrderEndpoint.class);
ControllerFactory.createController();
server.startServer();
}
This is the GatewayServer.class:
public class GatewayServer {
private static Logger logger = LogManager.getFormatterLogger(GatewayServer.class);
private final String serverHost;
private final String serverPort;
private URI address;
private ResourceConfig resourceConfig = null;
private com.sun.net.httpserver.HttpServer server;
public GatewayServer(final String host, final Integer port) {
serverHost = host;
serverPort = String.valueOf(port);
try {
logger.info("HTTP: Create Http-Server.");
resourceConfig = new ResourceConfig();
address = new URI(String.format("http://%s:%s/", serverHost, serverPort));
} catch (URISyntaxException ex) {
logger.error("HTTP: %s", ex.getMessage());
LoggingHelper.sendExceptionLog(ex, "STATUS_URI_ERROR", "URI Encoding error.");
} catch (ProcessingException ex) {
logger.error("HTTP: %s", ex.getMessage());
LoggingHelper.sendExceptionLog(ex, "STATUS_HTTP_ERROR", "HTTP-Server start error.");
}
}
public void registerController(Class<?> controller) {
if (resourceConfig != null) {
logger.info("HTTP: Register Controller: %s", controller.getName());
resourceConfig.register(controller);
}
}
public void startServer() {
server = JdkHttpServerFactory.createHttpServer(address, resourceConfig, false);
logger.info("HTTP: Start Http-Server. Adress: %s", address);
server.start();
}
public void stopServer(int delay) {
logger.info("HTTP: Stop Http-Server. Address: %s", address);
server.stop(delay);
}
}
This is pure java application and I want to start Spring Server in order to run Eureka Server by adding this code to the init() method:
SpringRestApplication springRestApplication = new SpringRestApplication();
springRestApplication.start();
Where SpringRestApplication.class is starting the Spring Boot server:
#SpringBootApplication
#EnableEurekaServer
public class SpringRestApplication {
public void start() {
SpringApplication.run(SpringRestApplication.class, new String[0]);
}
}
I would to run two servers on same host but different ports is it possible to connect Spring Boot Tomcat server with HttpServer?

You can run the two on different ports.
Eugene shows a couple of options to change the port of the Spring Boot application: https://www.baeldung.com/spring-boot-change-port
This is the most straight-forward:
public void start() {
SpringApplication app = new SpringApplication(SpringRestApplication.class);
app.setDefaultProperties(Collections
.singletonMap("server.port", "8083"));
app.run(args);
}

Related

how to automatically init an object after jetty setup?

My java application starts a jetty server container.
Is there any "after init" method that jetty can call after it's up
that will construct a specific BL object and call one of its methods?
This is my code to init jetty:
public static void main(String[] args) throws Exception {
SdkServiceConfig.s.initLog();
logger.error("testing log");
final int port = 8083;
...
webappContext.setExtractWAR(false);
handlers.addHandler(webappContext);
// Adding the handlers to the server.
jettyServer.setHandler(handlers);
try {
jettyServer.start();
jettyServer.join();
} catch (Exception ex) {
logger.error("failed to init jetty server", ex);
System.out.println(ex);
throw new RuntimeException(ex);
} finally {
jettyServer.destroy();
}
}
and then i call specific url to trigger my server state initialization.
Server.java
#Path("/waitRequests")
#GET
#Consumes(MediaType.APPLICATION_JSON + ";charset=utf-8")
#Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
public void waitRequests() throws Exception {
System.out.println("waitRequests");
PubSubFactory pubSubFactory = new PubSubFactory();
pubSubFactory.init(SdkServiceConfig.s.GCP_PROJECT_ID, new File(SdkServiceConfig.s.SDK_PUBSUB_CLIENT_SECRET));
I wish it would be something like:
#Path("/sdk-service")
public class SdkOperation {
private final org.apache.log4j.Logger logger = LoggingUtils.getLogger();
private final CofmanService cofmanService;
// private SdkRequestRepo sdkRequestRepo;
private CustomPublisher resultPublisher;
public SdkOperation() throws Exception {
this(new CofmanServiceNet(), null);
}
Server server = new Server();
server.waitRequests()

How to get active session/context/user in application of embedded jetty server?

I have a running jetty-server with basic authentification. Now i want to see in the application which users are logged in and have an active session. I want to save changes in a jpa-database by user, so i need to get the informationen in my JpaService-class to save the change by the user. My running server is
public class TestServer {
public static void main(String[] args) {
startServer();
}
public static void startServer() {
Server server = new Server(8899);
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");
context.setSecurityHandler(basicAuth());
server.setHandler(context);
ServletHolder jerseyServlet = context.addServlet(org.glassfish.jersey.servlet.ServletContainer.class, "/*");
jerseyServlet.setInitOrder(0);
jerseyServlet.setInitParameter("com.sun.jersey.api.json.POJOMappingFeature", "true");
jerseyServlet.setInitParameter("jersey.config.server.provider.classnames", JpaService.class.getCanonicalName());
try {
server.start();
server.join();
} catch (Exception e) {
e.printStackTrace();
} finally {
server.destroy();
}
}
private static final SecurityHandler basicAuth() {
HashLoginService l = new HashLoginService();
l.putUser("user1", Credential.getCredential("pass1"), new String[] {"user"});
l.putUser("user2", Credential.getCredential("pass2"), new String[] { "admin"});
l.setName("Private Server");
Constraint constraint = new Constraint();
constraint.setName(Constraint.__BASIC_AUTH);
constraint.setRoles(new String[] { "admin", "user" });
constraint.setAuthenticate(true);
ConstraintMapping cm = new ConstraintMapping();
cm.setConstraint(constraint);
cm.setPathSpec("/*");
ConstraintSecurityHandler csh = new ConstraintSecurityHandler();
csh.setAuthenticator(new BasicAuthenticator());
csh.setRealmName("NameOfRealm");
csh.addConstraintMapping(cm);
csh.setLoginService(l);
return csh;
}
}
So how can i "read" the relevant informations? I use jetty 9.2.3 and Get jetty realm credentials in application seems outdated.
I tried to add in a few different ways to add the following, but nothing happens.
public class HttpSessionCollector implements HttpSessionListener {
private static final Map<String, HttpSession> sessions = new HashMap<String, HttpSession>();
#Override
public void sessionCreated(HttpSessionEvent event) {
HttpSession session = event.getSession();
sessions.put(session.getId(), session);
System.out.println("Created Session: "+event.getSession().getId());
System.out.println("Last Accessed: "+new Date(event.getSession().getLastAccessedTime()));
System.out.println("Attributes: "+ event.getSession().getAttributeNames());
}
#Override
public void sessionDestroyed(HttpSessionEvent event) {
sessions.remove(event.getSession().getId());
System.out.println("Destroyed Session: "+event.getSession().getId());
}
public static HttpSession find(String sessionId) {
return sessions.get(sessionId);
}
public static Map<String, HttpSession> getSessions() {
return sessions;
}
}
And when i add context.getSessionHandler().getState() it says "STOPPED". When i try .start() i get a NullPointerException. Maybe i did all wrong, but how is it done, so i get logged in users in my web-application?

How to remotely connect to multiple Glassfish 4+ instances simultaneously?

I am looking for a way to connect to multiple instances of Glassfish 4+ (JDK7-EE) simultaneously from a stand-alone Swing-based client (JDK7-SE). I successfully connect to a single instance by the following way:
That's the construction of the initial context:
private void connect(String address, String port) {
System.setProperty("java.naming.factory.initial", "com.sun.enterprise.naming.SerialInitContextFactory");
System.setProperty("com.sun.corba.ee.transport.ORBTCPTimeouts", "500:30000:20:"+Integer.MAX_VALUE);
System.setProperty("com.sun.corba.ee.transport.ORBTCPConnectTimeouts", "250:90000:100:"+Integer.MAX_VALUE);
System.setProperty("com.sun.corba.ee.transport.ORBWaitForResponseTimeout", "300000");
System.setProperty("java.security.auth.login.config", new File("login.conf").getAbsolutePath());
System.setProperty("org.omg.CORBA.ORBInitialHost", address);
System.setProperty("org.omg.CORBA.ORBInitialPort", port);
InitialContext context = new InitialContext();
}
Look-ups are done by JNDI using a remote interface:
context.lookup("java:global/LawSuiteEE/LawSuiteEE-ejb/GlobalsFacade!ch.lawsuite.control.GlobalsFacadeRemote");
I am using a custom JDBC realm that resides on the server and works fine. On the client side I pass the following login.conf to the initial context (see code above):
default {
com.sun.enterprise.security.auth.login.ClientPasswordLoginModule required debug=true;
};
Authentication is currently done by ProgrammaticLogin:
private void login(String username, char[] password) {
ProgrammaticLogin plogin = new ProgrammaticLogin();
plogin.login(username, password);
}
All of this is working fine! But during startup of the stand-alone client, I want to simultaneously connect to another EJB located on a different server.
Since ProgrammaticLogin has no direct relation to the initial context, I am not sure how to login to two different Glassfish servers simulteneously with different credentials (e.g. username/password) ? Someone any ideas ?
Further examination of the issue has uncovered, that the initial context can only be set once on a per JVM basis. So as soon as the ORB is set up by using System.setProperty(String, String) and the inital context object is instantiated, the design of the SerialInitContextFactory let's you no more change the selected endpoint(s).
Therefore I decide to connect within different JVMs to the different Glassfish servers. So finally I ended up with a separate project that manages the connections to the application server and communicates by RMI with the main project.
Currently my project consists of two different EE projects to which I want connect simultaneously, namely "LawSuiteEE" and "MgmtCenterEE". Here's the new project that handles the connections:
public static void main(String args[]) {
try {
if(args.length==2) {
if(args[1].equals("LawSuiteEE")) {
ILawSuiteEE stub = (ILawSuiteEE) UnicastRemoteObject.exportObject(new LawSuiteEE(), 0);
Registry registry = LocateRegistry.createRegistry(Integer.parseInt(args[0]));
registry.bind("LawSuiteEE", stub);
} else if(args[1].equals("MgmtCenterEE")) {
ILawSuiteEE stub = (ILawSuiteEE) UnicastRemoteObject.exportObject(new MgmtCenterEE(), 0);
Registry registry = LocateRegistry.createRegistry(Integer.parseInt(args[0]));
registry.bind("MgmtCenterEE", stub);
} else {
throw new NumberFormatException();
}
Logger.getLogger(RemoteContext.class.getName()).log(Level.INFO, "Remote context service is listening on port "+args[0]+" for incoming requests delegating to "+args[1]+".");
System.out.println("SIGNAL[READY]");
} else {
throw new NumberFormatException();
}
} catch (RemoteException ex) {
System.exit(1);
} catch (AlreadyBoundException ex) {
System.exit(2);
} catch(NumberFormatException ex) {
System.exit(3);
}
The interface ILawSuiteEE is used for RMI between this and the main project (the second interface IMgmtCenterEE is quite the same):
public interface ILawSuiteEE extends IConcurrentDatastore {
void connect(String address, String port) throws RemoteException;
void disconnect() throws RemoteException;
boolean login(String username, char[] password) throws RemoteException;
}
The appropriate implementation:
public class LawSuiteEE implements ILawSuiteEE {
private InitialContext context;
private ProgrammaticLogin login;
#Override
public void connect(String address, String port) throws RemoteException {
if(context==null) {
try {
System.setProperty("java.naming.factory.initial", "com.sun.enterprise.naming.SerialInitContextFactory");
System.setProperty("com.sun.corba.ee.transport.ORBTCPTimeouts", "500:30000:20:"+Integer.MAX_VALUE);
System.setProperty("com.sun.corba.ee.transport.ORBTCPConnectTimeouts", "250:90000:100:"+Integer.MAX_VALUE);
System.setProperty("com.sun.corba.ee.transport.ORBWaitForResponseTimeout", "300000");
System.setProperty("java.security.auth.login.config", new File("login.conf").getAbsolutePath());
System.setProperty("org.omg.CORBA.ORBInitialHost", address);
System.setProperty("org.omg.CORBA.ORBInitialPort", Integer.toString(port));
Logger.getLogger(RemoteDatastore.class.getName()).log(Level.INFO, "Try to connect to application server at "+System.getProperty("org.omg.CORBA.ORBInitialHost")+":"+System.getProperty("org.omg.CORBA.ORBInitialPort")+" ...");
context = new InitialContext();
} catch (NamingException ex) {
throw new RemoteException(ex.getMessage());
}
}
}
#Override
public void disconnect() throws RemoteException {
if(context!=null) {
try {
context.close();
Logger.getLogger(LawSuiteEE.class.getName()).log(Level.INFO, "Server context successfully closed.");
} catch (NamingException ex) {
Logger.getLogger(LawSuiteEE.class.getName()).log(Level.SEVERE, "Couldn't close server context.");
} finally {
this.facades.clear();
this.services.clear();
this.context=null;
}
}
}
#Override
public boolean login(String username, char[] password) throws RemoteException {
login = new ProgrammaticLogin();
return login.login(username, password);
}
}
In the main project I'm going to connect with the following:
public class LawSuiteDatastore extends Thread implements ILawSuiteEE {
private int port;
private int trials;
private boolean ready;
private Process process;
private ILawSuiteEE stub;
public LawSuiteDatastore() {
this.setName("K+: Remote-Datastore-Connection");
this.port = RemoteDatastoreService.cport++;
}
#Override
public void run() {
try {
Tools.log(RemoteDatastoreService.class, Level.INFO, "Starting RMI registry on port "+port+" for connecting to LawSuiteEE server instance.");
this.process = Runtime.getRuntime().exec(new String[] {"java", "-jar", Context.getWorkingDirectory()+"/lib/LawSuiteSX.jar", Integer.toString(port), "LawSuiteEE"});
//<editor-fold defaultstate="collapsed" desc="Redirect Error Stream">
new Thread(new Runnable() {
#Override
public void run() {
try{
try(DataInputStream in = new DataInputStream(process.getErrorStream())) {
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String line;
while((line=br.readLine())!=null) {
Tools.log(RemoteDatastoreService.class, Level.SEVERE, line);
}
}
} catch(Exception ex){
Tools.log(MgmtCenterDatastore.class, Level.SEVERE, ex.getMessage());
}
}
}).start();
//</editor-fold>
//<editor-fold defaultstate="collapsed" desc="Redirect Output Stream">
new Thread(new Runnable() {
#Override
public void run() {
try{
try(DataInputStream in = new DataInputStream(process.getInputStream())) {
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String line;
while((line=br.readLine())!=null) {
if(line.contains("SIGNAL[READY]")) { ready=true; }
Tools.log(RemoteDatastoreService.class, Level.INFO, line);
}
}
} catch(Exception ex){
Tools.log(MgmtCenterDatastore.class, Level.SEVERE, ex.getMessage());
}
}
}).start();
//</editor-fold>
// keep thread alive as long process is alive
if(process.waitFor()>0) {
// port was already bound
if(process.exitValue()==2) {
// try it with a different port and start over again
if(trials<3) {
process = null;
port = ++RemoteDatastoreService.cport;
trials++;
if(trials<3) {
start();
}
}
}
}
} catch (IOException ex) {
Tools.log(RemoteDatastoreService.class, Level.SEVERE, ex.getMessage());
} catch (InterruptedException ex) {
Tools.log(RemoteDatastoreService.class, Level.SEVERE, ex.getMessage());
}
}
public boolean isReady() {
return ready;
}
public int getTrials() {
return trials;
}
#Override
public void connect(RemoteDatastore datastore) throws RemoteException {
try {
Tools.log(RemoteDatastoreService.class, Level.INFO, "Locating RMI registry on port "+port+" for connecting to LawSuiteEE server instance.");
Registry registry = LocateRegistry.getRegistry(port);
stub = (ILawSuiteEE)registry.lookup("LawSuiteEE");
stub.connect(datastore);
} catch (NotBoundException ex) {
Logger.getLogger(RemoteDatastoreService.class.getName()).log(Level.SEVERE, null, ex);
}
}
#Override
public void disconnect() throws RemoteException {
if(process!=null && stub!=null) {
stub.disconnect();
process.destroy();
} else {
throw new RemoteException("Remote RMI server is not ready.");
}
}
#Override
public boolean login(String username, char[] password) throws RemoteException {
if(process!=null && stub!=null) {
return stub.login(username, password);
} else {
throw new RemoteException("Remote RMI server is not ready.");
}
}
}
How about using multiple threads, one for each server?
You can create a new thread for each connection you need, set up the InitialContext on each thread and connect with the ProgrammaticLogin with different credentials.
You can create your own "custom" thread by implementing the Runnable interface, and create a constructor for it that receives the credentials and/or InitialContext object.
Simple example:
public class MyThread implements Runnable {
private ProgrammaticLogin plogin;
private string user;
private char[] pass;
public MyThread(String username, char[] password,InitialContext context) {
this.user = username;
this.pass = password;
this.plogin = new ProgrammaticLogin();
//add more code here if needed
}
public void run() {
//insert code here when thread will run
}
}
and invoke it thus:
Runnable thread1 = new MyThread("my user1","my pass1",ContextObject1);
Runnable thread2 = new MyThread("my user2","my pass2",ContextObject2);
new Thread(thread1).start();
new Thread(thread2).start();
Of course this is a very simple example and it might not be suitable for your exact needs, but i think it is a good start for what you need. Since each Context and login credentials will run on a different thread they will have their own separate execution stack and you should not experience any concurrency issues (two threads accessing the same object).
However, you should have a good understanding of concurrency and threads otherwise you might run into different exceptions, that are a bit harder to debug due to using multiple threads.
Tom.

Asynchronous web service call in flex and java

How can i access to my Asynchronous web service in java? I made this thing in Flex Builder, and it`s pretty easy: just add web service throw "Data -> Connect to Web Service -> Enter the URL of wsdl" and add this lines:
private function result(e:ResultEvent):void
{
trace(e.result.toString());
}
private function fault(e:FaultEvent):void
{
trace(e.toString());
}
var d:DomainAuth = new DomainAuth();
d.AuthFuncName(login, pass);
d.addEventListener(ResultEvent.RESULT, result);
d.addEventListener(FaultEvent.FAULT, fault);
How can i do this in Java using eclipse EE?
Basically you need to do a SOAP web service client in java if I understand you correctly.
JAX-WS can be your friend. The following code is from here
package simpleclient;
import javax.xml.ws.WebServiceRef;
import helloservice.endpoint.HelloService;
import helloservice.endpoint.Hello;
public class HelloClient {
#WebServiceRef(wsdlLocation="http://localhost:8080/
helloservice/hello?wsdl")
static HelloService service;
public static void main(String[] args) {
try {
HelloClient client = new HelloClient();
client.doTest(args);
} catch(Exception e) {
e.printStackTrace();
}
}
public void doTest(String[] args) {
try {
System.out.println("Retrieving the port from
the following service: " + service);
Hello port = service.getHelloPort();
System.out.println("Invoking the sayHello operation
on the port.");
String name;
if (args.length > 0) {
name = args[0];
} else {
name = "No Name";
}
String response = port.sayHello(name);
System.out.println(response);
} catch(Exception e) {
e.printStackTrace();
}
}
}

Connection refused to host using RMI

First of here is the Exception that I'm getting: http://i.imgur.com/dE5Ou.png
Just to give little background I'm trying to write simple RMI program that connects two remote computers (Client/Server) using java's RMI. I have my Server program up and running but when I run my Client program I get the exception showed above in the link. Since I'm telling it to connect to 192.168.0.104 why is it saying "Connection refused to host: 127.0.1.1"???
Client
public class Client
{
public static void main(String[] args)
{
ServerInterface server;
Registry registry;
try
{
registry = LocateRegistry.getRegistry("192.168.0.104", (new Integer(1099)).intValue());
server = (ServerInterface)Naming.lookup("//192.168.0.104/ServerTest");
String serverString = server.getAndSetMessage("Connecting");
System.out.println("Reply from the server is: " + serverString);
}
catch(Exception e)
{
e.printStackTrace();
System.exit(1);
}
}
}
Server
public class Server extends UnicastRemoteObject implements ServerInterface
{
static String hostName = "192.168.0.104";
String name;
public Server(String name) throws RemoteException
{
super();
this.name = name;
}
public String getAndSetMessage(String message) throws RemoteException
{
return("My name is " + name + " Thanks for message " + message);
}
public static void main(String args[])
{
try
{
String objectname = "ServerTest";
Server theServer = new Server(objectname);
Naming.rebind("//"+hostName+"/"+objectname,theServer);
System.out.println("//"+hostName+"/"+objectname);
System.out.println("I am Registered");
}
catch (Exception ex)
{
System.out.println(ex);
System.exit(1);
}
}
}
You could try to add the following code to the server:
System.setProperty("java.rmi.server.hostname", "192.168.0.104");

Categories