1 // Copyright 2011 Google Inc. All Rights Reserved.
3 package com
.google
.appengine
.tools
.admin
;
5 import com
.google
.apphosting
.utils
.config
.AppEngineConfigException
;
6 import com
.google
.apphosting
.utils
.config
.YamlUtils
;
8 import java
.io
.IOException
;
9 import java
.net
.HttpURLConnection
;
10 import java
.util
.HashMap
;
12 import java
.util
.Map
.Entry
;
18 public final class ResourceLimits
{
19 private final Map
<String
, Long
> resourceLimitsMap
;
22 * The names of our resources. Must be kept in sync with the admin console
23 * (see //apphosting/client/admin_console/api/appversion.py
24 * GetResourceLimitsHandler)
26 static final String MAX_BLOB_SIZE_KEY
= "max_blob_size";
27 static final String MAX_FILE_COUNT_KEY
= "max_file_count";
28 static final String MAX_FILE_SIZE_KEY
= "max_file_size";
29 static final String MAX_TOTAL_FILE_SIZE_KEY
= "max_total_file_size";
32 * Map of our default max resource limits.
34 private static final HashMap
<String
, Long
> DEFAULT_RESOURCE_LIMITS
;
36 DEFAULT_RESOURCE_LIMITS
= new HashMap
<String
, Long
>();
37 final long MILLION
= 1000 * 1000;
38 final long MEGA
= 1024 * 1024;
39 DEFAULT_RESOURCE_LIMITS
.put(MAX_BLOB_SIZE_KEY
, 32 * MILLION
);
40 DEFAULT_RESOURCE_LIMITS
.put(MAX_FILE_COUNT_KEY
, 10000L);
41 DEFAULT_RESOURCE_LIMITS
.put(MAX_FILE_SIZE_KEY
, 32 * MILLION
);
42 DEFAULT_RESOURCE_LIMITS
.put(MAX_TOTAL_FILE_SIZE_KEY
, 150 * MEGA
);
46 * Constructs a ResourceLimits object. The method is private; users of
47 * the class should create instance with {@code getResourceLimits()}.
49 * @param resourceLimitsMap A map that has (at a minimum) the expected
50 * resource limits (it may include extra entries).
52 private ResourceLimits(Map
<String
, Long
> resourceLimitsMap
) {
53 this.resourceLimitsMap
= resourceLimitsMap
;
57 * Gets the maximum blob size.
59 * @return The maximum blob size.
61 public long maxBlobSize() {
62 return resourceLimitsMap
.get(MAX_BLOB_SIZE_KEY
).longValue();
66 * Gets the maximum file count.
68 * @return The maximum file count.
70 public long maxFileCount() {
71 return resourceLimitsMap
.get(MAX_FILE_COUNT_KEY
).longValue();
75 * Gets the maximum file size.
77 * @return The maximum file size.
79 public long maxFileSize() {
80 return resourceLimitsMap
.get(MAX_FILE_SIZE_KEY
).longValue();
84 * Gets the maximum total file size.
86 * @return The maximum total file size.
88 public long maxTotalFileSize() {
89 return resourceLimitsMap
.get(MAX_TOTAL_FILE_SIZE_KEY
).longValue();
93 * Get the set of all resource limits.
95 * @return The set of all resource limits.
97 public Set
<String
> keySet() {
98 return resourceLimitsMap
.keySet();
102 * Get a resource limit by name. This should be used in conjunction with
103 * {@code keySet()} for display purposes.
105 * @param key The name of the resource limit as returned by {@code keySet()}.
106 * @return The value of the resource limit.
108 public long get(String key
) {
109 return resourceLimitsMap
.get(key
);
113 * Gets the resource limits. The values returned are a combination of
114 * values reported by the adminconsole/appserver plus locally defined
115 * defaults for any missing values.
117 * @param connection A connection to the adminconsole.
119 * @return A ResourceLimits instance.
121 * @throws IOException for errors regarding communicating with the
124 public static ResourceLimits
request(ServerConnection connection
,
125 GenericApplication app
) throws IOException
{
126 Map
<String
, Long
> remoteResourceLimits
= remoteRequest(connection
, app
);
127 for (Entry
<String
, Long
> defaultEntry
: DEFAULT_RESOURCE_LIMITS
.entrySet()) {
128 if (!remoteResourceLimits
.containsKey(defaultEntry
.getKey())) {
129 remoteResourceLimits
.put(defaultEntry
.getKey(),
130 defaultEntry
.getValue());
134 return new ResourceLimits(remoteResourceLimits
);
138 * Gets the resource limits as reported by the server.
140 * @param connection A connection to the adminconsole.
142 * @return A map of all the resource limits reported by the current
145 * @throws AdminException for errors regarding the data returned from
148 * @throws IOException for errors regarding communicating with the
151 private static Map
<String
, Long
> remoteRequest(ServerConnection connection
,
152 GenericApplication app
) throws IOException
{
155 reply
= connection
.post("/api/appversion/getresourcelimits", "",
156 "app_id", app
.getAppId(), "version", app
.getVersion());
157 return YamlUtils
.genericParse(reply
,
158 new YamlUtils
.ObjectConverter
<Long
>() {
160 public Long
convert(Object obj
) {
161 return Long
.parseLong((String
) obj
);
164 } catch (AppEngineConfigException exc
) {
165 throw new AdminException("Error parsing YAML: " + reply
, exc
);
166 } catch (HttpIoException exc
) {
167 if (exc
.getResponseCode() == HttpURLConnection
.HTTP_NOT_FOUND
) {
168 return new HashMap
<String
, Long
>();
175 * Generate a resource limits object for testing purposes.
177 * @param testValues A map of values to use.
179 * @return A ResourceLimits instance.
181 static ResourceLimits
generate(Map
<String
, Long
> testValues
) {
182 return new ResourceLimits(testValues
);