App Engine SDK 1.8.4 release.
[gae.git] / java / src / main / com / google / appengine / api / labs / modules / ModulesServiceImpl.java
blob4a67e45b250fb4c42aa59fda500a48272680f364
1 package com.google.appengine.api.labs.modules;
3 import com.google.appengine.api.labs.modules.ModulesServicePb.GetDefaultVersionRequest;
4 import com.google.appengine.api.labs.modules.ModulesServicePb.GetDefaultVersionResponse;
5 import com.google.appengine.api.labs.modules.ModulesServicePb.GetHostnameRequest;
6 import com.google.appengine.api.labs.modules.ModulesServicePb.GetHostnameResponse;
7 import com.google.appengine.api.labs.modules.ModulesServicePb.GetModulesRequest;
8 import com.google.appengine.api.labs.modules.ModulesServicePb.GetModulesResponse;
9 import com.google.appengine.api.labs.modules.ModulesServicePb.GetNumInstancesRequest;
10 import com.google.appengine.api.labs.modules.ModulesServicePb.GetNumInstancesResponse;
11 import com.google.appengine.api.labs.modules.ModulesServicePb.GetVersionsRequest;
12 import com.google.appengine.api.labs.modules.ModulesServicePb.GetVersionsResponse;
13 import com.google.appengine.api.labs.modules.ModulesServicePb.ModulesServiceError.ErrorCode;
14 import com.google.appengine.api.labs.modules.ModulesServicePb.SetNumInstancesRequest;
15 import com.google.appengine.api.labs.modules.ModulesServicePb.StartModuleRequest;
16 import com.google.appengine.api.labs.modules.ModulesServicePb.StartModuleResponse;
17 import com.google.appengine.api.labs.modules.ModulesServicePb.StopModuleRequest;
18 import com.google.appengine.api.labs.modules.ModulesServicePb.StopModuleResponse;
19 import com.google.apphosting.api.ApiProxy;
20 import com.google.apphosting.api.ApiProxy.Environment;
21 import com.google.common.base.Pair;
22 import com.google.common.base.Splitter;
23 import com.google.common.collect.Sets;
24 import com.google.protobuf.InvalidProtocolBufferException;
25 import com.google.protobuf.Message;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.Set;
31 class ModulesServiceImpl implements ModulesService {
32 protected static final String PACKAGE = "modules";
34 /**
35 * Environment attribute key where the instance id is stored.
37 * @see ModulesService#getCurrentInstanceId()
39 private static final String INSTANCE_ID_ENV_ATTRIBUTE = "com.google.appengine.instance.id";
41 private Pair<String, String> getCurrentModuleAndVersion() {
42 Environment env = ApiProxy.getCurrentEnvironment();
43 String majorVersion = Splitter.on('.').split(env.getVersionId()).iterator().next();
44 if (majorVersion.contains(":")) {
45 List<String> result = Splitter.on(':').splitToList(majorVersion);
46 return Pair.of(result.get(0), result.get(1));
47 } else {
48 return Pair.of("default", majorVersion);
52 @Override
53 public String getCurrentModule() {
54 return getCurrentModuleAndVersion().first;
57 @Override
58 public String getCurrentVersion() {
59 return getCurrentModuleAndVersion().second;
62 private static Map<String, Object> getThreadLocalAttributes() {
63 return ApiProxy.getCurrentEnvironment().getAttributes();
66 @Override
67 public String getCurrentInstanceId() {
68 Map<String, Object> env = getThreadLocalAttributes();
69 if (!env.containsKey(INSTANCE_ID_ENV_ATTRIBUTE)) {
70 throw new ModulesException("No valid instance id for this instance.");
72 String instanceId = (String) getThreadLocalAttributes().get(INSTANCE_ID_ENV_ATTRIBUTE);
73 if (instanceId == null) {
74 throw new ModulesException("No valid instance id for this instance.");
76 return instanceId;
79 private static void makeSyncCall(String method, Message.Builder request, Message.Builder response)
80 throws ModulesException {
81 byte[] responseBytes;
82 try {
83 responseBytes = ApiProxy.makeSyncCall(PACKAGE, method, request.build().toByteArray());
84 response.mergeFrom(responseBytes);
85 } catch (ApiProxy.ApplicationException e) {
86 switch(ErrorCode.valueOf(e.getApplicationError())) {
87 case INVALID_MODULE:
88 throw new InvalidModuleException("Given module is not known.");
89 case INVALID_VERSION:
90 throw new InvalidVersionException("Given module version is not known.");
91 case INVALID_INSTANCES:
92 throw new InvalidInstanceException("Given instances value is invalid.");
93 case UNEXPECTED_STATE:
94 if (method.equals("StartModule")) {
95 throw new ModuleAlreadyStartedException("Given module version is already started.");
96 } else if (method.equals("StopModule")) {
97 throw new ModuleAlreadyStoppedException("Given module version is already stopped.");
99 default:
100 throw new ModulesException("Unknown error occurred.");
102 } catch (InvalidProtocolBufferException e) {
103 throw new RuntimeException("Internal logic error: Response PB could not be parsed.", e);
107 @Override
108 public Set<String> getModules() {
109 GetModulesResponse.Builder response = GetModulesResponse.newBuilder();
110 makeSyncCall("GetModules", GetModulesRequest.newBuilder(), response);
111 return Sets.newHashSet(response.getModuleList());
114 @Override
115 public Set<String> getVersions(String module) {
116 GetVersionsRequest.Builder request = GetVersionsRequest.newBuilder();
117 request.setModule(module);
118 GetVersionsResponse.Builder response = GetVersionsResponse.newBuilder();
119 makeSyncCall("GetVersions", request, response);
120 return Sets.newHashSet(response.getVersionList());
123 @Override
124 public String getDefaultVersion(String module) {
125 GetDefaultVersionRequest.Builder request = GetDefaultVersionRequest.newBuilder();
126 request.setModule(module);
127 GetDefaultVersionResponse.Builder response = GetDefaultVersionResponse.newBuilder();
128 makeSyncCall("GetDefaultVersion", request, response);
129 return response.getVersion();
132 @Override
133 public long getNumInstances(String module, String version) {
134 GetNumInstancesRequest.Builder request = GetNumInstancesRequest.newBuilder();
135 request.setModule(module);
136 request.setVersion(version);
137 GetNumInstancesResponse.Builder response = GetNumInstancesResponse.newBuilder();
138 makeSyncCall("GetNumInstances", request, response);
139 return response.getInstances();
142 @Override
143 public void setNumInstances(String module, String version, long instances) {
144 SetNumInstancesRequest.Builder request = SetNumInstancesRequest.newBuilder();
145 request.setModule(module);
146 request.setVersion(version);
147 request.setInstances(instances);
148 makeSyncCall("SetNumInstances", request, SetNumInstancesRequest.newBuilder());
151 @Override
152 public void startModule(String module, String version) {
153 StartModuleRequest.Builder request = StartModuleRequest.newBuilder();
154 request.setModule(module);
155 request.setVersion(version);
156 makeSyncCall("StartModule", request, StartModuleResponse.newBuilder());
159 @Override
160 public void stopModule(String module, String version) {
161 StopModuleRequest.Builder request = StopModuleRequest.newBuilder();
162 request.setModule(module);
163 request.setVersion(version);
164 makeSyncCall("StopModule", request, StopModuleResponse.newBuilder());
167 private String getHostname(GetHostnameRequest.Builder request) {
168 GetHostnameResponse.Builder response = GetHostnameResponse.newBuilder();
169 makeSyncCall("GetHostname", request, response);
170 return response.getHostname();
173 private GetHostnameRequest.Builder newGetHostnameRequestBuilder(String module, String version) {
174 GetHostnameRequest.Builder builder = GetHostnameRequest.newBuilder();
175 if (module != null) {
176 builder.setModule(module);
178 if (version != null) {
179 builder.setVersion(version);
181 return builder;
184 @Override
185 public String getModuleHostname(String module, String version) {
186 GetHostnameRequest.Builder requestBuilder = newGetHostnameRequestBuilder(module, version);
187 return getHostname(requestBuilder);
190 @Override
191 public String getModuleHostname(String module, String version, int instance) {
192 GetHostnameRequest.Builder requestBuilder = newGetHostnameRequestBuilder(module, version);
193 requestBuilder.setInstance(Integer.toString(instance));
194 return getHostname(requestBuilder);
197 ModulesServiceImpl() { }