1 package com
.google
.appengine
.tools
.development
;
3 import com
.google
.appengine
.api
.labs
.servers
.ServersServicePb
.ServersServiceError
;
4 import com
.google
.apphosting
.api
.ApiProxy
;
5 import com
.google
.apphosting
.api
.ApiProxy
.ApplicationException
;
6 import com
.google
.apphosting
.utils
.config
.AppEngineConfigException
;
7 import com
.google
.apphosting
.utils
.config
.AppEngineWebXml
;
8 import com
.google
.apphosting
.utils
.config
.AppEngineWebXml
.ManualScaling
;
9 import com
.google
.common
.collect
.ImmutableList
;
10 import com
.google
.common
.collect
.ImmutableMap
;
13 import java
.io
.IOException
;
14 import java
.util
.List
;
16 import java
.util
.logging
.Level
;
17 import java
.util
.logging
.Logger
;
19 import javax
.servlet
.ServletException
;
20 import javax
.servlet
.http
.HttpServletRequest
;
21 import javax
.servlet
.http
.HttpServletResponse
;
24 * Manager for {@link DevAppServer} servers.
27 public class Servers
implements ServersController
, ServersFilterHelper
{
28 private static final Logger LOGGER
= Logger
.getLogger(Servers
.class.getName());
30 private final List
<Server
> servers
;
31 private final Map
<String
, Server
> serverNameToServerMap
;
33 static Servers
createServers(ApplicationConfigurationManager applicationConfigurationManager
,
34 String serverInfo
, File externalResourceDir
, String address
, int port
,
35 DevAppServerImpl devAppServer
) {
36 ImmutableList
.Builder
<Server
> builder
= ImmutableList
.builder();
37 LocalServerEnvironment mainEnvironment
= null;
38 for (ApplicationConfigurationManager
.ServerConfigurationHandle serverConfigurationHandle
:
39 applicationConfigurationManager
.getServerConfigurationHandles()) {
40 AppEngineWebXml appEngineWebXml
=
41 serverConfigurationHandle
.getModule().getAppEngineWebXml();
43 if (!appEngineWebXml
.getBasicScaling().isEmpty()) {
44 throw new AppEngineConfigException("Basic scaling servers are currently not supported");
45 } else if (!appEngineWebXml
.getManualScaling().isEmpty()) {
46 server
= new ManualServer(serverConfigurationHandle
, serverInfo
, address
, devAppServer
,
49 server
= new AutomaticServer(serverConfigurationHandle
, serverInfo
, externalResourceDir
,
50 address
, port
, devAppServer
);
55 externalResourceDir
= null;
57 return new Servers(builder
.build());
60 void shutdown() throws Exception
{
61 for (Server server
: servers
) {
66 void configure(Map
<String
, Object
>containerConfigProperties
) throws Exception
{
67 for (Server server
: servers
) {
68 server
.configure(containerConfigProperties
);
72 void createConnections() throws Exception
{
73 for (Server server
: servers
) {
74 server
.createConnection();
78 void startup() throws Exception
{
79 for (Server server
: servers
) {
84 Server
getMainServer() {
85 return servers
.get(0);
88 private Servers(List
<Server
> servers
) {
89 if (servers
.size() < 1) {
90 throw new IllegalArgumentException("servers must not be empty.");
92 this.servers
= servers
;
94 ImmutableMap
.Builder
<String
, Server
> mapBuilder
= ImmutableMap
.builder();
95 for (Server server
: this.servers
) {
96 mapBuilder
.put(server
.getServerName(), server
);
98 serverNameToServerMap
= mapBuilder
.build();
101 LocalServerEnvironment
getLocalServerEnvironment() {
102 return servers
.get(0).getLocalServerEnvironment();
105 Server
getServer(String serverName
) {
106 return serverNameToServerMap
.get(serverName
);
110 public Iterable
<String
> getServerNames() {
111 return serverNameToServerMap
.keySet();
115 public Iterable
<String
> getVersions(String serverName
) throws ApplicationException
{
116 return ImmutableList
.of(getDefaultVersion(serverName
));
120 public String
getDefaultVersion(String serverName
) throws ApplicationException
{
121 Server server
= getRequiredServer(serverName
);
122 return server
.getMainContainer().getAppEngineWebXmlConfig().getMajorVersionId();
126 public int getNumInstances(String serverName
, String version
) throws ApplicationException
{
127 Server server
= getRequiredServer(serverName
);
128 checkVersion(version
, server
);
129 ManualScaling manualScaling
= getRequiredManualScaling(server
);
130 return Integer
.parseInt(manualScaling
.getInstances());
134 public String
getHostname(String serverName
, String version
, int instance
)
135 throws ApplicationException
{
136 Server server
= getRequiredServer(serverName
);
137 checkVersion(version
, server
);
138 if (instance
!= LocalEnvironment
.MAIN_INSTANCE
) {
139 getRequiredManualScaling(server
);
141 String hostAndPort
= server
.getHostAndPort(instance
);
142 if (hostAndPort
== null) {
143 throw new ApiProxy
.ApplicationException(
144 ServersServiceError
.ErrorCode
.INVALID_INSTANCES_VALUE
,
145 "Instance " + instance
+ " not found");
151 public void startServer(String serverName
, String version
) throws ApplicationException
{
152 Server server
= getRequiredServer(serverName
);
153 checkVersion(version
, server
);
154 getRequiredManualScaling(server
);
156 server
.startServing();
157 } catch (Exception e
) {
158 LOGGER
.log(Level
.SEVERE
, "startServing failed", e
);
159 new ApiProxy
.ApplicationException(ServersServiceError
.ErrorCode
.UNEXPECTED_STATE_VALUE
,
160 "startServing failed with error " + e
.getMessage());
165 public void stopServer(String serverName
, String version
) throws ApplicationException
{
166 Server server
= getRequiredServer(serverName
);
167 checkVersion(version
, server
);
168 getRequiredManualScaling(server
);
170 server
.stopServing();
171 } catch (Exception e
) {
172 LOGGER
.log(Level
.SEVERE
, "stopServing failed", e
);
173 new ApiProxy
.ApplicationException(ServersServiceError
.ErrorCode
.UNEXPECTED_STATE_VALUE
,
174 "stopServing failed with error " + e
.getMessage());
178 private Server
getRequiredServer(String serverName
) {
179 Server server
= serverNameToServerMap
.get(serverName
);
180 if (server
== null) {
181 throw new ApiProxy
.ApplicationException(ServersServiceError
.ErrorCode
.INVALID_SERVER_VALUE
,
187 private ManualScaling
getRequiredManualScaling(Server server
) {
188 ManualScaling manualScaling
=
189 server
.getMainContainer().getAppEngineWebXmlConfig().getManualScaling();
190 if (manualScaling
.isEmpty()) {
191 throw new ApiProxy
.ApplicationException(ServersServiceError
.ErrorCode
.INVALID_VERSION_VALUE
,
192 "Manual scaling is required.");
194 return manualScaling
;
197 private void checkVersion(String version
, Server server
) {
198 String serverVersion
=
199 server
.getMainContainer().getAppEngineWebXmlConfig().getMajorVersionId();
200 if (version
== null || !version
.equals(serverVersion
)) {
201 throw new ApiProxy
.ApplicationException(ServersServiceError
.ErrorCode
.INVALID_VERSION_VALUE
,
202 "Version not found");
207 public boolean acquireServingPermit(
208 String serverName
, int instanceNumber
, boolean allowQueueOnBackends
) {
209 Server server
= getServer(serverName
);
210 InstanceHolder instanceHolder
= server
.getInstanceHolder(instanceNumber
);
211 return instanceHolder
.acquireServingPermit();
215 public int getAndReserveFreeInstance(String requestedServer
) {
216 Server server
= getServer(requestedServer
);
217 InstanceHolder instanceHolder
= server
.getAndReserveAvailableInstanceHolder();
218 return instanceHolder
== null ?
-1 : instanceHolder
.getInstance();
222 public void returnServingPermit(String serverName
, int instance
) {
226 public boolean checkInstanceExists(String serverName
, int instance
) {
227 Server server
= getServer(serverName
);
228 return server
!= null && server
.getInstanceHolder(instance
) != null;
232 public boolean checkServerExists(String serverName
) {
233 return getServer(serverName
) != null;
237 public boolean checkServerStopped(String serverName
) {
238 return checkInstanceStopped(serverName
, LocalEnvironment
.MAIN_INSTANCE
);
242 public boolean checkInstanceStopped(String serverName
, int instance
) {
243 Server server
= getServer(serverName
);
244 InstanceHolder instanceHolder
= server
.getInstanceHolder(instance
);
245 return instanceHolder
.isStopped();
249 public void forwardToServer(String requestedServer
, int instance
, HttpServletRequest hrequest
,
250 HttpServletResponse hresponse
) throws IOException
, ServletException
{
251 Server server
= getServer(requestedServer
);
252 InstanceHolder instanceHolder
= server
.getInstanceHolder(instance
);
253 instanceHolder
.getContainerService().forwardToServer(hrequest
, hresponse
);
257 public boolean isServerLoadBalancingServer(String serverName
, int instance
) {
258 Server server
= getServer(serverName
);
259 InstanceHolder instanceHolder
= server
.getInstanceHolder(instance
);
260 return instanceHolder
.isServerLoadBalancingServer();
264 public boolean expectsGeneratedStartRequests(String serverName
,
266 Server server
= getServer(serverName
);
267 InstanceHolder instanceHolder
= server
.getInstanceHolder(instance
);
268 return instanceHolder
.expectsGeneratedStartRequest();