PageRenderTime 23ms CodeModel.GetById 13ms RepoModel.GetById 1ms app.codeStats 0ms

/hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/webapp/WebApps.java

https://github.com/lalithsuresh/Scaling-HDFS-NameNode
Java | 221 lines | 149 code | 21 blank | 51 comment | 17 complexity | ac5ea1d9cfc7d80e723001e16ec27b12 MD5 | raw file
  1. /**
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. package org.apache.hadoop.yarn.webapp;
  19. import static com.google.common.base.Preconditions.*;
  20. import com.google.inject.AbstractModule;
  21. import com.google.inject.Guice;
  22. import com.google.inject.Injector;
  23. import com.google.inject.Module;
  24. import com.google.inject.servlet.GuiceFilter;
  25. import java.net.ConnectException;
  26. import java.net.URL;
  27. import org.apache.commons.lang.StringUtils;
  28. import org.apache.hadoop.conf.Configuration;
  29. import org.apache.hadoop.http.HttpServer;
  30. import org.slf4j.Logger;
  31. import org.slf4j.LoggerFactory;
  32. /**
  33. * Helpers to create an embedded webapp.
  34. *
  35. * <h4>Quick start:</h4>
  36. * <pre>
  37. * WebApp wa = WebApps.$for(myApp).start();</pre>
  38. * Starts a webapp with default routes binds to 0.0.0.0 (all network interfaces)
  39. * on an ephemeral port, which can be obtained with:<pre>
  40. * int port = wa.port();</pre>
  41. * <h4>With more options:</h4>
  42. * <pre>
  43. * WebApp wa = WebApps.$for(myApp).at(address, port).
  44. * with(configuration).
  45. * start(new WebApp() {
  46. * &#064;Override public void setup() {
  47. * route("/foo/action", FooController.class);
  48. * route("/foo/:id", FooController.class, "show");
  49. * }
  50. * });</pre>
  51. */
  52. public class WebApps {
  53. static final Logger LOG = LoggerFactory.getLogger(WebApps.class);
  54. public static class Builder<T> {
  55. final String name;
  56. final Class<T> api;
  57. final T application;
  58. String bindAddress = "0.0.0.0";
  59. int port = 0;
  60. boolean findPort = false;
  61. Configuration conf;
  62. boolean devMode = false;
  63. Module[] modules;
  64. Builder(String name, Class<T> api, T application) {
  65. this.name = name;
  66. this.api = api;
  67. this.application = application;
  68. }
  69. public Builder<T> at(String bindAddress) {
  70. String[] parts = StringUtils.split(bindAddress, ':');
  71. if (parts.length == 2) {
  72. return at(parts[0], Integer.parseInt(parts[1]), true);
  73. }
  74. return at(bindAddress, 0, true);
  75. }
  76. public Builder<T> at(int port) {
  77. return at("0.0.0.0", port, false);
  78. }
  79. public Builder<T> at(String address, int port, boolean findPort) {
  80. this.bindAddress = checkNotNull(address, "bind address");
  81. this.port = port;
  82. this.findPort = findPort;
  83. return this;
  84. }
  85. public Builder<T> with(Configuration conf) {
  86. this.conf = conf;
  87. return this;
  88. }
  89. public Builder<T> with(Module... modules) {
  90. this.modules = modules; // OK
  91. return this;
  92. }
  93. public Builder<T> inDevMode() {
  94. devMode = true;
  95. return this;
  96. }
  97. public WebApp start(WebApp webapp) {
  98. if (webapp == null) {
  99. webapp = new WebApp() {
  100. @Override
  101. public void setup() {
  102. // Defaults should be fine in usual cases
  103. }
  104. };
  105. }
  106. webapp.setName(name);
  107. if (conf == null) {
  108. conf = new Configuration();
  109. }
  110. try {
  111. if (application != null) {
  112. webapp.setHostClass(application.getClass());
  113. } else {
  114. String cls = inferHostClass();
  115. LOG.debug("setting webapp host class to {}", cls);
  116. webapp.setHostClass(Class.forName(cls));
  117. }
  118. if (devMode) {
  119. if (port > 0) {
  120. try {
  121. new URL("http://localhost:"+ port +"/__stop").getContent();
  122. LOG.info("stopping existing webapp instance");
  123. Thread.sleep(100);
  124. } catch (ConnectException e) {
  125. LOG.info("no existing webapp instance found: {}", e.toString());
  126. } catch (Exception e) {
  127. // should not be fatal
  128. LOG.warn("error stopping existing instance: {}", e.toString());
  129. }
  130. } else {
  131. LOG.error("dev mode does NOT work with ephemeral port!");
  132. System.exit(1);
  133. }
  134. }
  135. HttpServer server =
  136. new HttpServer(name, bindAddress, port, findPort, conf);
  137. server.addGlobalFilter("guice", GuiceFilter.class.getName(), null);
  138. webapp.setConf(conf);
  139. webapp.setHttpServer(server);
  140. server.start();
  141. LOG.info("Web app /"+ name +" started at "+ server.getPort());
  142. } catch (Exception e) {
  143. throw new WebAppException("Error starting http server", e);
  144. }
  145. Injector injector = Guice.createInjector(webapp, new AbstractModule() {
  146. @Override
  147. protected void configure() {
  148. if (api != null) {
  149. bind(api).toInstance(application);
  150. }
  151. }
  152. });
  153. LOG.info("Registered webapp guice modules");
  154. // save a guice filter instance for webapp stop (mostly for unit tests)
  155. webapp.setGuiceFilter(injector.getInstance(GuiceFilter.class));
  156. if (devMode) {
  157. injector.getInstance(Dispatcher.class).setDevMode(devMode);
  158. LOG.info("in dev mode!");
  159. }
  160. return webapp;
  161. }
  162. public WebApp start() {
  163. return start(null);
  164. }
  165. private String inferHostClass() {
  166. String thisClass = this.getClass().getName();
  167. Throwable t = new Throwable();
  168. for (StackTraceElement e : t.getStackTrace()) {
  169. if (e.getClassName().equals(thisClass)) continue;
  170. return e.getClassName();
  171. }
  172. LOG.warn("could not infer host class from", t);
  173. return thisClass;
  174. }
  175. }
  176. /**
  177. * Create a new webapp builder.
  178. * @see WebApps for a complete example
  179. * @param <T> application (holding the embedded webapp) type
  180. * @param prefix of the webapp
  181. * @param api the api class for the application
  182. * @param app the application instance
  183. * @return a webapp builder
  184. */
  185. public static <T> Builder<T> $for(String prefix, Class<T> api, T app) {
  186. return new Builder<T>(prefix, api, app);
  187. }
  188. // Short cut mostly for tests/demos
  189. @SuppressWarnings("unchecked")
  190. public static <T> Builder<T> $for(String prefix, T app) {
  191. return $for(prefix, (Class<T>)app.getClass(), app);
  192. }
  193. // Ditto
  194. public static <T> Builder<T> $for(T app) {
  195. return $for("", app);
  196. }
  197. public static <T> Builder<T> $for(String prefix) {
  198. return $for(prefix, null, null);
  199. }
  200. }