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
;
31 class ModulesServiceImpl
implements ModulesService
{
32 protected static final String PACKAGE
= "modules";
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));
48 return Pair
.of("default", majorVersion
);
53 public String
getCurrentModule() {
54 return getCurrentModuleAndVersion().first
;
58 public String
getCurrentVersion() {
59 return getCurrentModuleAndVersion().second
;
62 private static Map
<String
, Object
> getThreadLocalAttributes() {
63 return ApiProxy
.getCurrentEnvironment().getAttributes();
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.");
79 private static void makeSyncCall(String method
, Message
.Builder request
, Message
.Builder response
)
80 throws ModulesException
{
83 responseBytes
= ApiProxy
.makeSyncCall(PACKAGE
, method
, request
.build().toByteArray());
84 response
.mergeFrom(responseBytes
);
85 } catch (ApiProxy
.ApplicationException e
) {
86 switch(ErrorCode
.valueOf(e
.getApplicationError())) {
88 throw new InvalidModuleException("Given module is not known.");
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.");
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
);
108 public Set
<String
> getModules() {
109 GetModulesResponse
.Builder response
= GetModulesResponse
.newBuilder();
110 makeSyncCall("GetModules", GetModulesRequest
.newBuilder(), response
);
111 return Sets
.newHashSet(response
.getModuleList());
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());
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();
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();
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());
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());
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
);
185 public String
getModuleHostname(String module
, String version
) {
186 GetHostnameRequest
.Builder requestBuilder
= newGetHostnameRequestBuilder(module
, version
);
187 return getHostname(requestBuilder
);
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() { }