1   /*
2    * Copyright 2021 LINE Corporation
3    *
4    * LINE Corporation licenses this file to you under the Apache License,
5    * version 2.0 (the "License"); you may not use this file except in compliance
6    * with the License. You may obtain a copy of the License at:
7    *
8    *   https://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations
14   * under the License.
15   */
16  package com.linecorp.centraldogma.client;
17  
18  import static java.util.Objects.requireNonNull;
19  
20  import java.time.Duration;
21  import java.util.concurrent.CompletableFuture;
22  
23  import com.linecorp.centraldogma.common.Entry;
24  import com.linecorp.centraldogma.common.EntryNotFoundException;
25  import com.linecorp.centraldogma.common.Query;
26  import com.linecorp.centraldogma.common.Revision;
27  
28  /**
29   * Prepares to send a {@link CentralDogma#watchFile(String, String, Revision, Query, long, boolean)}
30   * request to the Central Dogma repository or create a new {@link Watcher}.
31   */
32  public final class WatchRequest<T> extends WatchOptions {
33  
34      private final CentralDogmaRepository centralDogmaRepo;
35      private final Query<T> query;
36  
37      WatchRequest(CentralDogmaRepository centralDogmaRepo, Query<T> query) {
38          this.centralDogmaRepo = centralDogmaRepo;
39          this.query = query;
40      }
41  
42      @Override
43      public WatchRequest<T> timeout(Duration timeout) {
44          //noinspection unchecked
45          return (WatchRequest<T>) super.timeout(timeout);
46      }
47  
48      @Override
49      public WatchRequest<T> timeoutMillis(long timeoutMillis) {
50          //noinspection unchecked
51          return (WatchRequest<T>) super.timeoutMillis(timeoutMillis);
52      }
53  
54      @Override
55      public WatchRequest<T> errorOnEntryNotFound(boolean errorOnEntryNotFound) {
56          //noinspection unchecked
57          return (WatchRequest<T>) super.errorOnEntryNotFound(errorOnEntryNotFound);
58      }
59  
60      /**
61       * Waits for the file matched by the {@link Query} to be changed since the {@link Revision#HEAD}.
62       * If no changes were made within the {@link #timeoutMillis(long)}, the
63       * returned {@link CompletableFuture} will be completed with {@code null}.
64       *
65       * @return the {@link Entry} which contains the latest known {@link Query} result.
66       *         {@code null} if the file was not changed for {@link #timeoutMillis(long)} milliseconds
67       *         since the invocation of this method. {@link EntryNotFoundException} is raised if the
68       *         target does not exist.
69       */
70      public CompletableFuture<Entry<T>> start() {
71          return start(Revision.HEAD);
72      }
73  
74      /**
75       * Waits for the file matched by the {@link Query} to be changed since the {@code lastKnownRevision}.
76       * If no changes were made within the {@link #timeoutMillis(long)}, the
77       * returned {@link CompletableFuture} will be completed with {@code null}.
78       *
79       * @return the {@link Entry} which contains the latest known {@link Query} result.
80       *         {@code null} if the file was not changed for {@link #timeoutMillis(long)} milliseconds
81       *         since the invocation of this method. {@link EntryNotFoundException} is raised if the
82       *         target does not exist.
83       */
84      public CompletableFuture<Entry<T>> start(Revision lastKnownRevision) {
85          requireNonNull(lastKnownRevision, "lastKnownRevision");
86          return centralDogmaRepo.centralDogma().watchFile(centralDogmaRepo.projectName(),
87                                                           centralDogmaRepo.repositoryName(),
88                                                           lastKnownRevision, query,
89                                                           timeoutMillis(), errorOnEntryNotFound());
90      }
91  }