PageRenderTime 47ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/jira-project/jira-functional-tests/jira-func-tests/src/main/java/com/atlassian/jira/functest/framework/backdoor/IndexingControl.java

https://bitbucket.org/ahmed_bilal_360factors/jira7-core
Java | 273 lines | 186 code | 45 blank | 42 comment | 3 complexity | 2addbe629ac1309d6a474e8bed1df45b MD5 | raw file
Possible License(s): Apache-2.0
  1. package com.atlassian.jira.functest.framework.backdoor;
  2. import com.atlassian.jira.index.request.ReindexRequestType;
  3. import com.atlassian.jira.index.request.SharedEntityType;
  4. import com.atlassian.jira.issue.index.IssueIndexingParams;
  5. import com.atlassian.jira.util.Supplier;
  6. import com.atlassian.jira.webtests.util.JIRAEnvironmentData;
  7. import com.sun.jersey.api.client.WebResource;
  8. import org.apache.commons.lang.time.DateUtils;
  9. import javax.annotation.Nonnull;
  10. import javax.annotation.Nullable;
  11. import java.util.Map;
  12. /**
  13. * Backdoor control for indexing.
  14. *
  15. * @since v5.2
  16. */
  17. public class IndexingControl extends BackdoorControl<IndexingControl> {
  18. public IndexingControl(JIRAEnvironmentData environmentData) {
  19. super(environmentData);
  20. }
  21. @Nonnull
  22. public IndexingProgress startInBackground() {
  23. return startInBackground(IssueIndexingParams.INDEX_ISSUE_ONLY);
  24. }
  25. @Nonnull
  26. public IndexingProgress startInBackground(final IssueIndexingParams issueIndexingParams) {
  27. final String taskId = createResource().path("indexing").path("background")
  28. .queryParam("comments", String.valueOf(issueIndexingParams.isIndexComments()))
  29. .queryParam("changeHistory", String.valueOf(issueIndexingParams.isIndexChangeHistory()))
  30. .queryParam("worklogs", String.valueOf(issueIndexingParams.isIndexWorklogs()))
  31. .queryParam("issues", String.valueOf(issueIndexingParams.isIndexIssues()))
  32. .queryParam("forceReloadFromDatabase", String.valueOf(issueIndexingParams.isForceReloadFromDatabase()))
  33. .post(String.class);
  34. return new IndexingProgress() {
  35. @Override
  36. boolean isIndexing() {
  37. return isIndexingInProgress();
  38. }
  39. @Override
  40. boolean isIndexingStarted() {
  41. return checkIsIndexingStarted();
  42. }
  43. @Override
  44. public String getTaskId() {
  45. return taskId;
  46. }
  47. };
  48. }
  49. /**
  50. * Initiate a stop-the-world foreground re-index
  51. *
  52. * @return a progress monitor
  53. */
  54. @Nonnull
  55. public IndexingProgress startStopTheWorldReIndex() {
  56. createResource().path("indexing").path("stoptheworld").post();
  57. return new DefaultIndexingProgress();
  58. }
  59. @Nullable
  60. public Boolean getIndexingTaskProgress(String taskId) {
  61. Map<?, ?> rawValues = resourceRoot(getEnvironmentData().getBaseUrl().toExternalForm()).path("rest").path("api").path("2").path("reindex").queryParam("taskId", taskId).get(Map.class);
  62. return (Boolean) rawValues.get("success");
  63. }
  64. @Nonnull
  65. public IndexingProgress getInBackgroundProgress() {
  66. return new DefaultIndexingProgress();
  67. }
  68. boolean isIndexingInProgress() {
  69. // returns true if indexing is running
  70. return createResource().path("indexing").get(Boolean.class);
  71. }
  72. boolean checkIsIndexingStarted() {
  73. // returns true if indexing has already started
  74. return createResource().path("indexing").path("started").get(Boolean.class);
  75. }
  76. @Nonnull
  77. public IndexingProgress getProjectIndexingProgress(final Long projectId) {
  78. return new IndexingProgress() {
  79. @Override
  80. boolean isIndexing() {
  81. return isIndexingProject(projectId);
  82. }
  83. @Override
  84. boolean isIndexingStarted() {
  85. return isIndexingProjectStarted(projectId);
  86. }
  87. @Override
  88. public String getTaskId() {
  89. return null;
  90. }
  91. };
  92. }
  93. boolean isIndexingProject(Long projectId) {
  94. // returns true if indexing is running
  95. return createResource().path("indexing").path("project").queryParam("projectId", projectId.toString()).get(Boolean.class);
  96. }
  97. boolean isIndexingProjectStarted(Long projectId) {
  98. // returns true if indexing is running
  99. return createResource().path("indexing").path("project").path("started").queryParam("projectId", projectId.toString()).get(Boolean.class);
  100. }
  101. public boolean isIndexConsistent() {
  102. return createResource().path("indexing").path("consistent").get(Boolean.class);
  103. }
  104. public boolean isIndexUpdatedFieldConsistent() {
  105. return createResource().path("indexing").path("consistent").path("updated").get(Boolean.class);
  106. }
  107. public void deleteIndex() {
  108. createResource().path("indexing").path("deleteIndex").post();
  109. }
  110. public void deindex(String issueKey) {
  111. createResource().path("indexing").path("deindex").queryParam("key", issueKey).get(Boolean.class);
  112. }
  113. public void indexDummyIssue(long id, long projectId, String issueType, String issueKey, String summary, String desc) {
  114. createResource().path("indexing")
  115. .path("indexDummyIssue")
  116. .queryParam("id", String.valueOf(id))
  117. .queryParam("projectId", String.valueOf(projectId))
  118. .queryParam("issueType", issueType)
  119. .queryParam("key", issueKey)
  120. .queryParam("summary", summary)
  121. .queryParam("description", desc)
  122. .get(Boolean.class);
  123. }
  124. public void reindexAll() {
  125. createResource().path("indexing").path("reindexAll").post();
  126. }
  127. public Long makeReindexRequest(ReindexRequestType type, String query, SharedEntityType... sharedEntityTypes) {
  128. WebResource resource = createResource().path("indexing").path("makeReindexRequest").queryParam("type", type.name())
  129. .queryParam("query", query);
  130. for (SharedEntityType sharedEntityType : sharedEntityTypes) {
  131. resource.queryParam("sharedEntityType", sharedEntityType.name());
  132. }
  133. return resource.get(Long.class);
  134. }
  135. public Long clearPendingReindexRequests() {
  136. return createResource().path("indexing").path("clearPendingReindexRequests").get(Long.class);
  137. }
  138. /**
  139. * Pause the scheduled reindex
  140. */
  141. @SuppressWarnings("unused")
  142. public void pauseScheduledReindex() {
  143. createResource().path("indexing").path("scheduledReindex").path("pause").post();
  144. }
  145. /**
  146. * Start the scheduled reindex
  147. */
  148. @SuppressWarnings("unused")
  149. public void startScheduledReindex() {
  150. createResource().path("indexing").path("scheduledReindex").path("start").post();
  151. }
  152. public abstract class IndexingProgress {
  153. /**
  154. * Timeout definition, in minutes.
  155. */
  156. private final long TIMEOUT_MINUTES = 5;
  157. /**
  158. * Chunk of incremental updates.
  159. */
  160. private final long MILLIS_PER_CHUNK = 200;
  161. /**
  162. * Timeout definition, in chunks.
  163. */
  164. private final long MAX_TIMEOUT_IN_CHUNKS = (TIMEOUT_MINUTES * DateUtils.MILLIS_PER_MINUTE) / MILLIS_PER_CHUNK;
  165. /**
  166. * Current interval
  167. */
  168. private long interval = 0;
  169. /**
  170. * Overall number of intervals waited.
  171. */
  172. private long overallChunks = 0;
  173. /**
  174. * Waits until the indexing is finished. This method works by polling the server in increasing intervals
  175. * starting from MILLIS_PER_CHUNK.
  176. */
  177. public void waitForCompletion() {
  178. poolUntilTrue(new Supplier<Boolean>() {
  179. @Override
  180. @Nonnull
  181. public Boolean get() {
  182. return !isIndexing();
  183. }
  184. });
  185. }
  186. public void waitForIndexingStarted() {
  187. poolUntilTrue(new Supplier<Boolean>() {
  188. @Override
  189. public Boolean get() {
  190. return isIndexingStarted();
  191. }
  192. });
  193. }
  194. private void poolUntilTrue(final Supplier<Boolean> condition) {
  195. while (!condition.get()) {
  196. try {
  197. Thread.sleep((++interval) * MILLIS_PER_CHUNK);
  198. overallChunks += interval;
  199. if (overallChunks > MAX_TIMEOUT_IN_CHUNKS) {
  200. throw new RuntimeException("Indexing timed out.");
  201. }
  202. } catch (InterruptedException e) {
  203. throw new RuntimeException(e);
  204. }
  205. }
  206. }
  207. abstract boolean isIndexing();
  208. abstract boolean isIndexingStarted();
  209. public abstract String getTaskId();
  210. }
  211. /**
  212. * The simplest IndexingProgress, with no task ID
  213. */
  214. private class DefaultIndexingProgress extends IndexingProgress {
  215. @Override
  216. boolean isIndexing() {
  217. return isIndexingInProgress();
  218. }
  219. @Override
  220. boolean isIndexingStarted() {
  221. return checkIsIndexingStarted();
  222. }
  223. @Override
  224. public String getTaskId() {
  225. return null;
  226. }
  227. }
  228. }