jadex.extension.rs.publish.GrizzlyRestPublishService Maven / Gradle / Ivy
package jadex.extension.rs.publish;
import java.lang.reflect.Method;
import java.net.URI;
import java.util.HashMap;
import java.util.Map;
import jakarta.servlet.MultipartConfigElement;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jadex.commons.SAccess;
import org.glassfish.grizzly.http.server.ErrorPageGenerator;
import org.glassfish.grizzly.http.server.HttpHandler;
import org.glassfish.grizzly.http.server.HttpServer;
import org.glassfish.grizzly.http.server.NetworkListener;
import org.glassfish.grizzly.http.server.Request;
import org.glassfish.grizzly.http.server.Response;
import org.glassfish.grizzly.http.server.ServerConfiguration;
import org.glassfish.grizzly.http.server.util.MappingData;
import org.glassfish.grizzly.servlet.HttpServletRequestImpl;
import org.glassfish.grizzly.servlet.HttpServletResponseImpl;
import org.glassfish.grizzly.servlet.WebappContext;
import org.glassfish.grizzly.ssl.SSLContextConfigurator;
import org.glassfish.grizzly.ssl.SSLEngineConfigurator;
import jadex.bridge.modelinfo.UnparsedExpression;
import jadex.bridge.service.IService;
import jadex.bridge.service.IServiceIdentifier;
import jadex.bridge.service.PublishInfo;
import jadex.bridge.service.ServiceScope;
import jadex.bridge.service.annotation.Service;
import jadex.bridge.service.component.IRequiredServicesFeature;
import jadex.bridge.service.search.ServiceQuery;
import jadex.bridge.service.types.publish.IPublishService;
import jadex.commons.SUtil;
import jadex.commons.Tuple2;
import jadex.commons.collection.MultiCollection;
import jadex.commons.future.ExceptionDelegationResultListener;
import jadex.commons.future.Future;
import jadex.commons.future.IFuture;
import jadex.extension.rs.publish.AbstractRestPublishService.MappingInfo;
import jadex.javaparser.SJavaParser;
/**
* Publish service without Jersey directly using Grizly container.
*/
@Service
public class GrizzlyRestPublishService extends AbstractRestPublishService
{
// Hack constant for enabling multi-part :-(
private static final MultipartConfigElement MULTI_PART_CONFIG = new MultipartConfigElement(System.getProperty("java.io.tmpdir"));
/** The servers per service id. */
protected Map sidservers;
/** The servers per port. */
protected Map portservers;
/**
* Test if publishing a specific type is supported (e.g. web service).
* @param publishtype The type to test.
* @return True, if can be published.
*/
public IFuture isSupported(String publishtype)
{
return IPublishService.PUBLISH_RS.equals(publishtype) ? IFuture.TRUE : IFuture.FALSE;
}
/**
* Publish a service.
* @param cl The classloader.
* @param service The original service.
* @param pid The publish id (e.g. url or name).
*/
public IFuture publishService(final IServiceIdentifier serviceid, final PublishInfo info)
{
Future ret = new Future<>();
IFuture> fut = evaluateMapping(serviceid, info);
fut.addResultListener(new ExceptionDelegationResultListener, Void>(ret)
{
@Override
public void customResultAvailable(PathManager mappings)
{
try
{
final IService service = component.getFeature(IRequiredServicesFeature.class).searchService(new ServiceQuery<>((Class)null, ServiceScope.PLATFORM).setServiceIdentifier(serviceid)).get();
final URI uri = new URI(getCleanPublishId(info.getPublishId()));
HttpServer server = (HttpServer)getHttpServer(uri, info);
System.out.println("Adding http handler to server: "+uri.getPath());
HttpHandler handler = new HttpHandler()
{
public void service(Request request, Response response) throws Exception
{
// Hack to enable multi-part
// http://dev.eclipse.org/mhonarc/lists/jetty-users/msg03294.html
// if(request.getContentType() != null && request.getContentType().startsWith("multipart/form-data"))
// baseRequest.setAttribute(Request.__MULTIPART_CONFIG_ELEMENT, MULTI_PART_CONFIG);
HttpServletResponseImpl res = HttpServletResponseImpl.create();
HttpServletRequestImpl req = HttpServletRequestImpl.create();
req.initialize(request, res, new WebappContext(uri.getPath(), uri.getPath()));
res.initialize(response, req);
MappingData data = request.obtainMappingData();
String pi = request.getPathInfo();
if(pi==null)
{
String ctx = request.getContextPath();
String full = request.getRequestURL().toString();
if(ctx!=null && full!=null)
{
int start = full.indexOf(ctx)+ctx.length();
int end = full.indexOf("?");
if(start>0 && full.length()>start)
{
pi = full.substring(start, end>0? end: full.length());
}
}
if("/".equals(pi))
pi = null;
}
if(pi!=null)
{
req.setServletPath(data.wrapperPath.toString());
Method m = req.getClass().getDeclaredMethod("setPathInfo", new Class[]{String.class});
SAccess.setAccessible(m, true);
m.invoke(req, new Object[]{pi});
}
Method m = req.getClass().getDeclaredMethod("setContextPath", new Class[]{String.class});
SAccess.setAccessible(m, true);
m.invoke(req, new Object[]{data.contextPath.toString()});
// request.setNote(SERVLET_REQUEST_NOTE, servletRequest);
// request.setNote(SERVLET_RESPONSE_NOTE, servletResponse);
handleRequest(service, mappings, req, res, null);
// System.out.println("handler is: "+uri.getPath());
}
};
ServerConfiguration sc = server.getServerConfiguration();
sc.addHttpHandler(handler, uri.getPath());
if(sidservers==null)
sidservers = new HashMap();
sidservers.put(service.getServiceId(), server);
ret.setResult(null);
}
catch(Exception e)
{
ret.setException(e);
}
}
});
return ret;
}
/**
* Get or start an api to the http server.
*/
public Object getHttpServer(URI uri, PublishInfo info)
{
HttpServer server = null;
try
{
// URI baseuri = new URI(uri.getScheme(), null, uri.getHost(), uri.getPort(), null, null, null);
server = portservers==null? null: portservers.get(uri.getPort());
if(server==null)
{
System.out.println("Starting new server: "+uri.getPort());
ErrorPageGenerator epg = null;
String keystore = null;
String keystorepass = null;
if(info!=null)
{
for(UnparsedExpression upex: info.getProperties())
{
// System.out.println("found publish expression: "+upex.getName());
if("sslkeystore".equals(upex.getName()))
{
keystore = (String)SJavaParser.getParsedValue(upex, null,
component!=null? component.getFetcher(): null, component!=null? component.getClassLoader(): null);
}
else if("sslkeystorepass".equals(upex.getName()))
{
keystorepass = (String)SJavaParser.getParsedValue(upex, null,
component!=null? component.getFetcher(): null, component!=null? component.getClassLoader(): null);
}
else if("errorpage".equals(upex.getName()))
{
String errpage = (String)SJavaParser.getParsedValue(upex, null,
component!=null? component.getFetcher(): null, component!=null? component.getClassLoader(): null);
if(errpage!=null)
{
final String errp = SUtil.readFile(errpage);
// System.out.println("errorpage path: "+errpage);
// System.out.println("errorpage: "+errp);
epg = new ErrorPageGenerator()
{
public String generate(Request request, int status, String reasonPhrase, String description, Throwable exception)
{
return errp;
}
};
}
}
}
}
if(keystore!=null)
{
SSLContextConfigurator sslContext = new SSLContextConfigurator();
sslContext.setKeyStoreFile(keystore); // contains server keypair
sslContext.setKeyStorePass(keystorepass);
// sslContext.setTrustStoreFile("./truststore_server"); // contains client certificate
// sslContext.setTrustStorePass("asdfgh");
SSLEngineConfigurator sslConf = new SSLEngineConfigurator(sslContext).setClientMode(false);
server = new HttpServer();
// final ServerConfiguration config = server.getServerConfiguration();
// config.addHttpHandler(handler, uri.getPath());
// config.setPassTraceRequest(true);
}
else
{
server = new HttpServer();
// server = GrizzlyHttpServerFactory.createHttpServer(uri, false);
}
NetworkListener listener = new NetworkListener("lis",
uri.getHost()!=null? uri.getHost(): "0.0.0.0", uri.getPort()!=-1? uri.getPort(): 80);
server.addListener(listener);
if(epg!=null)
{
server.getServerConfiguration().setDefaultErrorPageGenerator(epg);
}
ServerConfiguration sc = server.getServerConfiguration();
// sc.addHttpHandler(new HttpHandler()
// {
// public void service(Request request, Response response) throws Exception
// {
// Writer w = response.getWriter();
// w.write("ende");
// }
// }, "/test");
server.start();
if(portservers==null)
portservers = new HashMap();
portservers.put(uri.getPort(), server);
}
}
catch(RuntimeException e)
{
throw e;
}
catch(Exception e)
{
throw new RuntimeException(e);
}
return server;
}
/**
* Unpublish a service.
* @param sid The service identifier.
*/
public IFuture unpublishService(IServiceIdentifier sid)
{
throw new UnsupportedOperationException();
}
/**
* Publish a static page (without ressources).
*/
public IFuture publishHMTLPage(String uri, String vhost, String html)
{
throw new UnsupportedOperationException();
}
/**
* Publish file resources from the classpath.
*/
public IFuture publishResources(String uri, String rootpath)
{
throw new UnsupportedOperationException();
}
/**
* Publish file resources from the file system.
*/
public IFuture publishExternal(URI uri, String rootpath)
{
throw new UnsupportedOperationException();
}
public IFuture publishRedirect(URI uri, String html)
{
throw new UnsupportedOperationException();
}
public IFuture unpublish(String vhost, URI uri)
{
throw new UnsupportedOperationException();
}
public IFuture mirrorHttpServer(URI sourceserveruri, URI targetserveruri, PublishInfo info)
{
throw new UnsupportedOperationException();
}
public IFuture shutdownHttpServer(URI uri)
{
throw new UnsupportedOperationException();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy