View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.apache.hadoop.hbase.client;
19  
20  import java.io.IOException;
21  import java.util.ArrayList;
22  import java.util.List;
23  import java.util.concurrent.Future;
24  
25  import org.apache.commons.lang.StringUtils;
26  import org.apache.commons.logging.Log;
27  import org.apache.commons.logging.LogFactory;
28  import org.apache.hadoop.hbase.TableName;
29  import org.apache.hadoop.hbase.backup.BackupInfo;
30  import org.apache.hadoop.hbase.backup.BackupInfo.BackupState;
31  import org.apache.hadoop.hbase.backup.BackupRequest;
32  import org.apache.hadoop.hbase.backup.BackupRestoreClientFactory;
33  import org.apache.hadoop.hbase.backup.RestoreClient;
34  import org.apache.hadoop.hbase.backup.RestoreRequest;
35  import org.apache.hadoop.hbase.backup.impl.BackupSystemTable;
36  import org.apache.hadoop.hbase.backup.util.BackupClientUtil;
37  import org.apache.hadoop.hbase.backup.util.BackupSet;
38  import org.apache.hadoop.hbase.classification.InterfaceAudience;
39  import org.apache.hadoop.hbase.classification.InterfaceStability;
40  
41  /**
42   * The administrative API implementation for HBase Backup . Obtain an instance from 
43   * an {@link Admin#getBackupAdmin()} and call {@link #close()} afterwards.
44   * <p>BackupAdmin can be used to create backups, restore data from backups and for 
45   * other backup-related operations. 
46   *
47   * @see Admin
48   * @since 2.0
49   */
50  @InterfaceAudience.Private
51  @InterfaceStability.Evolving
52  
53  public class HBaseBackupAdmin implements BackupAdmin {
54    private static final Log LOG = LogFactory.getLog(HBaseBackupAdmin.class);
55  
56    private final HBaseAdmin admin;
57    private final Connection conn;
58    
59    HBaseBackupAdmin(HBaseAdmin admin) {
60      this.admin = admin;
61      this.conn = admin.getConnection();
62    }
63      
64    
65    @Override
66    public void close() throws IOException {
67    }
68  
69    @Override
70    public BackupInfo getBackupInfo(String backupId) throws IOException {    
71      BackupInfo backupInfo = null;
72      try (final BackupSystemTable table = new BackupSystemTable(conn)) {
73        backupInfo = table.readBackupInfo(backupId);
74        return backupInfo;
75      }   
76    }
77  
78    @Override
79    public int getProgress(String backupId) throws IOException {
80      BackupInfo backupInfo = null;
81      try (final BackupSystemTable table = new BackupSystemTable(conn)) {
82        if (backupId == null) {
83          ArrayList<BackupInfo> recentSessions =
84              table.getBackupContexts(BackupState.RUNNING);
85          if (recentSessions.isEmpty()) {
86            LOG.warn("No ongoing sessions found.");
87            return -1;
88          }
89          // else show status for ongoing session
90          // must be one maximum
91          return recentSessions.get(0).getProgress();
92        } else {
93  
94          backupInfo = table.readBackupInfo(backupId);
95          if (backupInfo != null) {
96            return backupInfo.getProgress();
97          } else {
98            LOG.warn("No information found for backupID=" + backupId);
99            return -1;
100         }
101       }
102     }  
103   }
104 
105   @Override
106   public int deleteBackups(String[] backupIds) throws IOException {
107     BackupInfo backupInfo = null;
108     String backupId = null;
109     int totalDeleted = 0;
110     try (final BackupSystemTable table = new BackupSystemTable(conn)) {
111       for (int i = 0; i < backupIds.length; i++) {
112         backupId = backupIds[i];
113         LOG.info("Deleting backup for backupID=" + backupId + " ...");
114         backupInfo = table.readBackupInfo(backupId);
115         if (backupInfo != null) {
116           BackupClientUtil.cleanupBackupData(backupInfo, admin.getConfiguration());
117           table.deleteBackupInfo(backupInfo.getBackupId());
118           LOG.info("Delete backup for backupID=" + backupId + " completed.");
119           totalDeleted++;
120         } else {
121           LOG.warn("Delete backup failed: no information found for backupID=" + backupId);
122         }
123       }
124     }
125     return totalDeleted;
126   }
127 
128   @Override
129   public List<BackupInfo> getHistory(int n) throws IOException {
130     try (final BackupSystemTable table = new BackupSystemTable(conn)) {
131       List<BackupInfo> history = table.getBackupHistory();
132       if( history.size() <= n) return history;
133       List<BackupInfo> list = new ArrayList<BackupInfo>();
134       for(int i=0; i < n; i++){
135         list.add(history.get(i));
136       }
137       return list;
138     }  
139   }
140 
141   @Override
142   public List<BackupSet> listBackupSets() throws IOException {
143     try (final BackupSystemTable table = new BackupSystemTable(conn)) {
144       List<String> list = table.listBackupSets();
145       List<BackupSet> bslist = new ArrayList<BackupSet>();
146       for (String s : list) {
147         List<TableName> tables = table.describeBackupSet(s);
148         if(tables != null){
149           bslist.add( new BackupSet(s, tables));
150         }
151       }
152       return bslist;
153     }
154   }
155 
156   @Override
157   public BackupSet getBackupSet(String name) throws IOException {
158     try (final BackupSystemTable table = new BackupSystemTable(conn)) {
159       List<TableName> list = table.describeBackupSet(name);
160       if(list == null) return null;
161       return new BackupSet(name, list);
162     }  
163   }
164 
165   @Override
166   public boolean deleteBackupSet(String name) throws IOException {
167     try (final BackupSystemTable table = new BackupSystemTable(conn)) {
168       if(table.describeBackupSet(name) == null) {
169         return false;
170       }
171       table.deleteBackupSet(name);
172       return true;
173     }  
174   }
175 
176   @Override
177   public void addToBackupSet(String name, TableName[] tables) throws IOException {
178     String[] tableNames = new String[tables.length];
179     for(int i = 0; i < tables.length; i++){
180       tableNames[i] = tables[i].getNameAsString();
181       if (!admin.tableExists(tableNames[i])) {
182         throw new IOException("Cannot add " + tableNames[i] + " because it doesn't exist");
183       }
184     }
185     try (final BackupSystemTable table = new BackupSystemTable(conn)) {
186       table.addToBackupSet(name, tableNames);      
187       LOG.info("Added tables ["+StringUtils.join(tableNames, " ")+"] to '" + name + "' backup set");
188     }  
189   }
190 
191   @Override
192   public void removeFromBackupSet(String name, String[] tables) throws IOException {
193     LOG.info("Removing tables ["+ StringUtils.join(tables, " ")+"] from '" + name + "'");
194     try (final BackupSystemTable table = new BackupSystemTable(conn)) {      
195       table.removeFromBackupSet(name, tables);
196       LOG.info("Removing tables ["+ StringUtils.join(tables, " ")+"] from '" + name + "' completed.");
197     }   
198   }
199 
200   @Override
201   public void restore(RestoreRequest request) throws IOException {
202     RestoreClient client = BackupRestoreClientFactory.getRestoreClient(admin.getConfiguration());
203     client.restore(request.getBackupRootDir(), 
204                    request.getBackupId(), 
205                    request.isCheck(), 
206                    request.getFromTables(), 
207                    request.getToTables(), 
208                    request.isOverwrite());
209     
210   }
211 
212   @Override
213   public String backupTables(final BackupRequest userRequest) 
214       throws IOException {
215    return admin.backupTables(userRequest);
216   }
217   
218   
219   @Override
220   public Future<String> backupTablesAsync(final BackupRequest userRequest) 
221       throws IOException {
222     return admin.backupTablesAsync(userRequest);
223   }
224   
225   
226 }