2 * Copyright 2008-2009 LinkedIn, Inc
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 * use this file except in compliance with the License. You may obtain a copy of
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 * License for the specific language governing permissions and limitations under
17 package voldemort
.server
.http
;
19 import org
.apache
.log4j
.Logger
;
20 import org
.mortbay
.jetty
.Connector
;
21 import org
.mortbay
.jetty
.Server
;
22 import org
.mortbay
.jetty
.nio
.SelectChannelConnector
;
23 import org
.mortbay
.jetty
.servlet
.Context
;
24 import org
.mortbay
.jetty
.servlet
.ServletHolder
;
25 import org
.mortbay
.thread
.QueuedThreadPool
;
27 import voldemort
.VoldemortException
;
28 import voldemort
.annotations
.jmx
.JmxGetter
;
29 import voldemort
.annotations
.jmx
.JmxManaged
;
30 import voldemort
.client
.protocol
.RequestFormatType
;
31 import voldemort
.common
.service
.AbstractService
;
32 import voldemort
.common
.service
.ServiceType
;
33 import voldemort
.server
.StoreRepository
;
34 import voldemort
.server
.VoldemortServer
;
35 import voldemort
.server
.http
.gui
.AdminServlet
;
36 import voldemort
.server
.http
.gui
.ReadOnlyStoreManagementServlet
;
37 import voldemort
.server
.http
.gui
.StatusServlet
;
38 import voldemort
.server
.http
.gui
.VelocityEngine
;
39 import voldemort
.server
.protocol
.RequestHandler
;
40 import voldemort
.server
.protocol
.SocketRequestHandlerFactory
;
41 import voldemort
.server
.storage
.StorageService
;
44 * An embedded http server that uses jetty
48 @JmxManaged(description
= "A store connector that serves remote clients via HTTP.")
49 public class HttpService
extends AbstractService
{
51 private final Logger logger
= Logger
.getLogger(HttpService
.class);
53 private final int port
;
54 private final int numberOfThreads
;
55 private final VoldemortServer server
;
56 private final VelocityEngine velocityEngine
;
57 private final RequestHandler requestHandler
;
58 private Server httpServer
;
59 private Context context
;
61 @SuppressWarnings("unused")
62 public HttpService(VoldemortServer server
,
63 StorageService storageService
,
64 StoreRepository storeRepository
,
65 RequestFormatType requestType
,
68 super(ServiceType
.HTTP
);
70 this.numberOfThreads
= numberOfThreads
;
72 this.velocityEngine
= new VelocityEngine(VoldemortServletContextListener
.VOLDEMORT_TEMPLATE_DIR
);
73 this.requestHandler
= new SocketRequestHandlerFactory(storageService
,
74 server
.getStoreRepository(),
75 server
.getMetadataStore(),
76 server
.getVoldemortConfig(),
77 server
.getAsyncRunner(),
78 null).getRequestHandler(requestType
);
82 public void startInner() {
84 SelectChannelConnector connector
= new SelectChannelConnector();
85 connector
.setLowResourceMaxIdleTime(3000);
86 connector
.setPort(this.port
);
87 connector
.setReuseAddress(true);
88 QueuedThreadPool threadPool
= new QueuedThreadPool();
89 threadPool
.setName("VoldemortHttp");
90 threadPool
.setMaxThreads(this.numberOfThreads
);
91 Server httpServer
= new Server();
92 httpServer
.setConnectors(new Connector
[] { connector
});
93 httpServer
.setThreadPool(threadPool
);
94 httpServer
.setSendServerVersion(false);
95 httpServer
.setSendDateHeader(false);
96 Context context
= new Context(httpServer
, "/", Context
.NO_SESSIONS
);
97 context
.setAttribute(VoldemortServletContextListener
.SERVER_KEY
, server
);
98 context
.setAttribute(VoldemortServletContextListener
.VELOCITY_ENGINE_KEY
,
100 context
.addServlet(new ServletHolder(new AdminServlet(server
, velocityEngine
)),
102 context
.addServlet(new ServletHolder(new StoreServlet(requestHandler
)), "/stores");
103 context
.addServlet(new ServletHolder(new ReadOnlyStoreManagementServlet(server
,
106 context
.addServlet(new ServletHolder(new StatusServlet(server
, velocityEngine
)),
108 this.context
= context
;
109 this.httpServer
= httpServer
;
110 this.httpServer
.start();
111 logger
.info("HTTP service started on port " + this.port
);
112 } catch(Exception e
) {
113 String errorMessage
= " Error starting service on port " + this.port
;
114 throw new VoldemortException(errorMessage
, e
);
119 public void stopInner() {
121 if(httpServer
!= null) {
123 for(Connector c
: httpServer
.getConnectors()) {
129 } catch(Exception e
) {
130 throw new VoldemortException(e
);
132 this.httpServer
= null;
136 @JmxGetter(name
= "numberOfThreads",
137 description
= "The number of threads used for the thread pool for HTTP.")
138 public int getNumberOfThreads() {
139 return numberOfThreads
;
142 @JmxGetter(name
= "port", description
= "The port on which http connections are accepted.")
143 public int getPort() {
147 public RequestHandler
getRequestHandler() {
148 return requestHandler
;