1.9.30 sync.
[gae.git] / java / src / main / com / google / apphosting / utils / config / AppEngineWebXml.java
blob95003fa87c7ab455b817187d509eb38ef5e87411
1 // Copyright 2008 Google Inc. All Rights Reserved.
2 package com.google.apphosting.utils.config;
4 import com.google.common.base.CharMatcher;
5 import com.google.common.collect.Lists;
6 import com.google.common.collect.Maps;
8 import java.security.Permissions;
9 import java.security.UnresolvedPermission;
10 import java.util.ArrayList;
11 import java.util.Collections;
12 import java.util.LinkedHashMap;
13 import java.util.LinkedHashSet;
14 import java.util.List;
15 import java.util.Map;
16 import java.util.Objects;
17 import java.util.Set;
18 import java.util.regex.Pattern;
20 /**
21 * Struct describing the config data that lives in WEB-INF/appengine-web.xml.
23 * Any additions to this class should also be made to the YAML
24 * version in AppYaml.java.
27 public class AppEngineWebXml implements Cloneable {
28 /**
29 * Enumeration of supported scaling types.
31 public static enum ScalingType {AUTOMATIC, MANUAL, BASIC}
33 private final Map<String, String> systemProperties = Maps.newHashMap();
35 private final Map<String, String> betaSettings = Maps.newLinkedHashMap();
37 private final HealthCheck healthCheck;
39 private final Resources resources;
41 private final Network network;
43 private final Map<String, String> envVariables = Maps.newHashMap();
45 private final List<UserPermission> userPermissions = new ArrayList<UserPermission>();
47 public static final String WARMUP_SERVICE = "warmup";
49 public static final String URL_HANDLER_URLFETCH = "urlfetch";
50 public static final String URL_HANDLER_NATIVE= "native";
52 private String appId;
54 private String majorVersionId;
56 private String module;
57 private String service;
58 private String instanceClass;
60 private final AutomaticScaling automaticScaling;
61 private final ManualScaling manualScaling;
62 private final BasicScaling basicScaling;
64 private String sourceLanguage;
65 private boolean sslEnabled = true;
66 private boolean useSessions = false;
67 private boolean asyncSessionPersistence = false;
68 private String asyncSessionPersistenceQueueName;
70 private final List<StaticFileInclude> staticFileIncludes;
71 private final List<String> staticFileExcludes;
72 private final List<String> resourceFileIncludes;
73 private final List<String> resourceFileExcludes;
75 private Pattern staticIncludePattern;
76 private Pattern staticExcludePattern;
77 private Pattern resourceIncludePattern;
78 private Pattern resourceExcludePattern;
80 private String publicRoot = "";
82 private String appRoot;
84 private final Set<String> inboundServices;
85 private boolean precompilationEnabled = true;
87 private final List<AdminConsolePage> adminConsolePages = new ArrayList<AdminConsolePage>();
88 private final List<ErrorHandler> errorHandlers = new ArrayList<ErrorHandler>();
90 private ClassLoaderConfig classLoaderConfig;
92 private String urlStreamHandlerType = null;
94 private boolean threadsafe = false;
95 private boolean threadsafeValueProvided = false;
97 private String autoIdPolicy;
99 private boolean codeLock = false;
100 private boolean useVm = false;
101 private String env = "1";
102 private ApiConfig apiConfig;
103 private final List<String> apiEndpointIds;
104 private Pagespeed pagespeed;
107 * Represent user's choice w.r.t the usage of Google's customized connector-j.
109 public static enum UseGoogleConnectorJ {
110 NOT_STATED_BY_USER,
111 TRUE,
112 FALSE,
114 private UseGoogleConnectorJ useGoogleConnectorJ = UseGoogleConnectorJ.NOT_STATED_BY_USER;
116 public AppEngineWebXml() {
117 automaticScaling = new AutomaticScaling();
118 manualScaling = new ManualScaling();
119 basicScaling = new BasicScaling();
120 healthCheck = new HealthCheck();
121 resources = new Resources();
122 network = new Network();
124 staticFileIncludes = new ArrayList<StaticFileInclude>();
125 staticFileExcludes = new ArrayList<String>();
126 staticFileExcludes.add("WEB-INF/**");
127 staticFileExcludes.add("**.jsp");
128 resourceFileIncludes = new ArrayList<String>();
129 resourceFileExcludes = new ArrayList<String>();
130 inboundServices = new LinkedHashSet<String>();
131 apiEndpointIds = new ArrayList<String>();
134 public AppEngineWebXml clone() {
135 try {
136 return (AppEngineWebXml) super.clone();
137 } catch (CloneNotSupportedException ce) {
138 throw new RuntimeException("Could not clone AppEngineWebXml", ce);
143 * @return An unmodifiable map whose entries correspond to the
144 * system properties defined in appengine-web.xml.
146 public Map<String, String> getSystemProperties() {
147 return Collections.unmodifiableMap(systemProperties);
150 public void addSystemProperty(String key, String value) {
151 systemProperties.put(key, value);
155 * @return An unmodifiable map whose entires correspond to the
156 * vm settings defined in appengine-web.xml.
158 public Map<String, String> getBetaSettings() {
159 return Collections.unmodifiableMap(betaSettings);
162 public void addBetaSetting(String key, String value) {
163 betaSettings.put(key, value);
166 public HealthCheck getHealthCheck() {
167 return healthCheck;
170 public Resources getResources() {
171 return resources;
174 public Network getNetwork() {
175 return network;
179 * @return An unmodifiable map whose entires correspond to the
180 * environment variables defined in appengine-web.xml.
182 public Map<String, String> getEnvironmentVariables() {
183 return Collections.unmodifiableMap(envVariables);
186 public void addEnvironmentVariable(String key, String value) {
187 envVariables.put(key, value);
190 public String getAppId() {
191 return appId;
194 public void setAppId(String appId) {
195 this.appId = appId;
198 public String getMajorVersionId() {
199 return majorVersionId;
202 public void setMajorVersionId(String majorVersionId) {
203 this.majorVersionId = majorVersionId;
206 public String getSourceLanguage() {
207 return this.sourceLanguage;
210 public void setSourceLanguage(String sourceLanguage) {
211 this.sourceLanguage = sourceLanguage;
214 public String getModule() {
215 return module;
218 public String getService() {
219 return service;
223 * Sets instanceClass (aka class in the xml/yaml files). Normalizes empty and null
224 * inputs to null.
226 public void setInstanceClass(String instanceClass) {
227 this.instanceClass = toNullIfEmptyOrWhitespace(instanceClass);
230 public String getInstanceClass() {
231 return instanceClass;
234 public AutomaticScaling getAutomaticScaling() {
235 return automaticScaling;
238 public ManualScaling getManualScaling() {
239 return manualScaling;
242 public BasicScaling getBasicScaling() {
243 return basicScaling;
246 public ScalingType getScalingType() {
247 if (!getBasicScaling().isEmpty()) {
248 return ScalingType.BASIC;
249 } else if (!getManualScaling().isEmpty()) {
250 return ScalingType.MANUAL;
251 } else {
252 return ScalingType.AUTOMATIC;
256 public void setModule(String module) {
257 this.module = module;
260 public void setService(String service) {
261 this.service = service;
264 public void setSslEnabled(boolean ssl) {
265 sslEnabled = ssl;
268 public boolean getSslEnabled() {
269 return sslEnabled;
272 public void setSessionsEnabled(boolean sessions) {
273 useSessions = sessions;
276 public boolean getSessionsEnabled() {
277 return useSessions;
280 public void setAsyncSessionPersistence(boolean asyncSessionPersistence) {
281 this.asyncSessionPersistence = asyncSessionPersistence;
284 public boolean getAsyncSessionPersistence() {
285 return asyncSessionPersistence;
288 public void setAsyncSessionPersistenceQueueName(String asyncSessionPersistenceQueueName) {
289 this.asyncSessionPersistenceQueueName = asyncSessionPersistenceQueueName;
292 public String getAsyncSessionPersistenceQueueName() {
293 return asyncSessionPersistenceQueueName;
296 public List<StaticFileInclude> getStaticFileIncludes() {
297 return staticFileIncludes;
300 public List<String> getStaticFileExcludes() {
301 return staticFileExcludes;
304 public StaticFileInclude includeStaticPattern(String pattern, String expiration) {
305 staticIncludePattern = null;
306 StaticFileInclude staticFileInclude = new StaticFileInclude(pattern, expiration);
307 staticFileIncludes.add(staticFileInclude);
308 return staticFileInclude;
311 public void excludeStaticPattern(String url) {
312 staticExcludePattern = null;
313 staticFileExcludes.add(url);
316 public List<String> getResourcePatterns() {
317 return resourceFileIncludes;
320 public List<String> getResourceFileExcludes() {
321 return resourceFileExcludes;
324 public void includeResourcePattern(String url) {
325 resourceExcludePattern = null;
326 resourceFileIncludes.add(url);
329 public void excludeResourcePattern(String url) {
330 resourceIncludePattern = null;
331 resourceFileExcludes.add(url);
334 public void addUserPermission(String className, String name, String actions) {
335 if (className.startsWith("java.")) {
336 throw new AppEngineConfigException("Cannot specify user-permissions for " +
337 "classes in java.* packages.");
340 userPermissions.add(new UserPermission(className, name, actions));
343 public Permissions getUserPermissions() {
344 Permissions permissions = new Permissions();
345 for (UserPermission permission : userPermissions) {
346 permissions.add(new UnresolvedPermission(permission.getClassName(),
347 permission.getName(),
348 permission.getActions(),
349 null));
351 permissions.setReadOnly();
352 return permissions;
355 public void setPublicRoot(String root) {
356 if (root.indexOf('*') != -1) {
357 throw new AppEngineConfigException("public-root cannot contain wildcards");
359 if (root.endsWith("/")) {
360 root = root.substring(0, root.length() - 1);
362 if (root.length() > 0 && !root.startsWith("/")) {
363 root = "/" + root;
365 staticIncludePattern = null;
366 publicRoot = root;
369 public String getPublicRoot() {
370 return publicRoot;
373 public void addInboundService(String service) {
374 inboundServices.add(service);
377 public Set<String> getInboundServices() {
378 return inboundServices;
381 public boolean getPrecompilationEnabled() {
382 return precompilationEnabled;
385 public void setPrecompilationEnabled(boolean precompilationEnabled) {
386 this.precompilationEnabled = precompilationEnabled;
389 public boolean getWarmupRequestsEnabled() {
390 return inboundServices.contains(WARMUP_SERVICE);
393 public void setWarmupRequestsEnabled(boolean warmupRequestsEnabled) {
394 if (warmupRequestsEnabled) {
395 inboundServices.add(WARMUP_SERVICE);
396 } else {
397 inboundServices.remove(WARMUP_SERVICE);
401 public List<AdminConsolePage> getAdminConsolePages() {
402 return Collections.unmodifiableList(adminConsolePages);
405 public void addAdminConsolePage(AdminConsolePage page) {
406 adminConsolePages.add(page);
409 public List<ErrorHandler> getErrorHandlers() {
410 return Collections.unmodifiableList(errorHandlers);
413 public void addErrorHandler(ErrorHandler handler) {
414 errorHandlers.add(handler);
417 public boolean getThreadsafe() {
418 return threadsafe;
421 public boolean getThreadsafeValueProvided() {
422 return threadsafeValueProvided;
425 public void setThreadsafe(boolean threadsafe) {
426 this.threadsafe = threadsafe;
427 this.threadsafeValueProvided = true;
430 public void setAutoIdPolicy(String policy) {
431 autoIdPolicy = policy;
434 public String getAutoIdPolicy() {
435 return autoIdPolicy;
438 public boolean getCodeLock() {
439 return codeLock;
442 public void setCodeLock(boolean codeLock) {
443 this.codeLock = codeLock;
446 public void setUseVm(boolean useVm) {
447 this.useVm = useVm;
450 public boolean getUseVm() {
451 return useVm;
454 public void setEnv(String env) {
455 this.env = env;
458 public String getEnv() {
459 return env;
462 public ApiConfig getApiConfig() {
463 return apiConfig;
466 public void setApiConfig(ApiConfig config) {
467 apiConfig = config;
470 public ClassLoaderConfig getClassLoaderConfig() {
471 return classLoaderConfig;
474 public void setClassLoaderConfig(ClassLoaderConfig classLoaderConfig) {
475 if (this.classLoaderConfig != null) {
476 throw new AppEngineConfigException("class-loader-config may only be specified once.");
478 this.classLoaderConfig = classLoaderConfig;
481 public String getUrlStreamHandlerType() {
482 return urlStreamHandlerType;
485 public void setUrlStreamHandlerType(String urlStreamHandlerType) {
486 if (this.classLoaderConfig != null) {
487 throw new AppEngineConfigException("url-stream-handler may only be specified once.");
489 if (!URL_HANDLER_URLFETCH.equals(urlStreamHandlerType)
490 && !URL_HANDLER_NATIVE.equals(urlStreamHandlerType)) {
491 throw new AppEngineConfigException(
492 "url-stream-handler must be " + URL_HANDLER_URLFETCH + " or " + URL_HANDLER_NATIVE +
493 " given " + urlStreamHandlerType);
495 this.urlStreamHandlerType = urlStreamHandlerType;
499 * Returns true if {@code url} matches one of the servlets or servlet
500 * filters listed in this web.xml that has api-endpoint set to true.
502 public boolean isApiEndpoint(String id) {
503 return apiEndpointIds.contains(id);
506 public void addApiEndpoint(String id) {
507 apiEndpointIds.add(id);
510 public Pagespeed getPagespeed() {
511 return pagespeed;
514 public void setPagespeed(Pagespeed pagespeed) {
515 this.pagespeed = pagespeed;
518 public void setUseGoogleConnectorJ(boolean useGoogleConnectorJ) {
519 if (useGoogleConnectorJ) {
520 this.useGoogleConnectorJ = UseGoogleConnectorJ.TRUE;
521 } else {
522 this.useGoogleConnectorJ = UseGoogleConnectorJ.FALSE;
526 public UseGoogleConnectorJ getUseGoogleConnectorJ() {
527 return useGoogleConnectorJ;
530 @Override
531 public String toString() {
532 return "AppEngineWebXml{"
533 + "systemProperties="
534 + systemProperties
535 + ", envVariables="
536 + envVariables
537 + ", userPermissions="
538 + userPermissions
539 + ", appId='"
540 + appId
541 + '\''
542 + ", majorVersionId='"
543 + majorVersionId
544 + '\''
545 + ", sourceLanguage='"
546 + sourceLanguage
547 + '\''
548 + ", service='"
549 + service
550 + '\''
551 + ", instanceClass='"
552 + instanceClass
553 + '\''
554 + ", automaticScaling="
555 + automaticScaling
556 + ", manualScaling="
557 + manualScaling
558 + ", basicScaling="
559 + basicScaling
560 + ", healthCheck="
561 + healthCheck
562 + ", resources="
563 + resources
564 + ", network="
565 + network
566 + ", sslEnabled="
567 + sslEnabled
568 + ", useSessions="
569 + useSessions
570 + ", asyncSessionPersistence="
571 + asyncSessionPersistence
572 + ", asyncSessionPersistenceQueueName='"
573 + asyncSessionPersistenceQueueName
574 + '\''
575 + ", staticFileIncludes="
576 + staticFileIncludes
577 + ", staticFileExcludes="
578 + staticFileExcludes
579 + ", resourceFileIncludes="
580 + resourceFileIncludes
581 + ", resourceFileExcludes="
582 + resourceFileExcludes
583 + ", staticIncludePattern="
584 + staticIncludePattern
585 + ", staticExcludePattern="
586 + staticExcludePattern
587 + ", resourceIncludePattern="
588 + resourceIncludePattern
589 + ", resourceExcludePattern="
590 + resourceExcludePattern
591 + ", publicRoot='"
592 + publicRoot
593 + '\''
594 + ", appRoot='"
595 + appRoot
596 + '\''
597 + ", inboundServices="
598 + inboundServices
599 + ", precompilationEnabled="
600 + precompilationEnabled
601 + ", adminConsolePages="
602 + adminConsolePages
603 + ", errorHandlers="
604 + errorHandlers
605 + ", threadsafe="
606 + threadsafe
607 + ", threadsafeValueProvided="
608 + threadsafeValueProvided
609 + ", autoIdPolicy="
610 + autoIdPolicy
611 + ", codeLock="
612 + codeLock
613 + ", apiConfig="
614 + apiConfig
615 + ", apiEndpointIds="
616 + apiEndpointIds
617 + ", pagespeed="
618 + pagespeed
619 + ", classLoaderConfig="
620 + classLoaderConfig
621 + ", urlStreamHandlerType="
622 + (urlStreamHandlerType == null ? URL_HANDLER_URLFETCH : urlStreamHandlerType)
623 + ", useGoogleConnectorJ="
624 + useGoogleConnectorJ
625 + '}';
628 @Override
629 public boolean equals(Object o) {
630 if (this == o) {
631 return true;
633 if (o == null || getClass() != o.getClass()) {
634 return false;
637 AppEngineWebXml that = (AppEngineWebXml) o;
639 if (asyncSessionPersistence != that.asyncSessionPersistence) {
640 return false;
642 if (precompilationEnabled != that.precompilationEnabled) {
643 return false;
645 if (sslEnabled != that.sslEnabled) {
646 return false;
648 if (threadsafe != that.threadsafe) {
649 return false;
651 if (threadsafeValueProvided != that.threadsafeValueProvided) {
652 return false;
654 if (autoIdPolicy != null ? !autoIdPolicy.equals(that.autoIdPolicy)
655 : that.autoIdPolicy != null) {
656 return false;
658 if (codeLock != that.codeLock) {
659 return false;
661 if (useSessions != that.useSessions) {
662 return false;
664 if (adminConsolePages != null ? !adminConsolePages.equals(that.adminConsolePages)
665 : that.adminConsolePages != null) {
666 return false;
668 if (appId != null ? !appId.equals(that.appId) : that.appId != null) {
669 return false;
671 if (majorVersionId != null ? !majorVersionId.equals(that.majorVersionId)
672 : that.majorVersionId != null) {
673 return false;
675 if (service != null ? !service.equals(that.service) : that.service != null) {
676 return false;
678 if (instanceClass != null ? !instanceClass.equals(that.instanceClass)
679 : that.instanceClass != null) {
680 return false;
682 if (!automaticScaling.equals(that.automaticScaling)) {
683 return false;
685 if (!manualScaling.equals(that.manualScaling)) {
686 return false;
688 if (!basicScaling.equals(that.basicScaling)) {
689 return false;
691 if (appRoot != null ? !appRoot.equals(that.appRoot) : that.appRoot != null) {
692 return false;
694 if (asyncSessionPersistenceQueueName != null ? !asyncSessionPersistenceQueueName
695 .equals(that.asyncSessionPersistenceQueueName)
696 : that.asyncSessionPersistenceQueueName != null) {
697 return false;
699 if (envVariables != null ? !envVariables.equals(that.envVariables)
700 : that.envVariables != null) {
701 return false;
703 if (errorHandlers != null ? !errorHandlers.equals(that.errorHandlers)
704 : that.errorHandlers != null) {
705 return false;
707 if (inboundServices != null ? !inboundServices.equals(that.inboundServices)
708 : that.inboundServices != null) {
709 return false;
711 if (majorVersionId != null ? !majorVersionId.equals(that.majorVersionId)
712 : that.majorVersionId != null) {
713 return false;
715 if (sourceLanguage != null ? !sourceLanguage.equals(that.sourceLanguage)
716 : that.sourceLanguage != null) {
717 return false;
719 if (publicRoot != null ? !publicRoot.equals(that.publicRoot) : that.publicRoot != null) {
720 return false;
722 if (resourceExcludePattern != null ? !resourceExcludePattern.equals(that.resourceExcludePattern)
723 : that.resourceExcludePattern != null) {
724 return false;
726 if (resourceFileExcludes != null ? !resourceFileExcludes.equals(that.resourceFileExcludes)
727 : that.resourceFileExcludes != null) {
728 return false;
730 if (resourceFileIncludes != null ? !resourceFileIncludes.equals(that.resourceFileIncludes)
731 : that.resourceFileIncludes != null) {
732 return false;
734 if (resourceIncludePattern != null ? !resourceIncludePattern.equals(that.resourceIncludePattern)
735 : that.resourceIncludePattern != null) {
736 return false;
738 if (staticExcludePattern != null ? !staticExcludePattern.equals(that.staticExcludePattern)
739 : that.staticExcludePattern != null) {
740 return false;
742 if (staticFileExcludes != null ? !staticFileExcludes.equals(that.staticFileExcludes)
743 : that.staticFileExcludes != null) {
744 return false;
746 if (staticFileIncludes != null ? !staticFileIncludes.equals(that.staticFileIncludes)
747 : that.staticFileIncludes != null) {
748 return false;
750 if (staticIncludePattern != null ? !staticIncludePattern.equals(that.staticIncludePattern)
751 : that.staticIncludePattern != null) {
752 return false;
754 if (systemProperties != null ? !systemProperties.equals(that.systemProperties)
755 : that.systemProperties != null) {
756 return false;
758 if (betaSettings != null ? !betaSettings.equals(that.betaSettings) : that.betaSettings != null) {
759 return false;
761 if (healthCheck != null ? !healthCheck.equals(that.healthCheck)
762 : that.healthCheck != null) {
763 return false;
765 if (resources != null ? !resources.equals(that.resources) : that.resources != null) {
766 return false;
768 if (network != null ? !network.equals(that.network) : that.network != null) {
769 return false;
771 if (userPermissions != null ? !userPermissions.equals(that.userPermissions)
772 : that.userPermissions != null) {
773 return false;
775 if (apiConfig != null ? !apiConfig.equals(that.apiConfig)
776 : that.apiConfig != null) {
777 return false;
779 if (apiEndpointIds != null ? !apiEndpointIds.equals(that.apiEndpointIds)
780 : that.apiEndpointIds != null) {
781 return false;
783 if (pagespeed != null ? !pagespeed.equals(that.pagespeed) : that.pagespeed != null) {
784 return false;
786 if (classLoaderConfig != null ? !classLoaderConfig.equals(that.classLoaderConfig) :
787 that.classLoaderConfig != null) {
788 return false;
790 if (urlStreamHandlerType != null ? !urlStreamHandlerType.equals(that.urlStreamHandlerType) :
791 that.urlStreamHandlerType != null) {
792 return false;
794 if (useGoogleConnectorJ != that.useGoogleConnectorJ) {
795 return false;
798 return true;
801 @Override
802 public int hashCode() {
803 int result = systemProperties != null ? systemProperties.hashCode() : 0;
804 result = 31 * result + (envVariables != null ? envVariables.hashCode() : 0);
805 result = 31 * result + (userPermissions != null ? userPermissions.hashCode() : 0);
806 result = 31 * result + (appId != null ? appId.hashCode() : 0);
807 result = 31 * result + (majorVersionId != null ? majorVersionId.hashCode() : 0);
808 result = 31 * result + (sourceLanguage != null ? sourceLanguage.hashCode() : 0);
809 result = 31 * result + (service != null ? service.hashCode() : 0);
810 result = 31 * result + (instanceClass != null ? instanceClass.hashCode() : 0);
811 result = 31 * result + automaticScaling.hashCode();
812 result = 31 * result + manualScaling.hashCode();
813 result = 31 * result + basicScaling.hashCode();
814 result = 31 * result + (sslEnabled ? 1 : 0);
815 result = 31 * result + (useSessions ? 1 : 0);
816 result = 31 * result + (asyncSessionPersistence ? 1 : 0);
817 result =
818 31 * result + (asyncSessionPersistenceQueueName != null ? asyncSessionPersistenceQueueName
819 .hashCode() : 0);
820 result = 31 * result + (staticFileIncludes != null ? staticFileIncludes.hashCode() : 0);
821 result = 31 * result + (staticFileExcludes != null ? staticFileExcludes.hashCode() : 0);
822 result = 31 * result + (resourceFileIncludes != null ? resourceFileIncludes.hashCode() : 0);
823 result = 31 * result + (resourceFileExcludes != null ? resourceFileExcludes.hashCode() : 0);
824 result = 31 * result + (staticIncludePattern != null ? staticIncludePattern.hashCode() : 0);
825 result = 31 * result + (staticExcludePattern != null ? staticExcludePattern.hashCode() : 0);
826 result = 31 * result + (resourceIncludePattern != null ? resourceIncludePattern.hashCode() : 0);
827 result = 31 * result + (resourceExcludePattern != null ? resourceExcludePattern.hashCode() : 0);
828 result = 31 * result + (publicRoot != null ? publicRoot.hashCode() : 0);
829 result = 31 * result + (appRoot != null ? appRoot.hashCode() : 0);
830 result = 31 * result + (inboundServices != null ? inboundServices.hashCode() : 0);
831 result = 31 * result + (precompilationEnabled ? 1 : 0);
832 result = 31 * result + (adminConsolePages != null ? adminConsolePages.hashCode() : 0);
833 result = 31 * result + (errorHandlers != null ? errorHandlers.hashCode() : 0);
834 result = 31 * result + (threadsafe ? 1 : 0);
835 result = 31 * result + (autoIdPolicy != null ? autoIdPolicy.hashCode() : 0);
836 result = 31 * result + (threadsafeValueProvided ? 1 : 0);
837 result = 31 * result + (codeLock ? 1 : 0);
838 result = 31 * result + (apiConfig != null ? apiConfig.hashCode() : 0);
839 result = 31 * result + (apiEndpointIds != null ? apiEndpointIds.hashCode() : 0);
840 result = 31 * result + (pagespeed != null ? pagespeed.hashCode() : 0);
841 result = 31 * result + (classLoaderConfig != null ? classLoaderConfig.hashCode() : 0);
842 result = 31 * result + (urlStreamHandlerType != null ? urlStreamHandlerType.hashCode() : 0);
843 result = 31 * result + (useGoogleConnectorJ.hashCode());
844 result = 31 * result + (betaSettings != null ? betaSettings.hashCode() : 0);
845 result = 31 * result + (healthCheck != null ? healthCheck.hashCode() : 0);
846 result = 31 * result + (resources != null ? resources.hashCode() : 0);
847 result = 31 * result + (network != null ? network.hashCode() : 0);
848 return result;
851 public boolean includesResource(String path) {
852 if (resourceIncludePattern == null) {
853 if (resourceFileIncludes.size() == 0) {
854 resourceIncludePattern = Pattern.compile(".*");
855 } else {
856 resourceIncludePattern = Pattern.compile(makeRegexp(resourceFileIncludes));
859 if (resourceExcludePattern == null && resourceFileExcludes.size() > 0) {
860 resourceExcludePattern = Pattern.compile(makeRegexp(resourceFileExcludes));
861 } else {
863 return includes(path, resourceIncludePattern, resourceExcludePattern);
866 public boolean includesStatic(String path) {
867 if (staticIncludePattern == null) {
868 if (staticFileIncludes.size() == 0) {
869 String staticRoot;
870 if (publicRoot.length() > 0) {
871 staticRoot = publicRoot + "/**";
872 } else {
873 staticRoot = "**";
875 staticIncludePattern = Pattern.compile(
876 makeRegexp(Collections.singletonList(staticRoot)));
877 } else {
878 List<String> patterns = new ArrayList<String>();
879 for (StaticFileInclude include : staticFileIncludes) {
880 patterns.add(include.getPattern());
882 staticIncludePattern = Pattern.compile(makeRegexp(patterns));
885 if (staticExcludePattern == null && staticFileExcludes.size() > 0) {
886 staticExcludePattern = Pattern.compile(makeRegexp(staticFileExcludes));
887 } else {
889 return includes(path, staticIncludePattern, staticExcludePattern);
893 * Tests whether {@code path} is covered by the pattern {@code includes}
894 * while not being blocked by matching {@code excludes}.
896 * @param path a URL to test
897 * @param includes a non-{@code null} pattern for included URLs
898 * @param excludes a pattern for exclusion, or {@code null} to not exclude
899 * anything from the {@code includes} set.
901 public boolean includes(String path, Pattern includes, Pattern excludes) {
902 assert(includes != null);
903 if (!includes.matcher(path).matches()) {
904 return false;
906 if (excludes != null && excludes.matcher(path).matches()) {
907 return false;
909 return true;
912 public String makeRegexp(List<String> patterns) {
913 StringBuilder builder = new StringBuilder();
914 boolean first = true;
915 for (String item : patterns) {
916 if (first) {
917 first = false;
918 } else {
919 builder.append('|');
922 while (item.charAt(0) == '/') {
923 item = item.substring(1);
926 builder.append('(');
927 if (appRoot != null) {
928 builder.append(makeFileRegex(appRoot));
930 builder.append("/");
931 builder.append(makeFileRegex(item));
932 builder.append(')');
934 return builder.toString();
938 * Helper method to translate from appengine-web.xml "file globs" to
939 * proper regular expressions as used in app.yaml.
941 * @param fileGlob the glob to translate
942 * @return the regular expression string matching the input {@code file} pattern.
944 static String makeFileRegex(String fileGlob) {
945 fileGlob = fileGlob.replaceAll("([^A-Za-z0-9\\-_/])", "\\\\$1");
946 fileGlob = fileGlob.replaceAll("\\\\\\*\\\\\\*", ".*");
947 fileGlob = fileGlob.replaceAll("\\\\\\*", "[^/]*");
948 return fileGlob;
951 * Sets the application root directory, as a prefix for the regexps in
952 * {@link #includeResourcePattern(String)} and friends. This is needed
953 * because we want to match complete filenames relative to root.
955 * @param appRoot
957 public void setSourcePrefix(String appRoot) {
958 this.appRoot = appRoot;
959 this.resourceIncludePattern = null;
960 this.resourceExcludePattern = null;
961 this.staticIncludePattern = null;
962 this.staticExcludePattern = null;
965 public String getSourcePrefix() {
966 return this.appRoot;
969 private static String toNullIfEmptyOrWhitespace(String string) {
970 if (string == null || CharMatcher.WHITESPACE.matchesAllOf(string)) {
971 return null;
973 return string;
977 * Represents a {@link java.security.Permission} that needs to be
978 * granted to user code.
980 private static class UserPermission {
981 private final String className;
982 private final String name;
983 private final String actions;
985 private boolean hasHashCode = false;
986 private int hashCode;
988 public UserPermission(String className, String name, String actions) {
989 this.className = className;
990 this.name = name;
991 this.actions = actions;
994 public String getClassName() {
995 return className;
998 public String getName() {
999 return name;
1002 public String getActions() {
1003 return actions;
1006 @Override
1007 public int hashCode() {
1008 if (hasHashCode) {
1009 return hashCode;
1012 int hash = className.hashCode();
1013 hash = 31 * hash + name.hashCode();
1014 if (actions != null) {
1015 hash = 31 * hash + actions.hashCode();
1018 hashCode = hash;
1019 hasHashCode = true;
1020 return hashCode;
1023 @Override
1024 public boolean equals(Object obj) {
1025 if (obj instanceof UserPermission) {
1026 UserPermission perm = (UserPermission) obj;
1027 if (className.equals(perm.className) && name.equals(perm.name)) {
1028 if (actions == null ? perm.actions == null : actions.equals(perm.actions)) {
1029 return true;
1033 return false;
1038 * Represents an &lt;include&gt; element within the
1039 * &lt;static-files&gt; element. Currently this includes both a
1040 * pattern and an optional expiration time specification.
1042 public static class StaticFileInclude {
1043 private final String pattern;
1044 private final String expiration;
1045 private final Map<String, String> httpHeaders;
1047 public StaticFileInclude(String pattern, String expiration) {
1048 this.pattern = pattern;
1049 this.expiration = expiration;
1050 this.httpHeaders = new LinkedHashMap<>();
1053 public String getPattern() {
1054 return pattern;
1057 public Pattern getRegularExpression() {
1058 return Pattern.compile(makeFileRegex(pattern));
1061 public String getExpiration() {
1062 return expiration;
1065 public Map<String, String> getHttpHeaders() {
1066 return httpHeaders;
1069 @Override
1070 public int hashCode() {
1071 return Objects.hash(pattern, expiration, httpHeaders);
1074 @Override
1075 public boolean equals(Object obj) {
1076 if (!(obj instanceof StaticFileInclude)) {
1077 return false;
1080 StaticFileInclude other = (StaticFileInclude) obj;
1082 if (pattern != null) {
1083 if (!pattern.equals(other.pattern)) {
1084 return false;
1086 } else {
1087 if (other.pattern != null) {
1088 return false;
1092 if (expiration != null) {
1093 if (!expiration.equals(other.expiration)) {
1094 return false;
1096 } else {
1097 if (other.expiration != null) {
1098 return false;
1102 if (httpHeaders != null) {
1103 if (!httpHeaders.equals(other.httpHeaders)) {
1104 return false;
1106 } else {
1107 if (other.httpHeaders != null) {
1108 return false;
1112 return true;
1116 public static class AdminConsolePage {
1117 private final String name;
1118 private final String url;
1120 public AdminConsolePage(String name, String url) {
1121 this.name = name;
1122 this.url = url;
1125 public String getName() {
1126 return name;
1129 public String getUrl() {
1130 return url;
1133 @Override
1134 public int hashCode() {
1135 final int prime = 31;
1136 int result = 1;
1137 result = prime * result + ((name == null) ? 0 : name.hashCode());
1138 result = prime * result + ((url == null) ? 0 : url.hashCode());
1139 return result;
1142 @Override
1143 public boolean equals(Object obj) {
1144 if (this == obj) return true;
1145 if (obj == null) return false;
1146 if (getClass() != obj.getClass()) return false;
1147 AdminConsolePage other = (AdminConsolePage) obj;
1148 if (name == null) {
1149 if (other.name != null) return false;
1150 } else if (!name.equals(other.name)) return false;
1151 if (url == null) {
1152 if (other.url != null) return false;
1153 } else if (!url.equals(other.url)) return false;
1154 return true;
1159 * Represents an &lt;error-handler&gt; element. Currently this includes both
1160 * a file name and an optional error code.
1162 public static class ErrorHandler {
1163 private final String file;
1164 private final String errorCode;
1166 public ErrorHandler(String file, String errorCode) {
1167 this.file = file;
1168 this.errorCode = errorCode;
1171 public String getFile() {
1172 return file;
1175 public String getErrorCode() {
1176 return errorCode;
1179 @Override
1180 public int hashCode() {
1181 final int prime = 31;
1182 int result = 1;
1183 result = prime * result + ((file == null) ? 0 : file.hashCode());
1184 result = prime * result +
1185 ((errorCode == null) ? 0 : errorCode.hashCode());
1186 return result;
1189 @Override
1190 public boolean equals(Object obj) {
1191 if (!(obj instanceof ErrorHandler)) {
1192 return false;
1195 ErrorHandler handler = (ErrorHandler) obj;
1196 if (!file.equals(handler.file)) {
1197 return false;
1200 if (errorCode == null) {
1201 if (handler.errorCode != null) {
1202 return false;
1204 } else {
1205 if (!errorCode.equals(handler.errorCode)) {
1206 return false;
1210 return true;
1215 * Represents an &lt;api-config&gt; element. This is a singleton specifying
1216 * url-pattern and servlet-class for the api config server.
1218 public static class ApiConfig {
1219 private final String servletClass;
1220 private final String url;
1222 public ApiConfig(String servletClass, String url) {
1223 this.servletClass = servletClass;
1224 this.url = url;
1227 public String getservletClass() {
1228 return servletClass;
1231 public String getUrl() {
1232 return url;
1235 @Override
1236 public int hashCode() {
1237 final int prime = 31;
1238 int result = 1;
1239 result = prime * result + ((servletClass == null) ? 0 : servletClass.hashCode());
1240 result = prime * result + ((url == null) ? 0 : url.hashCode());
1241 return result;
1244 @Override
1245 public boolean equals(Object obj) {
1246 if (this == obj) { return true; }
1247 if (obj == null) { return false; }
1248 if (getClass() != obj.getClass()) { return false; }
1249 ApiConfig other = (ApiConfig) obj;
1250 if (servletClass == null) {
1251 if (other.servletClass != null) { return false; }
1252 } else if (!servletClass.equals(other.servletClass)) { return false; }
1253 if (url == null) {
1254 if (other.url != null) { return false; }
1255 } else if (!url.equals(other.url)) { return false; }
1256 return true;
1259 @Override
1260 public String toString() {
1261 return "ApiConfig{servletClass=\"" + servletClass + "\", url=\"" + url + "\"}";
1266 * Holder for automatic settings.
1268 public static class AutomaticScaling {
1269 private static final AutomaticScaling EMPTY_SETTINGS = new AutomaticScaling();
1271 public static final String AUTOMATIC = "automatic";
1272 private String minPendingLatency;
1273 private String maxPendingLatency;
1274 private String minIdleInstances;
1275 private String maxIdleInstances;
1276 private String maxConcurrentRequests;
1278 private Integer minNumInstances;
1279 private Integer maxNumInstances;
1280 private Integer coolDownPeriodSec;
1281 private CpuUtilization cpuUtilization;
1283 private Integer targetNetworkSentBytesPerSec;
1284 private Integer targetNetworkSentPacketsPerSec;
1285 private Integer targetNetworkReceivedBytesPerSec;
1286 private Integer targetNetworkReceivedPacketsPerSec;
1287 private Integer targetDiskWriteBytesPerSec;
1288 private Integer targetDiskWriteOpsPerSec;
1289 private Integer targetDiskReadBytesPerSec;
1290 private Integer targetDiskReadOpsPerSec;
1291 private Integer targetRequestCountPerSec;
1292 private Integer targetConcurrentRequests;
1294 public String getMinPendingLatency() {
1295 return minPendingLatency;
1299 * Sets minPendingLatency. Normalizes empty and null inputs to null.
1301 public void setMinPendingLatency(String minPendingLatency) {
1302 this.minPendingLatency = toNullIfEmptyOrWhitespace(minPendingLatency);
1305 public String getMaxPendingLatency() {
1306 return maxPendingLatency;
1310 * Sets maxPendingLatency. Normalizes empty and null inputs to null.
1312 public void setMaxPendingLatency(String maxPendingLatency) {
1313 this.maxPendingLatency = toNullIfEmptyOrWhitespace(maxPendingLatency);
1316 public String getMinIdleInstances() {
1317 return minIdleInstances;
1321 * Sets minIdleInstances. Normalizes empty and null inputs to null.
1323 public void setMinIdleInstances(String minIdleInstances) {
1324 this.minIdleInstances = toNullIfEmptyOrWhitespace(minIdleInstances);
1327 public String getMaxIdleInstances() {
1328 return maxIdleInstances;
1332 * Sets maxIdleInstances. Normalizes empty and null inputs to null.
1334 public void setMaxIdleInstances(String maxIdleInstances) {
1335 this.maxIdleInstances = toNullIfEmptyOrWhitespace(maxIdleInstances);
1338 public boolean isEmpty() {
1339 return this.equals(EMPTY_SETTINGS);
1342 public String getMaxConcurrentRequests() {
1343 return maxConcurrentRequests;
1347 * Sets maxConcurrentRequests. Normalizes empty and null inputs to null.
1349 public void setMaxConcurrentRequests(String maxConcurrentRequests) {
1350 this.maxConcurrentRequests = toNullIfEmptyOrWhitespace(maxConcurrentRequests);
1353 public Integer getMinNumInstances() {
1354 return minNumInstances;
1357 public void setMinNumInstances(Integer minNumInstances) {
1358 this.minNumInstances = minNumInstances;
1361 public Integer getMaxNumInstances() {
1362 return maxNumInstances;
1365 public void setMaxNumInstances(Integer maxNumInstances) {
1366 this.maxNumInstances = maxNumInstances;
1369 public Integer getCoolDownPeriodSec() {
1370 return coolDownPeriodSec;
1373 public void setCoolDownPeriodSec(Integer coolDownPeriodSec) {
1374 this.coolDownPeriodSec = coolDownPeriodSec;
1377 public CpuUtilization getCpuUtilization() {
1378 return cpuUtilization;
1381 public void setCpuUtilization(CpuUtilization cpuUtilization) {
1382 this.cpuUtilization = cpuUtilization;
1385 public Integer getTargetNetworkSentBytesPerSec() {
1386 return targetNetworkSentBytesPerSec;
1389 public void setTargetNetworkSentBytesPerSec(Integer targetNetworkSentBytesPerSec) {
1390 this.targetNetworkSentBytesPerSec = targetNetworkSentBytesPerSec;
1393 public Integer getTargetNetworkSentPacketsPerSec() {
1394 return targetNetworkSentPacketsPerSec;
1397 public void setTargetNetworkSentPacketsPerSec(Integer targetNetworkSentPacketsPerSec) {
1398 this.targetNetworkSentPacketsPerSec = targetNetworkSentPacketsPerSec;
1401 public Integer getTargetNetworkReceivedBytesPerSec() {
1402 return targetNetworkReceivedBytesPerSec;
1405 public void setTargetNetworkReceivedBytesPerSec(Integer targetNetworkReceivedBytesPerSec) {
1406 this.targetNetworkReceivedBytesPerSec = targetNetworkReceivedBytesPerSec;
1409 public Integer getTargetNetworkReceivedPacketsPerSec() {
1410 return targetNetworkReceivedPacketsPerSec;
1413 public void setTargetNetworkReceivedPacketsPerSec(Integer targetNetworkReceivedPacketsPerSec) {
1414 this.targetNetworkReceivedPacketsPerSec = targetNetworkReceivedPacketsPerSec;
1417 public Integer getTargetDiskWriteBytesPerSec() {
1418 return targetDiskWriteBytesPerSec;
1421 public void setTargetDiskWriteBytesPerSec(Integer targetDiskWriteBytesPerSec) {
1422 this.targetDiskWriteBytesPerSec = targetDiskWriteBytesPerSec;
1425 public Integer getTargetDiskWriteOpsPerSec() {
1426 return targetDiskWriteOpsPerSec;
1429 public void setTargetDiskWriteOpsPerSec(Integer targetDiskWriteOpsPerSec) {
1430 this.targetDiskWriteOpsPerSec = targetDiskWriteOpsPerSec;
1433 public Integer getTargetDiskReadBytesPerSec() {
1434 return targetDiskReadBytesPerSec;
1437 public void setTargetDiskReadBytesPerSec(Integer targetDiskReadBytesPerSec) {
1438 this.targetDiskReadBytesPerSec = targetDiskReadBytesPerSec;
1441 public Integer getTargetDiskReadOpsPerSec() {
1442 return targetDiskReadOpsPerSec;
1445 public void setTargetDiskReadOpsPerSec(Integer targetDiskReadOpsPerSec) {
1446 this.targetDiskReadOpsPerSec = targetDiskReadOpsPerSec;
1449 public Integer getTargetRequestCountPerSec() {
1450 return targetRequestCountPerSec;
1453 public void setTargetRequestCountPerSec(Integer targetRequestCountPerSec) {
1454 this.targetRequestCountPerSec = targetRequestCountPerSec;
1457 public Integer getTargetConcurrentRequests() {
1458 return targetConcurrentRequests;
1461 public void setTargetConcurrentRequests(Integer targetConcurrentRequests) {
1462 this.targetConcurrentRequests = targetConcurrentRequests;
1465 @Override
1466 public int hashCode() {
1467 return Objects.hash(maxPendingLatency, minPendingLatency, maxIdleInstances,
1468 minIdleInstances, maxConcurrentRequests, minNumInstances,
1469 maxNumInstances, coolDownPeriodSec, cpuUtilization,
1470 targetNetworkSentBytesPerSec, targetNetworkSentPacketsPerSec,
1471 targetNetworkReceivedBytesPerSec, targetNetworkReceivedPacketsPerSec,
1472 targetDiskWriteBytesPerSec, targetDiskWriteOpsPerSec,
1473 targetDiskReadBytesPerSec, targetDiskReadOpsPerSec,
1474 targetRequestCountPerSec, targetConcurrentRequests);
1477 @Override
1478 public boolean equals(Object obj) {
1479 if (this == obj) {
1480 return true;
1482 if (obj == null) {
1483 return false;
1485 if (getClass() != obj.getClass()) {
1486 return false;
1488 AutomaticScaling other = (AutomaticScaling) obj;
1489 return Objects.equals(maxPendingLatency, other.maxPendingLatency)
1490 && Objects.equals(minPendingLatency, other.minPendingLatency)
1491 && Objects.equals(maxIdleInstances, other.maxIdleInstances)
1492 && Objects.equals(minIdleInstances, other.minIdleInstances)
1493 && Objects.equals(maxConcurrentRequests, other.maxConcurrentRequests)
1494 && Objects.equals(minNumInstances, other.minNumInstances)
1495 && Objects.equals(maxNumInstances, other.maxNumInstances)
1496 && Objects.equals(coolDownPeriodSec, other.coolDownPeriodSec)
1497 && Objects.equals(cpuUtilization, other.cpuUtilization)
1498 && Objects.equals(targetNetworkSentBytesPerSec, other.targetNetworkSentBytesPerSec)
1499 && Objects.equals(targetNetworkSentPacketsPerSec, other.targetNetworkSentPacketsPerSec)
1500 && Objects.equals(targetNetworkReceivedBytesPerSec,
1501 other.targetNetworkReceivedBytesPerSec)
1502 && Objects.equals(targetNetworkReceivedPacketsPerSec,
1503 other.targetNetworkReceivedPacketsPerSec)
1504 && Objects.equals(targetDiskWriteBytesPerSec, other.targetDiskWriteBytesPerSec)
1505 && Objects.equals(targetDiskWriteOpsPerSec, other.targetDiskWriteOpsPerSec)
1506 && Objects.equals(targetDiskReadBytesPerSec, other.targetDiskReadBytesPerSec)
1507 && Objects.equals(targetDiskReadOpsPerSec, other.targetDiskReadOpsPerSec)
1508 && Objects.equals(targetRequestCountPerSec, other.targetRequestCountPerSec)
1509 && Objects.equals(targetConcurrentRequests, other.targetConcurrentRequests);
1512 @Override
1513 public String toString() {
1514 return "AutomaticScaling [minPendingLatency=" + minPendingLatency
1515 + ", maxPendingLatency=" + maxPendingLatency
1516 + ", minIdleInstances=" + minIdleInstances
1517 + ", maxIdleInstances=" + maxIdleInstances
1518 + ", maxConcurrentRequests=" + maxConcurrentRequests
1519 + ", minNumInstances=" + minNumInstances
1520 + ", maxNumInstances=" + maxNumInstances
1521 + ", coolDownPeriodSec=" + coolDownPeriodSec
1522 + ", cpuUtilization=" + cpuUtilization
1523 + ", targetNetworkSentBytesPerSec=" + targetNetworkSentBytesPerSec
1524 + ", targetNetworkSentPacketsPerSec=" + targetNetworkSentPacketsPerSec
1525 + ", targetNetworkReceivedBytesPerSec=" + targetNetworkReceivedBytesPerSec
1526 + ", targetNetworkReceivedPacketsPerSec=" + targetNetworkReceivedPacketsPerSec
1527 + ", targetDiskWriteBytesPerSec=" + targetDiskWriteBytesPerSec
1528 + ", targetDiskWriteOpsPerSec=" + targetDiskWriteOpsPerSec
1529 + ", targetDiskReadBytesPerSec=" + targetDiskReadBytesPerSec
1530 + ", targetDiskReadOpsPerSec=" + targetDiskReadOpsPerSec
1531 + ", targetRequestCountPerSec=" + targetRequestCountPerSec
1532 + ", targetConcurrentRequests=" + targetConcurrentRequests
1533 + "]";
1538 * Holder for CPU utilization.
1540 public static class CpuUtilization {
1541 private static final CpuUtilization EMPTY_SETTINGS = new CpuUtilization();
1542 private Double targetUtilization;
1543 private Integer aggregationWindowLengthSec;
1545 public Double getTargetUtilization() {
1546 return targetUtilization;
1549 public void setTargetUtilization(Double targetUtilization) {
1550 this.targetUtilization = targetUtilization;
1553 public Integer getAggregationWindowLengthSec() {
1554 return aggregationWindowLengthSec;
1557 public void setAggregationWindowLengthSec(Integer aggregationWindowLengthSec) {
1558 this.aggregationWindowLengthSec = aggregationWindowLengthSec;
1561 public boolean isEmpty() {
1562 return this.equals(EMPTY_SETTINGS);
1565 @Override
1566 public int hashCode() {
1567 return Objects.hash(targetUtilization, aggregationWindowLengthSec);
1570 @Override
1571 public boolean equals(Object obj) {
1572 if (this == obj) {
1573 return true;
1575 if (obj == null) {
1576 return false;
1578 if (getClass() != obj.getClass()) {
1579 return false;
1581 CpuUtilization other = (CpuUtilization) obj;
1582 return Objects.equals(targetUtilization, other.targetUtilization)
1583 && Objects.equals(aggregationWindowLengthSec, other.aggregationWindowLengthSec);
1586 @Override
1587 public String toString() {
1588 return "CpuUtilization [targetUtilization=" + targetUtilization
1589 + ", aggregationWindowLengthSec=" + aggregationWindowLengthSec + "]";
1594 * Holder for health check.
1596 public static class HealthCheck {
1597 private static final HealthCheck EMPTY_SETTINGS = new HealthCheck();
1599 private boolean enableHealthCheck = true;
1600 private Integer checkIntervalSec;
1601 private Integer timeoutSec;
1602 private Integer unhealthyThreshold;
1603 private Integer healthyThreshold;
1604 private Integer restartThreshold;
1605 private String host;
1607 public boolean getEnableHealthCheck() {
1608 return enableHealthCheck;
1611 * Sets enableHealthCheck.
1613 public void setEnableHealthCheck(boolean enableHealthCheck) {
1614 this.enableHealthCheck = enableHealthCheck;
1617 public Integer getCheckIntervalSec() {
1618 return checkIntervalSec;
1621 * Sets checkIntervalSec.
1623 public void setCheckIntervalSec(Integer checkIntervalSec) {
1624 this.checkIntervalSec = checkIntervalSec;
1627 public Integer getTimeoutSec() {
1628 return timeoutSec;
1631 * Sets timeoutSec.
1633 public void setTimeoutSec(Integer timeoutSec) {
1634 this.timeoutSec = timeoutSec;
1637 public Integer getUnhealthyThreshold() {
1638 return unhealthyThreshold;
1642 * Sets unhealthyThreshold.
1644 public void setUnhealthyThreshold(Integer unhealthyThreshold) {
1645 this.unhealthyThreshold = unhealthyThreshold;
1648 public Integer getHealthyThreshold() {
1649 return healthyThreshold;
1653 * Sets healthyThreshold.
1656 public void setHealthyThreshold(Integer healthyThreshold) {
1657 this.healthyThreshold = healthyThreshold;
1660 public Integer getRestartThreshold() {
1661 return restartThreshold;
1665 * Sets restartThreshold.
1667 public void setRestartThreshold(Integer restartThreshold) {
1668 this.restartThreshold = restartThreshold;
1671 public String getHost() {
1672 return host;
1676 * Sets host. Normalizes empty and null inputs to null.
1678 public void setHost(String host) {
1679 this.host = toNullIfEmptyOrWhitespace(host);
1682 public boolean isEmpty() {
1683 return this.equals(EMPTY_SETTINGS);
1686 @Override
1687 public int hashCode() {
1688 return Objects.hash(enableHealthCheck, checkIntervalSec, timeoutSec, unhealthyThreshold,
1689 healthyThreshold, restartThreshold, host);
1692 @Override
1693 public boolean equals(Object obj) {
1694 if (this == obj) {
1695 return true;
1697 if (obj == null) {
1698 return false;
1700 if (getClass() != obj.getClass()) {
1701 return false;
1703 HealthCheck other = (HealthCheck) obj;
1704 return Objects.equals(enableHealthCheck, other.enableHealthCheck)
1705 && Objects.equals(checkIntervalSec, other.checkIntervalSec)
1706 && Objects.equals(timeoutSec, other.timeoutSec)
1707 && Objects.equals(unhealthyThreshold, other.unhealthyThreshold)
1708 && Objects.equals(healthyThreshold, other.healthyThreshold)
1709 && Objects.equals(restartThreshold, other.restartThreshold)
1710 && Objects.equals(host, other.host);
1713 @Override
1714 public String toString() {
1715 return "HealthCheck [enableHealthCheck=" + enableHealthCheck
1716 + ", checkIntervalSec=" + checkIntervalSec
1717 + ", timeoutSec=" + timeoutSec
1718 + ", unhealthyThreshold=" + unhealthyThreshold
1719 + ", healthyThreshold=" + healthyThreshold
1720 + ", restartThreshold=" + restartThreshold
1721 + ", host=" + host + "]";
1726 * Holder for Resources
1728 public static class Resources {
1729 private static final Resources EMPTY_SETTINGS = new Resources();
1731 private double cpu;
1733 public double getCpu() {
1734 return cpu;
1737 public void setCpu(double cpu) {
1738 this.cpu = cpu;
1741 private double memory_gb;
1743 public double getMemoryGb() {
1744 return memory_gb;
1747 public void setMemoryGb(double memory_gb) {
1748 this.memory_gb = memory_gb;
1751 private int disk_size_gb;
1753 public int getDiskSizeGb() {
1754 return disk_size_gb;
1757 public void setDiskSizeGb(int disk_size_gb) {
1758 this.disk_size_gb = disk_size_gb;
1761 public boolean isEmpty() {
1762 return this.equals(EMPTY_SETTINGS);
1765 @Override
1766 public int hashCode() {
1767 return Objects.hash(cpu, memory_gb, disk_size_gb);
1770 @Override
1771 public boolean equals(Object obj) {
1772 if (this == obj) {
1773 return true;
1775 if (obj == null) {
1776 return false;
1778 if (getClass() != obj.getClass()) {
1779 return false;
1781 Resources other = (Resources) obj;
1782 return Objects.equals(cpu, other.cpu) &&
1783 Objects.equals(memory_gb, other.memory_gb) &&
1784 Objects.equals(disk_size_gb, other.disk_size_gb);
1787 @Override
1788 public String toString() {
1789 return "Resources [" + "cpu=" + cpu +
1790 ", memory_gb=" + memory_gb +
1791 ", disk_size_gb=" + disk_size_gb + "]";
1796 * Holder for network.
1798 public static class Network {
1799 private static final Network EMPTY_SETTINGS = new Network();
1801 private String instanceTag;
1803 public String getInstanceTag() {
1804 return instanceTag;
1807 public void setInstanceTag(String instanceTag) {
1808 this.instanceTag = instanceTag;
1811 private final List<String> forwardedPorts = Lists.newArrayList();
1813 public List<String> getForwardedPorts() {
1814 return Collections.unmodifiableList(forwardedPorts);
1817 public void addForwardedPort(String forwardedPort) {
1818 forwardedPorts.add(forwardedPort);
1821 private String name;
1823 public String getName() {
1824 return name;
1827 public void setName(String name) {
1828 this.name = name;
1831 public boolean isEmpty() {
1832 return this.equals(EMPTY_SETTINGS);
1835 @Override
1836 public int hashCode() {
1837 return Objects.hash(forwardedPorts, instanceTag);
1840 @Override
1841 public boolean equals(Object obj) {
1842 if (this == obj) {
1843 return true;
1845 if (obj == null) {
1846 return false;
1848 if (getClass() != obj.getClass()) {
1849 return false;
1851 Network other = (Network) obj;
1852 return Objects.equals(forwardedPorts, other.forwardedPorts)
1853 && Objects.equals(instanceTag, other.instanceTag);
1856 @Override
1857 public String toString() {
1858 return "Network [forwardedPorts=" + forwardedPorts + ", instanceTag=" + instanceTag + "]";
1863 * Holder for manual settings.
1865 public static class ManualScaling {
1866 private static final ManualScaling EMPTY_SETTINGS = new ManualScaling();
1868 private String instances;
1870 public String getInstances() {
1871 return instances;
1875 * Sets instances. Normalizes empty and null inputs to null.
1877 public void setInstances(String instances) {
1878 this.instances = toNullIfEmptyOrWhitespace(instances);
1881 public boolean isEmpty() {
1882 return this.equals(EMPTY_SETTINGS);
1885 @Override
1886 public int hashCode() {
1887 return Objects.hash(instances);
1890 @Override
1891 public boolean equals(Object obj) {
1892 if (this == obj) {
1893 return true;
1895 if (obj == null) {
1896 return false;
1898 if (getClass() != obj.getClass()) {
1899 return false;
1901 ManualScaling other = (ManualScaling) obj;
1902 return Objects.equals(instances, other.instances);
1905 @Override
1906 public String toString() {
1907 return "ManualScaling [" + "instances=" + instances + "]";
1912 * Holder for basic settings.
1914 public static class BasicScaling {
1915 private static final BasicScaling EMPTY_SETTINGS = new BasicScaling();
1917 private String maxInstances;
1918 private String idleTimeout;
1920 public String getMaxInstances() {
1921 return maxInstances;
1924 public String getIdleTimeout() {
1925 return idleTimeout;
1929 * Sets maxInstances. Normalizes empty and null inputs to null.
1931 public void setMaxInstances(String maxInstances) {
1932 this.maxInstances = toNullIfEmptyOrWhitespace(maxInstances);
1936 * Sets idleTimeout. Normalizes empty and null inputs to null.
1938 public void setIdleTimeout(String idleTimeout) {
1939 this.idleTimeout = toNullIfEmptyOrWhitespace(idleTimeout);
1942 public boolean isEmpty() {
1943 return this.equals(EMPTY_SETTINGS);
1946 @Override
1947 public int hashCode() {
1948 return Objects.hash(maxInstances, idleTimeout);
1951 @Override
1952 public boolean equals(Object obj) {
1953 if (this == obj) {
1954 return true;
1956 if (obj == null) {
1957 return false;
1959 if (getClass() != obj.getClass()) {
1960 return false;
1962 BasicScaling other = (BasicScaling) obj;
1963 return Objects.equals(maxInstances, other.maxInstances)
1964 && Objects.equals(idleTimeout, other.idleTimeout);
1967 @Override
1968 public String toString() {
1969 return "BasicScaling [" + "maxInstances=" + maxInstances
1970 + ", idleTimeout=" + idleTimeout + "]";
1975 * Represents a &lt;pagespeed&gt; element. This is used to specify configuration for the Page
1976 * Speed Service, which can be used to automatically optimize the loading speed of app engine
1977 * sites.
1979 public static class Pagespeed {
1980 private final List<String> urlBlacklist = Lists.newArrayList();
1981 private final List<String> domainsToRewrite = Lists.newArrayList();
1982 private final List<String> enabledRewriters = Lists.newArrayList();
1983 private final List<String> disabledRewriters = Lists.newArrayList();
1985 public void addUrlBlacklist(String url) {
1986 urlBlacklist.add(url);
1989 public List<String> getUrlBlacklist() {
1990 return Collections.unmodifiableList(urlBlacklist);
1993 public void addDomainToRewrite(String domain) {
1994 domainsToRewrite.add(domain);
1997 public List<String> getDomainsToRewrite() {
1998 return Collections.unmodifiableList(domainsToRewrite);
2001 public void addEnabledRewriter(String rewriter) {
2002 enabledRewriters.add(rewriter);
2005 public List<String> getEnabledRewriters() {
2006 return Collections.unmodifiableList(enabledRewriters);
2009 public void addDisabledRewriter(String rewriter) {
2010 disabledRewriters.add(rewriter);
2013 public List<String> getDisabledRewriters() {
2014 return Collections.unmodifiableList(disabledRewriters);
2017 public boolean isEmpty() {
2018 return urlBlacklist.isEmpty() && domainsToRewrite.isEmpty() && enabledRewriters.isEmpty()
2019 && disabledRewriters.isEmpty();
2022 @Override
2023 public int hashCode() {
2024 return Objects.hash(urlBlacklist, domainsToRewrite, enabledRewriters, disabledRewriters);
2027 @Override
2028 public boolean equals(Object obj) {
2029 if (this == obj) {
2030 return true;
2032 if (obj == null) {
2033 return false;
2035 if (getClass() != obj.getClass()) {
2036 return false;
2038 Pagespeed other = (Pagespeed) obj;
2039 return Objects.equals(urlBlacklist, other.urlBlacklist)
2040 && Objects.equals(domainsToRewrite, other.domainsToRewrite)
2041 && Objects.equals(enabledRewriters, other.enabledRewriters)
2042 && Objects.equals(disabledRewriters, other.disabledRewriters);
2045 @Override
2046 public String toString() {
2047 return "Pagespeed [urlBlacklist=" + urlBlacklist + ", domainsToRewrite=" + domainsToRewrite
2048 + ", enabledRewriters=" + enabledRewriters + ", disabledRewriters=" + disabledRewriters
2049 + "]";
2053 public static class ClassLoaderConfig {
2054 private final List<PrioritySpecifierEntry> entries = Lists.newArrayList();
2056 public void add(PrioritySpecifierEntry entry) {
2057 entries.add(entry);
2060 public List<PrioritySpecifierEntry> getEntries() {
2061 return entries;
2064 @Override
2065 public int hashCode() {
2066 final int prime = 31;
2067 int result = 1;
2068 result = prime * result + ((entries == null) ? 0 : entries.hashCode());
2069 return result;
2072 @Override
2073 public boolean equals(Object obj) {
2074 if (this == obj) return true;
2075 if (obj == null) return false;
2076 if (getClass() != obj.getClass()) return false;
2077 ClassLoaderConfig other = (ClassLoaderConfig) obj;
2078 if (entries == null) {
2079 if (other.entries != null) return false;
2080 } else if (!entries.equals(other.entries)) return false;
2081 return true;
2084 @Override
2085 public String toString() {
2086 return "ClassLoaderConfig{entries=\"" + entries + "\"}";
2090 public static class PrioritySpecifierEntry {
2091 private String filename;
2092 private Double priority;
2094 private void checkNotAlreadySet() {
2095 if (filename != null) {
2096 throw new AppEngineConfigException("Found more that one file name matching tag. "
2097 + "Only one of 'filename' attribute allowed.");
2101 public String getFilename() {
2102 return filename;
2105 public void setFilename(String filename) {
2106 checkNotAlreadySet();
2107 this.filename = filename;
2110 public Double getPriority() {
2111 return priority;
2114 public double getPriorityValue() {
2115 if (priority == null) {
2116 return 1.0d;
2118 return priority;
2121 public void setPriority(String priority) {
2122 if (this.priority != null) {
2123 throw new AppEngineConfigException("The 'priority' tag may only be specified once.");
2126 if (priority == null) {
2127 this.priority = null;
2128 return;
2131 this.priority = Double.parseDouble(priority);
2134 public void checkClassLoaderConfig() {
2135 if (filename == null) {
2136 throw new AppEngineConfigException("Must have a filename attribute.");
2140 @Override
2141 public int hashCode() {
2142 final int prime = 31;
2143 int result = 1;
2144 result = prime * result + ((filename == null) ? 0 : filename.hashCode());
2145 result = prime * result + ((priority == null) ? 0 : priority.hashCode());
2146 return result;
2149 @Override
2150 public boolean equals(Object obj) {
2151 if (this == obj) return true;
2152 if (obj == null) return false;
2153 if (getClass() != obj.getClass()) return false;
2154 PrioritySpecifierEntry other = (PrioritySpecifierEntry) obj;
2155 if (filename == null) {
2156 if (other.filename != null) return false;
2157 } else if (!filename.equals(other.filename)) return false;
2158 if (priority == null) {
2159 if (other.priority != null) return false;
2160 } else if (!priority.equals(other.priority)) return false;
2161 return true;
2164 @Override
2165 public String toString() {
2166 return "PrioritySpecifierEntry{filename=\"" + filename + "\", priority=\"" + priority + "\"}";