Line data Source code
1 : // Copyright (C) 2008 The Android Open Source Project 2 : // 3 : // Licensed under the Apache License, Version 2.0 (the "License"); 4 : // you may not use this file except in compliance with the License. 5 : // You may obtain a copy of the License at 6 : // 7 : // http://www.apache.org/licenses/LICENSE-2.0 8 : // 9 : // Unless required by applicable law or agreed to in writing, software 10 : // distributed under the License is distributed on an "AS IS" BASIS, 11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 : // See the License for the specific language governing permissions and 13 : // limitations under the License. 14 : 15 : package com.google.gerrit.sshd.commands; 16 : 17 : import static com.google.gerrit.common.data.GlobalCapability.FLUSH_CACHES; 18 : import static com.google.gerrit.common.data.GlobalCapability.MAINTAIN_SERVER; 19 : import static com.google.gerrit.server.restapi.config.PostCaches.Operation.FLUSH; 20 : import static com.google.gerrit.server.restapi.config.PostCaches.Operation.FLUSH_ALL; 21 : import static com.google.gerrit.sshd.CommandMetaData.Mode.MASTER_OR_SLAVE; 22 : 23 : import com.google.gerrit.extensions.annotations.RequiresAnyCapability; 24 : import com.google.gerrit.extensions.restapi.RestApiException; 25 : import com.google.gerrit.server.config.ConfigResource; 26 : import com.google.gerrit.server.restapi.config.ListCaches; 27 : import com.google.gerrit.server.restapi.config.ListCaches.OutputFormat; 28 : import com.google.gerrit.server.restapi.config.PostCaches; 29 : import com.google.gerrit.sshd.CommandMetaData; 30 : import com.google.gerrit.sshd.SshCommand; 31 : import com.google.inject.Inject; 32 : import java.util.ArrayList; 33 : import java.util.List; 34 : import org.kohsuke.args4j.Option; 35 : 36 : /** Causes the caches to purge all entries and reload. */ 37 : @RequiresAnyCapability({FLUSH_CACHES, MAINTAIN_SERVER}) 38 : @CommandMetaData( 39 : name = "flush-caches", 40 : description = "Flush some/all server caches from memory", 41 : runsAt = MASTER_OR_SLAVE) 42 1 : final class FlushCaches extends SshCommand { 43 1 : @Option(name = "--cache", usage = "flush named cache", metaVar = "NAME") 44 : private List<String> caches = new ArrayList<>(); 45 : 46 : @Option(name = "--all", usage = "flush all caches") 47 : private boolean all; 48 : 49 : @Option(name = "--list", usage = "list available caches") 50 : private boolean list; 51 : 52 : @Inject private ListCaches listCaches; 53 : 54 : @Inject private PostCaches postCaches; 55 : 56 : @Override 57 : protected void run() throws Failure { 58 0 : enableGracefulStop(); 59 : try { 60 0 : if (list) { 61 0 : if (all || !caches.isEmpty()) { 62 0 : throw die("cannot use --list with --all or --cache"); 63 : } 64 0 : doList(); 65 0 : return; 66 : } 67 : 68 0 : if (all && !caches.isEmpty()) { 69 0 : throw die("cannot combine --all and --cache"); 70 0 : } else if (!all && caches.size() == 1 && caches.contains("all")) { 71 0 : caches.clear(); 72 0 : all = true; 73 0 : } else if (!all && caches.isEmpty()) { 74 0 : all = true; 75 : } 76 : 77 0 : if (all) { 78 0 : postCaches.apply(new ConfigResource(), new PostCaches.Input(FLUSH_ALL)); 79 : } else { 80 0 : postCaches.apply(new ConfigResource(), new PostCaches.Input(FLUSH, caches)); 81 : } 82 0 : } catch (RestApiException e) { 83 0 : throw die(e.getMessage()); 84 0 : } catch (Exception e) { 85 0 : throw new Failure(1, "unavailable", e); 86 0 : } 87 0 : } 88 : 89 : @SuppressWarnings("unchecked") 90 : private void doList() throws Exception { 91 : for (String name : 92 0 : (List<String>) 93 0 : listCaches.setFormat(OutputFormat.LIST).apply(new ConfigResource()).value()) { 94 0 : stderr.print(name); 95 0 : stderr.print('\n'); 96 0 : } 97 0 : stderr.flush(); 98 0 : } 99 : }