/java/src/main/com/google/appengine/api/labs/servers/ServersServiceImpl.java

http://googleappengine.googlecode.com/ · Java · 191 lines · 165 code · 21 blank · 5 comment · 8 complexity · e09e571ad4250ae15291580385fddddf MD5 · raw file

  1. package com.google.appengine.api.labs.servers;
  2. import com.google.appengine.api.labs.servers.ServersServicePb.GetDefaultVersionRequest;
  3. import com.google.appengine.api.labs.servers.ServersServicePb.GetDefaultVersionResponse;
  4. import com.google.appengine.api.labs.servers.ServersServicePb.GetHostnameRequest;
  5. import com.google.appengine.api.labs.servers.ServersServicePb.GetHostnameResponse;
  6. import com.google.appengine.api.labs.servers.ServersServicePb.GetNumInstancesRequest;
  7. import com.google.appengine.api.labs.servers.ServersServicePb.GetNumInstancesResponse;
  8. import com.google.appengine.api.labs.servers.ServersServicePb.GetServersRequest;
  9. import com.google.appengine.api.labs.servers.ServersServicePb.GetServersResponse;
  10. import com.google.appengine.api.labs.servers.ServersServicePb.GetVersionsRequest;
  11. import com.google.appengine.api.labs.servers.ServersServicePb.GetVersionsResponse;
  12. import com.google.appengine.api.labs.servers.ServersServicePb.ServersServiceError.ErrorCode;
  13. import com.google.appengine.api.labs.servers.ServersServicePb.SetNumInstancesRequest;
  14. import com.google.appengine.api.labs.servers.ServersServicePb.StartServerRequest;
  15. import com.google.appengine.api.labs.servers.ServersServicePb.StartServerResponse;
  16. import com.google.appengine.api.labs.servers.ServersServicePb.StopServerRequest;
  17. import com.google.appengine.api.labs.servers.ServersServicePb.StopServerResponse;
  18. import com.google.apphosting.api.ApiProxy;
  19. import com.google.apphosting.api.ApiProxy.Environment;
  20. import com.google.common.base.Pair;
  21. import com.google.common.base.Splitter;
  22. import com.google.common.collect.Sets;
  23. import com.google.protobuf.InvalidProtocolBufferException;
  24. import com.google.protobuf.Message;
  25. import java.util.List;
  26. import java.util.Map;
  27. import java.util.Set;
  28. class ServersServiceImpl implements ServersService {
  29. protected static final String PACKAGE = "servers";
  30. /**
  31. * Environment attribute key where the instance id is stored.
  32. *
  33. * @see ServersService#getCurrentInstanceId()
  34. */
  35. private static final String INSTANCE_ID_ENV_ATTRIBUTE = "com.google.appengine.instance.id";
  36. private Pair<String, String> getCurrentServerAndVersion() {
  37. Environment env = ApiProxy.getCurrentEnvironment();
  38. String majorVersion = Splitter.on('.').split(env.getVersionId()).iterator().next();
  39. if (majorVersion.contains(":")) {
  40. List<String> result = Splitter.on(':').splitToList(majorVersion);
  41. return Pair.of(result.get(0), result.get(1));
  42. } else {
  43. return Pair.of("default", majorVersion);
  44. }
  45. }
  46. @Override
  47. public String getCurrentServer() {
  48. return getCurrentServerAndVersion().first;
  49. }
  50. @Override
  51. public String getCurrentVersion() {
  52. return getCurrentServerAndVersion().second;
  53. }
  54. private static Map<String, Object> getThreadLocalAttributes() {
  55. return ApiProxy.getCurrentEnvironment().getAttributes();
  56. }
  57. @Override
  58. public String getCurrentInstanceId() {
  59. Map<String, Object> env = getThreadLocalAttributes();
  60. if (!env.containsKey(INSTANCE_ID_ENV_ATTRIBUTE)) {
  61. throw new ServersException("No valid instance id for this instance.");
  62. }
  63. String instanceId = (String) getThreadLocalAttributes().get(INSTANCE_ID_ENV_ATTRIBUTE);
  64. if (instanceId == null) {
  65. throw new ServersException("No valid instance id for this instance.");
  66. }
  67. return instanceId;
  68. }
  69. private static void makeSyncCall(String method, Message.Builder request, Message.Builder response)
  70. throws ServersException {
  71. byte[] responseBytes;
  72. try {
  73. responseBytes = ApiProxy.makeSyncCall(PACKAGE, method, request.build().toByteArray());
  74. response.mergeFrom(responseBytes);
  75. } catch (ApiProxy.ApplicationException e) {
  76. switch(ErrorCode.valueOf(e.getApplicationError())) {
  77. case INVALID_SERVER:
  78. throw new InvalidServerException("Given server is not known.");
  79. case INVALID_VERSION:
  80. throw new InvalidVersionException("Given server version is not known.");
  81. case INVALID_INSTANCES:
  82. throw new InvalidInstanceException("Given instances value is invalid.");
  83. case UNEXPECTED_STATE:
  84. if (method.equals("StartServer")) {
  85. throw new ServerAlreadyStartedException("Given server version is already started.");
  86. } else if (method.equals("StopServer")) {
  87. throw new ServerAlreadyStoppedException("Given server version is already stopped.");
  88. }
  89. default:
  90. throw new ServersException("Unknown error occurred.");
  91. }
  92. } catch (InvalidProtocolBufferException e) {
  93. throw new RuntimeException("Internal logic error: Response PB could not be parsed.", e);
  94. }
  95. }
  96. @Override
  97. public Set<String> getServers() {
  98. GetServersResponse.Builder response = GetServersResponse.newBuilder();
  99. makeSyncCall("GetServers", GetServersRequest.newBuilder(), response);
  100. return Sets.newHashSet(response.getServerList());
  101. }
  102. @Override
  103. public Set<String> getVersions(String server) {
  104. GetVersionsRequest.Builder request = GetVersionsRequest.newBuilder();
  105. request.setServer(server);
  106. GetVersionsResponse.Builder response = GetVersionsResponse.newBuilder();
  107. makeSyncCall("GetVersions", request, response);
  108. return Sets.newHashSet(response.getVersionList());
  109. }
  110. @Override
  111. public String getDefaultVersion(String server) {
  112. GetDefaultVersionRequest.Builder request = GetDefaultVersionRequest.newBuilder();
  113. request.setServer(server);
  114. GetDefaultVersionResponse.Builder response = GetDefaultVersionResponse.newBuilder();
  115. makeSyncCall("GetDefaultVersion", request, response);
  116. return response.getVersion();
  117. }
  118. @Override
  119. public long getNumInstances(String server, String version) {
  120. GetNumInstancesRequest.Builder request = GetNumInstancesRequest.newBuilder();
  121. request.setServer(server);
  122. request.setVersion(version);
  123. GetNumInstancesResponse.Builder response = GetNumInstancesResponse.newBuilder();
  124. makeSyncCall("GetNumInstances", request, response);
  125. return response.getInstances();
  126. }
  127. @Override
  128. public void setNumInstances(String server, String version, long instances) {
  129. SetNumInstancesRequest.Builder request = SetNumInstancesRequest.newBuilder();
  130. request.setServer(server);
  131. request.setVersion(version);
  132. request.setInstances(instances);
  133. makeSyncCall("SetNumInstances", request, SetNumInstancesRequest.newBuilder());
  134. }
  135. @Override
  136. public void startServer(String server, String version) {
  137. StartServerRequest.Builder request = StartServerRequest.newBuilder();
  138. request.setServer(server);
  139. request.setVersion(version);
  140. makeSyncCall("StartServer", request, StartServerResponse.newBuilder());
  141. }
  142. @Override
  143. public void stopServer(String server, String version) {
  144. StopServerRequest.Builder request = StopServerRequest.newBuilder();
  145. request.setServer(server);
  146. request.setVersion(version);
  147. makeSyncCall("StopServer", request, StopServerResponse.newBuilder());
  148. }
  149. private String getHostname(GetHostnameRequest.Builder request) {
  150. GetHostnameResponse.Builder response = GetHostnameResponse.newBuilder();
  151. makeSyncCall("GetHostname", request, response);
  152. return response.getHostname();
  153. }
  154. @Override
  155. public String getServerHostname(String server, String version) {
  156. GetHostnameRequest.Builder request = GetHostnameRequest.newBuilder();
  157. request.setServer(server);
  158. request.setVersion(version);
  159. return getHostname(request);
  160. }
  161. @Override
  162. public String getServerHostname(String server, String version, int instance) {
  163. GetHostnameRequest.Builder request = GetHostnameRequest.newBuilder();
  164. request.setServer(server);
  165. request.setVersion(version);
  166. request.setInstance(Integer.toString(instance));
  167. return getHostname(request);
  168. }
  169. ServersServiceImpl() { }
  170. }