You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

PlatformLevel.java 5.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2021 SonarSource SA
  4. * mailto:info AT sonarsource DOT com
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 3 of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public License
  17. * along with this program; if not, write to the Free Software Foundation,
  18. * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  19. */
  20. package org.sonar.server.platform.platformlevel;
  21. import java.util.Collection;
  22. import java.util.List;
  23. import java.util.Optional;
  24. import javax.annotation.Nonnull;
  25. import javax.annotation.Nullable;
  26. import org.sonar.core.platform.ComponentContainer;
  27. import org.sonar.core.platform.Module;
  28. import org.sonar.server.platform.WebServer;
  29. import static com.google.common.base.Preconditions.checkNotNull;
  30. import static java.util.Objects.requireNonNull;
  31. public abstract class PlatformLevel {
  32. private final String name;
  33. @Nullable
  34. private final PlatformLevel parent;
  35. private final ComponentContainer container;
  36. private AddIfStartupLeader addIfStartupLeader;
  37. private AddIfCluster addIfCluster;
  38. private AddIfStandalone addIfStandalone;
  39. public PlatformLevel(String name) {
  40. this.name = name;
  41. this.parent = null;
  42. this.container = createContainer(null);
  43. }
  44. public PlatformLevel(String name, @Nonnull PlatformLevel parent) {
  45. this.name = checkNotNull(name);
  46. this.parent = checkNotNull(parent);
  47. this.container = createContainer(parent.container);
  48. }
  49. public ComponentContainer getContainer() {
  50. return container;
  51. }
  52. public String getName() {
  53. return name;
  54. }
  55. /**
  56. * Intended to be override by subclasses if needed
  57. */
  58. protected ComponentContainer createContainer(@Nullable ComponentContainer parent) {
  59. if (parent == null) {
  60. return new ComponentContainer();
  61. }
  62. return parent.createChild();
  63. }
  64. public PlatformLevel configure() {
  65. configureLevel();
  66. List<Module> modules = container.getComponentsByType(Module.class);
  67. for (Module module : modules) {
  68. module.configure(container);
  69. }
  70. return this;
  71. }
  72. protected abstract void configureLevel();
  73. /**
  74. * Intended to be override by subclasses if needed
  75. */
  76. public PlatformLevel start() {
  77. container.startComponents();
  78. return this;
  79. }
  80. /**
  81. * Intended to be override by subclasses if needed
  82. */
  83. public PlatformLevel stop() {
  84. container.stopComponents();
  85. return this;
  86. }
  87. /**
  88. * Intended to be override by subclasses if needed
  89. */
  90. public PlatformLevel destroy() {
  91. if (parent != null) {
  92. parent.container.removeChild(container);
  93. }
  94. return this;
  95. }
  96. protected <T> T get(Class<T> tClass) {
  97. return requireNonNull(container.getComponentByType(tClass));
  98. }
  99. protected <T> List<T> getAll(Class<T> tClass) {
  100. return container.getComponentsByType(tClass);
  101. }
  102. protected <T> Optional<T> getOptional(Class<T> tClass) {
  103. return Optional.ofNullable(container.getComponentByType(tClass));
  104. }
  105. protected void add(Object... objects) {
  106. for (Object object : objects) {
  107. if (object != null) {
  108. container.addComponent(object, true);
  109. }
  110. }
  111. }
  112. /**
  113. * Add a component to container only if the web server is startup leader.
  114. *
  115. * @throws IllegalStateException if called from PlatformLevel1, when cluster settings are not loaded
  116. */
  117. AddIfStartupLeader addIfStartupLeader(Object... objects) {
  118. if (addIfStartupLeader == null) {
  119. this.addIfStartupLeader = new AddIfStartupLeader(getWebServer().isStartupLeader());
  120. }
  121. addIfStartupLeader.ifAdd(objects);
  122. return addIfStartupLeader;
  123. }
  124. /**
  125. * Add a component to container only if clustering is enabled.
  126. *
  127. * @throws IllegalStateException if called from PlatformLevel1, when cluster settings are not loaded
  128. */
  129. AddIfCluster addIfCluster(Object... objects) {
  130. if (addIfCluster == null) {
  131. addIfCluster = new AddIfCluster(!getWebServer().isStandalone());
  132. }
  133. addIfCluster.ifAdd(objects);
  134. return addIfCluster;
  135. }
  136. /**
  137. * Add a component to container only if this is a standalone instance, without clustering.
  138. *
  139. * @throws IllegalStateException if called from PlatformLevel1, when cluster settings are not loaded
  140. */
  141. AddIfStandalone addIfStandalone(Object... objects) {
  142. if (addIfStandalone == null) {
  143. addIfStandalone = new AddIfStandalone(getWebServer().isStandalone());
  144. }
  145. addIfStandalone.ifAdd(objects);
  146. return addIfStandalone;
  147. }
  148. private WebServer getWebServer() {
  149. return getOptional(WebServer.class)
  150. .orElseThrow(() -> new IllegalStateException("WebServer not available in Pico yet"));
  151. }
  152. private abstract class AddIf {
  153. private final boolean condition;
  154. private AddIf(boolean condition) {
  155. this.condition = condition;
  156. }
  157. public void ifAdd(Object... objects) {
  158. if (condition) {
  159. PlatformLevel.this.add(objects);
  160. }
  161. }
  162. public void otherwiseAdd(Object... objects) {
  163. if (!condition) {
  164. PlatformLevel.this.add(objects);
  165. }
  166. }
  167. }
  168. public final class AddIfStartupLeader extends AddIf {
  169. private AddIfStartupLeader(boolean condition) {
  170. super(condition);
  171. }
  172. }
  173. public final class AddIfCluster extends AddIf {
  174. private AddIfCluster(boolean condition) {
  175. super(condition);
  176. }
  177. }
  178. public final class AddIfStandalone extends AddIf {
  179. private AddIfStandalone(boolean condition) {
  180. super(condition);
  181. }
  182. }
  183. protected void addAll(Collection<?> objects) {
  184. add(objects.toArray(new Object[objects.size()]));
  185. }
  186. }