1 /* 2 * Copyright 2017 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 17 package com.linecorp.centraldogma.server.command; 18 19 import static com.google.common.base.Preconditions.checkArgument; 20 import static java.util.Objects.requireNonNull; 21 22 import javax.annotation.Nullable; 23 24 import com.fasterxml.jackson.annotation.JsonProperty; 25 import com.fasterxml.jackson.annotation.JsonSubTypes; 26 import com.fasterxml.jackson.annotation.JsonSubTypes.Type; 27 import com.fasterxml.jackson.annotation.JsonTypeInfo; 28 import com.google.common.collect.ImmutableList; 29 30 import com.linecorp.centraldogma.common.Author; 31 import com.linecorp.centraldogma.common.Change; 32 import com.linecorp.centraldogma.common.Markup; 33 import com.linecorp.centraldogma.common.Revision; 34 import com.linecorp.centraldogma.server.auth.Session; 35 import com.linecorp.centraldogma.server.management.ServerStatus; 36 import com.linecorp.centraldogma.server.storage.repository.Repository; 37 38 /** 39 * A Central Dogma command which is used to mutate projects and repositories. 40 * 41 * @param <T> the result type of a {@link Command} 42 */ 43 @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type") 44 @JsonSubTypes({ 45 @Type(value = CreateProjectCommand.class, name = "CREATE_PROJECT"), 46 @Type(value = RemoveProjectCommand.class, name = "REMOVE_PROJECT"), 47 @Type(value = PurgeProjectCommand.class, name = "PURGE_PROJECT"), 48 @Type(value = UnremoveProjectCommand.class, name = "UNREMOVE_PROJECT"), 49 @Type(value = CreateRepositoryCommand.class, name = "CREATE_REPOSITORY"), 50 @Type(value = RemoveRepositoryCommand.class, name = "REMOVE_REPOSITORY"), 51 @Type(value = PurgeRepositoryCommand.class, name = "PURGE_REPOSITORY"), 52 @Type(value = UnremoveRepositoryCommand.class, name = "UNREMOVE_REPOSITORY"), 53 @Type(value = NormalizingPushCommand.class, name = "NORMALIZING_PUSH"), 54 @Type(value = PushAsIsCommand.class, name = "PUSH"), 55 @Type(value = CreateSessionCommand.class, name = "CREATE_SESSIONS"), 56 @Type(value = RemoveSessionCommand.class, name = "REMOVE_SESSIONS"), 57 @Type(value = UpdateServerStatusCommand.class, name = "UPDATE_SERVER_STATUS"), 58 @Type(value = ForcePushCommand.class, name = "FORCE_PUSH_COMMAND"), 59 }) 60 public interface Command<T> { 61 62 /** 63 * Returns a new {@link Command} which is used to create a new project. 64 * 65 * @param author the author who is creating the project 66 * @param name the name of the project which is supposed to be created 67 */ 68 static Command<Void> createProject(Author author, String name) { 69 return createProject(null, author, name); 70 } 71 72 /** 73 * Returns a new {@link Command} which is used to create a new project. 74 * 75 * @param timestamp the creation time of the project, in milliseconds 76 * @param author the author who is creating the project 77 * @param name the name of the project which is supposed to be created 78 */ 79 static Command<Void> createProject(@Nullable Long timestamp, Author author, String name) { 80 requireNonNull(author, "author"); 81 return new CreateProjectCommand(timestamp, author, name); 82 } 83 84 /** 85 * Returns a new {@link Command} which is used to remove a project. 86 * 87 * @param author the author who is removing the project 88 * @param name the name of the project which is supposed to be removed 89 */ 90 static Command<Void> removeProject(Author author, String name) { 91 return removeProject(null, author, name); 92 } 93 94 /** 95 * Returns a new {@link Command} which is used to remove a project. 96 * 97 * @param timestamp the removal time of the project, in milliseconds 98 * @param author the author who is removing the project 99 * @param name the name of the project which is supposed to be removed 100 */ 101 static Command<Void> removeProject(@Nullable Long timestamp, Author author, String name) { 102 requireNonNull(author, "author"); 103 return new RemoveProjectCommand(timestamp, author, name); 104 } 105 106 /** 107 * Returns a new {@link Command} which is used to restore a project that was removed before. 108 * 109 * @param author the author who is restoring the project 110 * @param name the name of the project which is supposed to be restored 111 */ 112 static Command<Void> unremoveProject(Author author, String name) { 113 return unremoveProject(null, author, name); 114 } 115 116 /** 117 * Returns a new {@link Command} which is used to restore a project that was removed before. 118 * 119 * @param timestamp the restoration time of the project, in milliseconds 120 * @param author the author who is restoring the project 121 * @param name the name of the project which is supposed to be restored 122 */ 123 static Command<Void> unremoveProject(@Nullable Long timestamp, Author author, String name) { 124 requireNonNull(author, "author"); 125 return new UnremoveProjectCommand(timestamp, author, name); 126 } 127 128 /** 129 * Returns a new {@link Command} which is used to purge a project that was removed before. 130 * 131 * @param author the author who is restoring the project 132 * @param name the name of the project which is supposed to be restored 133 */ 134 static Command<Void> purgeProject(Author author, String name) { 135 requireNonNull(author, "author"); 136 return new PurgeProjectCommand(null, author, name); 137 } 138 139 /** 140 * Returns a new {@link Command} which is used to purge a project that was removed before. 141 * 142 * @param timestamp the purging time of the project, in milliseconds 143 * @param author the author who is restoring the project 144 * @param name the name of the project which is supposed to be restored 145 */ 146 static Command<Void> purgeProject(@Nullable Long timestamp, Author author, String name) { 147 requireNonNull(author, "author"); 148 return new PurgeProjectCommand(timestamp, author, name); 149 } 150 151 /** 152 * Returns a new {@link Command} which is used to create a new repository. 153 * 154 * @param author the author who is creating the repository 155 * @param projectName the name of the project that the new repository is supposed to belong to 156 * @param repositoryName the name of the repository which is supposed to be created 157 */ 158 static Command<Void> createRepository(Author author, String projectName, String repositoryName) { 159 return createRepository(null, author, projectName, repositoryName); 160 } 161 162 /** 163 * Returns a new {@link Command} which is used to create a new repository. 164 * 165 * @param timestamp the creation time of the repository, in milliseconds 166 * @param author the author who is creating the repository 167 * @param projectName the name of the project that the new repository is supposed to belong to 168 * @param repositoryName the name of the repository which is supposed to be created 169 */ 170 static Command<Void> createRepository(@Nullable Long timestamp, Author author, 171 String projectName, String repositoryName) { 172 requireNonNull(author, "author"); 173 return new CreateRepositoryCommand(timestamp, author, projectName, repositoryName); 174 } 175 176 /** 177 * Returns a new {@link Command} which is used to remove a repository. 178 * 179 * @param author the author who is removing the repository 180 * @param projectName the name of the project 181 * @param repositoryName the name of the repository which is supposed to be removed 182 */ 183 static Command<Void> removeRepository(Author author, String projectName, String repositoryName) { 184 return removeRepository(null, author, projectName, repositoryName); 185 } 186 187 /** 188 * Returns a new {@link Command} which is used to remove a repository. 189 * 190 * @param timestamp the removal time of the repository, in milliseconds 191 * @param author the author who is removing the repository 192 * @param projectName the name of the project 193 * @param repositoryName the name of the repository which is supposed to be removed 194 */ 195 static Command<Void> removeRepository(@Nullable Long timestamp, Author author, 196 String projectName, String repositoryName) { 197 requireNonNull(author, "author"); 198 return new RemoveRepositoryCommand(timestamp, author, projectName, repositoryName); 199 } 200 201 /** 202 * Returns a new {@link Command} which is used to restore a repository that was removed before. 203 * 204 * @param author the author who is restoring the repository 205 * @param projectName the name of the project 206 * @param repositoryName the name of the repository which is supposed to be restored 207 */ 208 static Command<Void> unremoveRepository(Author author, String projectName, String repositoryName) { 209 return unremoveRepository(null, author, projectName, repositoryName); 210 } 211 212 /** 213 * Returns a new {@link Command} which is used to restore a repository that was removed before. 214 * 215 * @param timestamp the restoration time of the project, in milliseconds 216 * @param author the author who is restoring the repository 217 * @param projectName the name of the project 218 * @param repositoryName the name of the repository which is supposed to be restored 219 */ 220 static Command<Void> unremoveRepository(@Nullable Long timestamp, Author author, 221 String projectName, String repositoryName) { 222 requireNonNull(author, "author"); 223 return new UnremoveRepositoryCommand(timestamp, author, projectName, repositoryName); 224 } 225 226 /** 227 * Returns a new {@link Command} which is used to purge a repository. 228 * 229 * @param author the author who is removing the repository 230 * @param projectName the name of the project 231 * @param repositoryName the name of the repository which is supposed to be purged 232 */ 233 static Command<Void> purgeRepository(Author author, 234 String projectName, String repositoryName) { 235 requireNonNull(author, "author"); 236 return new PurgeRepositoryCommand(null, author, projectName, repositoryName); 237 } 238 239 /** 240 * Returns a new {@link Command} which is used to purge a repository. 241 * 242 * @param timestamp the purging time of the repository, in milliseconds 243 * @param author the author who is removing the repository 244 * @param projectName the name of the project 245 * @param repositoryName the name of the repository which is supposed to be purged 246 */ 247 static Command<Void> purgeRepository(@Nullable Long timestamp, Author author, 248 String projectName, String repositoryName) { 249 requireNonNull(author, "author"); 250 return new PurgeRepositoryCommand(timestamp, author, projectName, repositoryName); 251 } 252 253 /** 254 * Returns a new {@link Command} which is used to push the changes. The changes are normalized via 255 * {@link Repository#previewDiff(Revision, Iterable)} before they are applied. 256 * You can find the normalized changes from the {@link CommitResult#changes()} that is the result of 257 * {@link CommandExecutor#execute(Command)}. 258 * 259 * @param author the author who is pushing the changes 260 * @param projectName the name of the project 261 * @param repositoryName the name of the repository which is supposed to be restored 262 * @param baseRevision the revision which is supposed to apply the changes 263 * @param summary the summary of the changes 264 * @param detail the detail message of the changes 265 * @param markup the markup for the detail message 266 * @param changes the changes to be applied 267 */ 268 static Command<CommitResult> push(Author author, String projectName, String repositoryName, 269 Revision baseRevision, String summary, String detail, 270 Markup markup, Change<?>... changes) { 271 272 return push(null, author, projectName, repositoryName, baseRevision, summary, detail, markup, changes); 273 } 274 275 /** 276 * Returns a new {@link Command} which is used to push the changes. The changes are normalized via 277 * {@link Repository#previewDiff(Revision, Iterable)} before they are applied. 278 * You can find the normalized changes from the {@link CommitResult#changes()} that is the result of 279 * {@link CommandExecutor#execute(Command)}. 280 * 281 * @param timestamp the time when pushing the changes, in milliseconds 282 * @param author the author who is pushing the changes 283 * @param projectName the name of the project 284 * @param repositoryName the name of the repository which is supposed to be restored 285 * @param baseRevision the revision which is supposed to apply the changes 286 * @param summary the summary of the changes 287 * @param detail the detail message of the changes 288 * @param markup the markup for the detail message 289 * @param changes the changes to be applied 290 */ 291 static Command<CommitResult> push(@Nullable Long timestamp, Author author, 292 String projectName, String repositoryName, 293 Revision baseRevision, String summary, String detail, 294 Markup markup, Change<?>... changes) { 295 return push(timestamp, author, projectName, repositoryName, baseRevision, 296 summary, detail, markup, ImmutableList.copyOf(changes)); 297 } 298 299 /** 300 * Returns a new {@link Command} which is used to push the changes. The changes are normalized via 301 * {@link Repository#previewDiff(Revision, Iterable)} before they are applied. 302 * You can find the normalized changes from the {@link CommitResult#changes()} that is the result of 303 * {@link CommandExecutor#execute(Command)}. 304 * 305 * @param author the author who is pushing the changes 306 * @param projectName the name of the project 307 * @param repositoryName the name of the repository which is supposed to be restored 308 * @param baseRevision the revision which is supposed to apply the changes 309 * @param summary the summary of the changes 310 * @param detail the detail message of the changes 311 * @param markup the markup for the detail message 312 * @param changes the changes to be applied 313 */ 314 static Command<CommitResult> push(Author author, String projectName, String repositoryName, 315 Revision baseRevision, String summary, String detail, 316 Markup markup, Iterable<Change<?>> changes) { 317 return push(null, author, projectName, repositoryName, baseRevision, summary, detail, markup, changes); 318 } 319 320 /** 321 * Returns a new {@link Command} which is used to push the changes. The changes are normalized via 322 * {@link Repository#previewDiff(Revision, Iterable)} before they are applied. 323 * You can find the normalized changes from the {@link CommitResult#changes()} that is the result of 324 * {@link CommandExecutor#execute(Command)}. 325 * 326 * @param timestamp the time when pushing the changes, in milliseconds 327 * @param author the author who is pushing the changes 328 * @param projectName the name of the project 329 * @param repositoryName the name of the repository which is supposed to be restored 330 * @param baseRevision the revision which is supposed to apply the changes 331 * @param summary the summary of the changes 332 * @param detail the detail message of the changes 333 * @param markup the markup for the detail message 334 * @param changes the changes to be applied 335 */ 336 static Command<CommitResult> push(@Nullable Long timestamp, Author author, 337 String projectName, String repositoryName, 338 Revision baseRevision, String summary, String detail, 339 Markup markup, Iterable<Change<?>> changes) { 340 return new NormalizingPushCommand(timestamp, author, projectName, repositoryName, baseRevision, 341 summary, detail, markup, changes); 342 } 343 344 /** 345 * Returns a new {@link Command} which is used to create a new session. 346 * 347 * @param session the session supposed to be created 348 */ 349 static Command<Void> createSession(Session session) { 350 return new CreateSessionCommand(null, null, session); 351 } 352 353 /** 354 * Returns a new {@link Command} which is used to remove an existing session. 355 * 356 * @param sessionId the session ID supposed to be removed 357 */ 358 static Command<Void> removeSession(String sessionId) { 359 return new RemoveSessionCommand(null, null, sessionId); 360 } 361 362 /** 363 * Returns a new {@link Command} which is used to update the status of the server. 364 */ 365 static Command<Void> updateServerStatus(ServerStatus serverStatus) { 366 return new UpdateServerStatusCommand(null, null, serverStatus); 367 } 368 369 /** 370 * Returns a new {@link Command} which is used to force-push {@link Command} even the server is in 371 * read-only mode. This command is useful for migrating the repository content during maintenance mode. 372 * 373 * <p>Note that {@link CommandType#NORMALIZING_PUSH} and {@link CommandType#PUSH} are allowed as the 374 * delegate. 375 */ 376 static <T> Command<T> forcePush(Command<T> delegate) { 377 requireNonNull(delegate, "delegate"); 378 checkArgument(delegate.type() == CommandType.NORMALIZING_PUSH || delegate.type() == CommandType.PUSH, 379 "delegate: %s (expected: NORMALIZING_PUSH or PUSH)", delegate); 380 return new ForcePushCommand<>(delegate); 381 } 382 383 /** 384 * Returns the {@link CommandType} of the command. 385 */ 386 CommandType type(); 387 388 /** 389 * Returns the time when performing the command, in milliseconds. 390 */ 391 @JsonProperty 392 long timestamp(); 393 394 /** 395 * Returns the author who initiated the command. 396 */ 397 @JsonProperty 398 Author author(); 399 400 /** 401 * Returns the target that the command is supposed to affect, i.e. the project name for the commands 402 * affecting to the project, or the project and repository names for the commands affecting to the 403 * repository. 404 */ 405 String executionPath(); 406 }