package com.sun.grizzly.http.embed; import java.io.IOException; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.HashMap; import java.util.Map.Entry; import java.util.logging.Level; import javax.management.ObjectName; import org.apache.log4j.Logger; import com.sun.grizzly.SSLConfig; import com.sun.grizzly.arp.AsyncFilter; import com.sun.grizzly.arp.AsyncHandler; import com.sun.grizzly.arp.DefaultAsyncHandler; import com.sun.grizzly.http.Management; import com.sun.grizzly.http.SelectorThread; import com.sun.grizzly.ssl.SSLSelectorThread; import com.sun.grizzly.tcp.Adapter; import com.sun.grizzly.tcp.http11.GrizzlyAdapter; import com.sun.grizzly.tcp.http11.GrizzlyAdapterChain; import com.sun.grizzly.util.net.jsse.JSSEImplementation; public class MyGrizzlyWebServer { private static Logger log = Logger.getLogger(MyGrizzlyWebServer.class); // The port private static final int DEFAULT_PORT = 8080; // The port private static final String DEFAULT_WEB_RESOURCES_PATH = "."; // The underlying {@link SelectorThread} private SelectorThread st = null; // The underlying {@link GrizzlyAdapterChain} private GrizzlyAdapterChain adapterChains = new GrizzlyAdapterChain(); // List of {@link GrizzlyAdapter} and its associated mapping private HashMap adapters = new HashMap(); // Are we started? private boolean isStarted = false; // List of {@link AsyncFilter} private ArrayList asyncFilters = new ArrayList(); // The path to static resource. private String webResourcesPath = DEFAULT_WEB_RESOURCES_PATH; // The mBean default object name. private String mBeanName = "com.sun.grizzly:type=GrizzlyWebServer,name=GrizzlyHttpEngine-" + DEFAULT_PORT; // The {@link Statistis} instance associated with this instance. private Statistics statistics; // private String bindAddress; /** * Create a default GrizzlyWebServer * @param maxThreads TODO */ public MyGrizzlyWebServer(String bindAddress, int port, int maxThreads, int coreThread, boolean asyncWrite,int keepAliveTimeoutInSeconds) { this.bindAddress = bindAddress; createSelectorThread(bindAddress, port, false); setMaxThreads(maxThreads); useAsynchronousWrite(asyncWrite); //MT SET DEI THREAD CORE setCoreThreads(coreThread); st.setDisplayConfiguration(true); st.setKeepAliveTimeoutInSeconds(keepAliveTimeoutInSeconds); this.webResourcesPath = DEFAULT_WEB_RESOURCES_PATH; } public MyGrizzlyWebServer(int port, int maxThreads, int coreThreads, boolean asyncWrite,int keepAliveTimeoutInSeconds) { this(null, port, maxThreads, coreThreads, asyncWrite, keepAliveTimeoutInSeconds); } /** * Create an underlying {@link SelectorThread} * @param port The port to listen to. * @param secure true if https needs to be used. */ private void createSelectorThread(String bindAddress, int port, boolean secure){ if (secure) { SSLSelectorThread sslSelectorThread = new SSLSelectorThread(); try { sslSelectorThread.setSSLImplementation(new JSSEImplementation()); } catch (ClassNotFoundException e) { throw new IllegalStateException(e); } st = sslSelectorThread; } else { st = new SelectorThread(); } // BindAddress if(bindAddress != null && !bindAddress.trim().equals("")){ try { log.info("set bindAddress="+bindAddress); InetAddress ip = InetAddress.getByName(bindAddress); st.setInet(ip); st.setAddress(ip); log.info("bindAddress setted"); } catch (UnknownHostException e1) { throw new IllegalArgumentException("UnknownHostException "+bindAddress); } }else{ log.info("BindAddress was null!"); } // Port st.setPort(port); } /** * Return the underlying {@link SelectorThread}. Only advanced users * should manipulate that class. * @return {@link SelectorThread} */ public SelectorThread getSelectorThread(){ return st; } /** * Add an {@link AsyncFilter}. Adding {@link AsyncFilter} automatically * enable Grizzly Asynchronous Request Processing mode. {@link AsyncFilter}s * are always invoked before {@link GrizzlyAdapter} * * @param asyncFilter An {@link AsyncFilter} */ public void addAsyncFilter(AsyncFilter asyncFilter){ asyncFilters.add(asyncFilter); } /** * Add a {@link GrizzlyAdapter}. {@link GrizzlyAdapter} will be invoked by * Grizzly in the order they are added, e.g the first added is always the * first invoked. {@link GrizzlyAdapter}s * are always invoked after {@link AsyncFilter} * @param grizzlyAdapter a {@link GrizzlyAdapter} * @deprecated - Use {@link #addGrizzlyAdapter(com.sun.grizzly.tcp.http11.GrizzlyAdapter, java.lang.String[])} */ public void addGrizzlyAdapter(GrizzlyAdapter grizzlyAdapter){ adapters.put(grizzlyAdapter,new String[0]); } /** * Add a {@link GrizzlyAdapter} with its associated mapping. A request will * be dispatched to a {@link GrizzlyAdapter} based on its mapping value. * @param grizzlyAdapter a {@link GrizzlyAdapter} * @param mapping An array contains the context path mapping information. */ public void addGrizzlyAdapter(GrizzlyAdapter grizzlyAdapter, String[] mapping){ adapters.put(grizzlyAdapter,mapping); adapterChains.setHandleStaticResources(false); if (isStarted) { Adapter ga = st.getAdapter(); if (ga instanceof GrizzlyAdapterChain){ ((GrizzlyAdapterChain)ga).addGrizzlyAdapter(grizzlyAdapter, mapping); } else { updateGrizzlyAdapters(); } } } /** * Remove a {@link GrizzlyAdapter} * return true of the operation was successful. */ public boolean removeGrizzlyAdapter(GrizzlyAdapter grizzlyAdapter){ if (adapters.size() > 1){ adapterChains.removeAdapter(grizzlyAdapter); } boolean removed = adapters.remove(grizzlyAdapter) != null; if (isStarted) { Adapter ga = st.getAdapter(); if (ga instanceof GrizzlyAdapterChain){ ((GrizzlyAdapterChain)ga).removeAdapter(grizzlyAdapter); } else { updateGrizzlyAdapters(); } } return removed; } /** * Set the {@link SSLConfig} instance used when https is required */ public void setSSLConfig(SSLConfig sslConfig){ if (!(st instanceof SSLSelectorThread)){ throw new IllegalStateException("This instance isn't supporting SSL/HTTPS"); } ((SSLSelectorThread)st).setSSLConfig(sslConfig); } /** * Set to true if you want to use asynchronous write operations. Asynchronous * write operations may significantly improve performance under high load, but * may also comsume more memory. Default is set to false. * @param asyncWrite true to enabled asynchronous write I/O operations. */ public void useAsynchronousWrite(boolean asyncWrite){ st.setAsyncHttpWriteEnabled(asyncWrite); } /** * Start the GrizzlyWebServer and start listening for http requests. Calling * this method several time has no effect once GrizzlyWebServer has been started. * @throws java.io.IOException */ public void start() throws IOException{ if (isStarted) return; isStarted = true; // Use the default updateGrizzlyAdapters(); if (asyncFilters.size() > 0){ st.setEnableAsyncExecution(true); AsyncHandler asyncHandler = new DefaultAsyncHandler(); for (AsyncFilter asyncFilter: asyncFilters){ asyncHandler.addAsyncFilter(asyncFilter); } st.setAsyncHandler(asyncHandler); } try { st.listen(); } catch (InstantiationException ex) { throw new IOException(ex.getMessage()); } } @SuppressWarnings("deprecation") private void updateGrizzlyAdapters() { adapterChains = new GrizzlyAdapterChain(); if (adapters.size() == 0){ adapterChains.setHandleStaticResources(true); st.setAdapter(adapterChains); } else if (adapters.size() == 1){ st.setAdapter(adapters.keySet().iterator().next()); } else { for (Entry entry: adapters.entrySet()){ // For backward compatibility if (entry.getValue().length == 0){ adapterChains.addGrizzlyAdapter(entry.getKey()); } else { adapterChains.addGrizzlyAdapter(entry.getKey(),entry.getValue()); } } st.setAdapter(adapterChains); adapterChains.setHandleStaticResources(true); adapterChains.setRootFolder(webResourcesPath); } } /** * Enable JMX Management by configuring the {@link Management} * @param jmxManagement An instance of the {@link Management} interface */ public void enableJMX(Management jmxManagement){ if (jmxManagement == null) return; st.setManagement(jmxManagement); try { ObjectName sname = new ObjectName(mBeanName); jmxManagement.registerComponent(st, sname, null); } catch (Exception ex) { SelectorThread.logger().log(Level.SEVERE, "Enabling JMX failed", ex); } } /** * Return a {@link Statistics} instance that can be used to gather * statistics. By default, the {@link Statistics} object is not * gathering statistics. Invoking {@link Statistics#startGatheringStatistics} * will do it. */ public Statistics getStatistics(){ if (statistics == null){ statistics = new Statistics(st); } return statistics; } /** * Set the initial number of threads in a thread pool. * @param coreThreads the initial number of threads in a thread pool. */ public void setCoreThreads(int coreThreads) { st.setCoreThreads(coreThreads); } /** * Set the maximum number of threads in a thread pool. * @param maxThreads the maximum number of threads in a thread pool. */ public void setMaxThreads(int maxThreads) { st.setMaxThreads(maxThreads); } /** * Stop the GrizzlyWebServer. */ public void stop(){ if (!isStarted) return; isStarted = false; st.stopEndpoint(); } @SuppressWarnings("unused") private String getBindAddress() { return this.bindAddress; } }