View Javadoc

1   /*
2    *
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   * http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   */
19  
20  package org.apache.hadoop.hbase.master;
21  
22  import org.apache.hadoop.classification.InterfaceAudience;
23  import org.apache.hadoop.conf.Configuration;
24  import org.apache.hadoop.hbase.*;
25  import org.apache.hadoop.hbase.coprocessor.*;
26  import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.SnapshotDescription;
27  
28  import java.io.IOException;
29  import java.util.List;
30  
31  /**
32   * Provides the coprocessor framework and environment for master oriented
33   * operations.  {@link HMaster} interacts with the loaded coprocessors
34   * through this class.
35   */
36  @InterfaceAudience.Private
37  public class MasterCoprocessorHost
38      extends CoprocessorHost<MasterCoprocessorHost.MasterEnvironment> {
39  
40    /**
41     * Coprocessor environment extension providing access to master related
42     * services.
43     */
44    static class MasterEnvironment extends CoprocessorHost.Environment
45        implements MasterCoprocessorEnvironment {
46      private MasterServices masterServices;
47  
48      public MasterEnvironment(final Class<?> implClass, final Coprocessor impl,
49          final int priority, final int seq, final Configuration conf,
50          final MasterServices services) {
51        super(impl, priority, seq, conf);
52        this.masterServices = services;
53      }
54  
55      public MasterServices getMasterServices() {
56        return masterServices;
57      }
58    }
59  
60    private MasterServices masterServices;
61  
62    MasterCoprocessorHost(final MasterServices services, final Configuration conf) {
63      super(services);
64      this.conf = conf;
65      this.masterServices = services;
66      loadSystemCoprocessors(conf, MASTER_COPROCESSOR_CONF_KEY);
67    }
68  
69    @Override
70    public MasterEnvironment createEnvironment(final Class<?> implClass,
71        final Coprocessor instance, final int priority, final int seq,
72        final Configuration conf) {
73      for (Class<?> c : implClass.getInterfaces()) {
74        if (CoprocessorService.class.isAssignableFrom(c)) {
75          masterServices.registerService(((CoprocessorService)instance).getService());
76        }
77      }
78      return new MasterEnvironment(implClass, instance, priority, seq, conf,
79          masterServices);
80    }
81  
82    public boolean preCreateNamespace(final NamespaceDescriptor ns) throws IOException {
83      boolean bypass = false;
84      ObserverContext<MasterCoprocessorEnvironment> ctx = null;
85      for (MasterEnvironment env: coprocessors) {
86        if (env.getInstance() instanceof MasterObserver) {
87          ctx = ObserverContext.createAndPrepare(env, ctx);
88          Thread currentThread = Thread.currentThread();
89          ClassLoader cl = currentThread.getContextClassLoader();
90          try {
91            currentThread.setContextClassLoader(env.getClassLoader());
92            ((MasterObserver)env.getInstance()).preCreateNamespace(ctx, ns);
93          } catch (Throwable e) {
94            handleCoprocessorThrowable(env, e);
95          } finally {
96            currentThread.setContextClassLoader(cl);
97          }
98          bypass |= ctx.shouldBypass();
99          if (ctx.shouldComplete()) {
100           break;
101         }
102       }
103     }
104     return bypass;
105   }
106 
107   public void postCreateNamespace(final NamespaceDescriptor ns) throws IOException {
108     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
109     for (MasterEnvironment env: coprocessors) {
110       if (env.getInstance() instanceof MasterObserver) {
111         ctx = ObserverContext.createAndPrepare(env, ctx);
112         Thread currentThread = Thread.currentThread();
113         ClassLoader cl = currentThread.getContextClassLoader();
114         try {
115           currentThread.setContextClassLoader(env.getClassLoader());
116           ((MasterObserver)env.getInstance()).postCreateNamespace(ctx, ns);
117         } catch (Throwable e) {
118           handleCoprocessorThrowable(env, e);
119         } finally {
120           currentThread.setContextClassLoader(cl);
121         }
122         if (ctx.shouldComplete()) {
123           break;
124         }
125       }
126     }
127   }
128 
129   public boolean preDeleteNamespace(final String namespaceName) throws IOException {
130     boolean bypass = false;
131     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
132     for (MasterEnvironment env: coprocessors) {
133       if (env.getInstance() instanceof MasterObserver) {
134         ctx = ObserverContext.createAndPrepare(env, ctx);
135         Thread currentThread = Thread.currentThread();
136         ClassLoader cl = currentThread.getContextClassLoader();
137         try {
138           currentThread.setContextClassLoader(env.getClassLoader());
139           ((MasterObserver)env.getInstance()).preDeleteNamespace(ctx, namespaceName);
140         } catch (Throwable e) {
141           handleCoprocessorThrowable(env, e);
142         } finally {
143           currentThread.setContextClassLoader(cl);
144         }
145         bypass |= ctx.shouldBypass();
146         if (ctx.shouldComplete()) {
147           break;
148         }
149       }
150     }
151     return bypass;
152   }
153 
154   public void postDeleteNamespace(final String namespaceName) throws IOException {
155     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
156     for (MasterEnvironment env: coprocessors) {
157       if (env.getInstance() instanceof MasterObserver) {
158         ctx = ObserverContext.createAndPrepare(env, ctx);
159         Thread currentThread = Thread.currentThread();
160         ClassLoader cl = currentThread.getContextClassLoader();
161         try {
162           currentThread.setContextClassLoader(env.getClassLoader());
163           ((MasterObserver)env.getInstance()).postDeleteNamespace(ctx, namespaceName);
164         } catch (Throwable e) {
165           handleCoprocessorThrowable(env, e);
166         } finally {
167           currentThread.setContextClassLoader(cl);
168         }
169         if (ctx.shouldComplete()) {
170           break;
171         }
172       }
173     }
174   }
175 
176   public boolean preModifyNamespace(final NamespaceDescriptor ns) throws IOException {
177     boolean bypass = false;
178     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
179     for (MasterEnvironment env: coprocessors) {
180       if (env.getInstance() instanceof MasterObserver) {
181         ctx = ObserverContext.createAndPrepare(env, ctx);
182         Thread currentThread = Thread.currentThread();
183         ClassLoader cl = currentThread.getContextClassLoader();
184         try {
185           currentThread.setContextClassLoader(env.getClassLoader());
186           ((MasterObserver)env.getInstance()).preModifyNamespace(ctx, ns);
187         } catch (Throwable e) {
188           handleCoprocessorThrowable(env, e);
189         } finally {
190           currentThread.setContextClassLoader(cl);
191         }
192         bypass |= ctx.shouldBypass();
193         if (ctx.shouldComplete()) {
194           break;
195         }
196       }
197     }
198     return bypass;
199   }
200 
201   public void postModifyNamespace(final NamespaceDescriptor ns) throws IOException {
202     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
203     for (MasterEnvironment env: coprocessors) {
204       if (env.getInstance() instanceof MasterObserver) {
205         ctx = ObserverContext.createAndPrepare(env, ctx);
206         Thread currentThread = Thread.currentThread();
207         ClassLoader cl = currentThread.getContextClassLoader();
208         try {
209           currentThread.setContextClassLoader(env.getClassLoader());
210           ((MasterObserver)env.getInstance()).postModifyNamespace(ctx, ns);
211         } catch (Throwable e) {
212           handleCoprocessorThrowable(env, e);
213         } finally {
214           currentThread.setContextClassLoader(cl);
215         }
216         if (ctx.shouldComplete()) {
217           break;
218         }
219       }
220     }
221   }
222 
223   /* Implementation of hooks for invoking MasterObservers */
224 
225   public void preCreateTable(final HTableDescriptor htd, final HRegionInfo[] regions)
226     throws IOException {
227     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
228     for (MasterEnvironment env: coprocessors) {
229       if (env.getInstance() instanceof MasterObserver) {
230         ctx = ObserverContext.createAndPrepare(env, ctx);
231         Thread currentThread = Thread.currentThread();
232         ClassLoader cl = currentThread.getContextClassLoader();
233         try {
234           currentThread.setContextClassLoader(env.getClassLoader());
235           ((MasterObserver)env.getInstance()).preCreateTable(ctx, htd, regions);
236         } catch (Throwable e) {
237           handleCoprocessorThrowable(env, e);
238         } finally {
239           currentThread.setContextClassLoader(cl);
240         }
241         if (ctx.shouldComplete()) {
242           break;
243         }
244       }
245     }
246   }
247 
248   public void postCreateTable(final HTableDescriptor htd, final HRegionInfo[] regions)
249     throws IOException {
250     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
251     for (MasterEnvironment env: coprocessors) {
252       if (env.getInstance() instanceof MasterObserver) {
253         ctx = ObserverContext.createAndPrepare(env, ctx);
254         Thread currentThread = Thread.currentThread();
255         ClassLoader cl = currentThread.getContextClassLoader();
256         try {
257           currentThread.setContextClassLoader(env.getClassLoader());
258           ((MasterObserver)env.getInstance()).postCreateTable(ctx, htd, regions);
259         } catch (Throwable e) {
260           handleCoprocessorThrowable(env, e);
261         } finally {
262           currentThread.setContextClassLoader(cl);
263         }
264         if (ctx.shouldComplete()) {
265           break;
266         }
267       }
268     }
269   }
270 
271   public void preCreateTableHandler(final HTableDescriptor htd, final HRegionInfo[] regions)
272       throws IOException {
273     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
274     for (MasterEnvironment env : coprocessors) {
275       if (env.getInstance() instanceof MasterObserver) {
276         ctx = ObserverContext.createAndPrepare(env, ctx);
277         Thread currentThread = Thread.currentThread();
278         ClassLoader cl = currentThread.getContextClassLoader();
279         try {
280           currentThread.setContextClassLoader(env.getClassLoader());
281           ((MasterObserver) env.getInstance()).preCreateTableHandler(ctx, htd, regions);
282         } catch (Throwable e) {
283           handleCoprocessorThrowable(env, e);
284         } finally {
285           currentThread.setContextClassLoader(cl);
286         }
287         if (ctx.shouldComplete()) {
288           break;
289         }
290       }
291     }
292   }
293 
294   public void postCreateTableHandler(final HTableDescriptor htd, final HRegionInfo[] regions)
295       throws IOException {
296     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
297     for (MasterEnvironment env : coprocessors) {
298       if (env.getInstance() instanceof MasterObserver) {
299         ctx = ObserverContext.createAndPrepare(env, ctx);
300         Thread currentThread = Thread.currentThread();
301         ClassLoader cl = currentThread.getContextClassLoader();
302         try {
303           currentThread.setContextClassLoader(env.getClassLoader());
304           ((MasterObserver) env.getInstance()).postCreateTableHandler(ctx, htd, regions);
305         } catch (Throwable e) {
306           handleCoprocessorThrowable(env, e);
307         } finally {
308           currentThread.setContextClassLoader(cl);
309         }
310         if (ctx.shouldComplete()) {
311           break;
312         }
313       }
314     }
315   }
316 
317   public void preDeleteTable(final TableName tableName) throws IOException {
318     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
319     for (MasterEnvironment env: coprocessors) {
320       if (env.getInstance() instanceof MasterObserver) {
321         ctx = ObserverContext.createAndPrepare(env, ctx);
322         Thread currentThread = Thread.currentThread();
323         ClassLoader cl = currentThread.getContextClassLoader();
324         try {
325           currentThread.setContextClassLoader(env.getClassLoader());
326           ((MasterObserver)env.getInstance()).preDeleteTable(ctx, tableName);
327         } catch (Throwable e) {
328           handleCoprocessorThrowable(env, e);
329         } finally {
330           currentThread.setContextClassLoader(cl);
331         }
332         if (ctx.shouldComplete()) {
333           break;
334         }
335       }
336     }
337   }
338 
339   public void postDeleteTable(final TableName tableName) throws IOException {
340     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
341     for (MasterEnvironment env: coprocessors) {
342       if (env.getInstance() instanceof MasterObserver) {
343         ctx = ObserverContext.createAndPrepare(env, ctx);
344         Thread currentThread = Thread.currentThread();
345         ClassLoader cl = currentThread.getContextClassLoader();
346         try {
347           currentThread.setContextClassLoader(env.getClassLoader());
348           ((MasterObserver)env.getInstance()).postDeleteTable(ctx, tableName);
349         } catch (Throwable e) {
350           handleCoprocessorThrowable(env, e);
351         } finally {
352           currentThread.setContextClassLoader(cl);
353         }
354         if (ctx.shouldComplete()) {
355           break;
356         }
357       }
358     }
359   }
360 
361   public void preDeleteTableHandler(final TableName tableName) throws IOException {
362     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
363     for (MasterEnvironment env : coprocessors) {
364       if (env.getInstance() instanceof MasterObserver) {
365         ctx = ObserverContext.createAndPrepare(env, ctx);
366         Thread currentThread = Thread.currentThread();
367         ClassLoader cl = currentThread.getContextClassLoader();
368         try {
369           currentThread.setContextClassLoader(env.getClassLoader());
370           ((MasterObserver) env.getInstance()).preDeleteTableHandler(ctx, tableName);
371         } catch (Throwable e) {
372           handleCoprocessorThrowable(env, e);
373         } finally {
374           currentThread.setContextClassLoader(cl);
375         }
376         if (ctx.shouldComplete()) {
377           break;
378         }
379       }
380     }
381   }
382 
383   public void postDeleteTableHandler(final TableName tableName) throws IOException {
384     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
385     for (MasterEnvironment env : coprocessors) {
386       if (env.getInstance() instanceof MasterObserver) {
387         ctx = ObserverContext.createAndPrepare(env, ctx);
388         Thread currentThread = Thread.currentThread();
389         ClassLoader cl = currentThread.getContextClassLoader();
390         try {
391           currentThread.setContextClassLoader(env.getClassLoader());
392           ((MasterObserver) env.getInstance()).postDeleteTableHandler(ctx, tableName);
393         } catch (Throwable e) {
394           handleCoprocessorThrowable(env, e);
395         } finally {
396           currentThread.setContextClassLoader(cl);
397         }
398         if (ctx.shouldComplete()) {
399           break;
400         }
401       }
402     }
403   }
404 
405   public void preModifyTable(final TableName tableName, final HTableDescriptor htd)
406       throws IOException {
407     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
408     for (MasterEnvironment env: coprocessors) {
409       if (env.getInstance() instanceof MasterObserver) {
410         ctx = ObserverContext.createAndPrepare(env, ctx);
411         Thread currentThread = Thread.currentThread();
412         ClassLoader cl = currentThread.getContextClassLoader();
413         try {
414           currentThread.setContextClassLoader(env.getClassLoader());
415           ((MasterObserver)env.getInstance()).preModifyTable(ctx, tableName, htd);
416         } catch (Throwable e) {
417           handleCoprocessorThrowable(env, e);
418         } finally {
419           currentThread.setContextClassLoader(cl);
420         }
421         if (ctx.shouldComplete()) {
422           break;
423         }
424       }
425     }
426   }
427 
428   public void postModifyTable(final TableName tableName, final HTableDescriptor htd)
429       throws IOException {
430     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
431     for (MasterEnvironment env: coprocessors) {
432       if (env.getInstance() instanceof MasterObserver) {
433         ctx = ObserverContext.createAndPrepare(env, ctx);
434         Thread currentThread = Thread.currentThread();
435         ClassLoader cl = currentThread.getContextClassLoader();
436         try {
437           currentThread.setContextClassLoader(env.getClassLoader());
438           ((MasterObserver)env.getInstance()).postModifyTable(ctx, tableName, htd);
439         } catch (Throwable e) {
440           handleCoprocessorThrowable(env, e);
441         } finally {
442           currentThread.setContextClassLoader(cl);
443         }
444         if (ctx.shouldComplete()) {
445           break;
446         }
447       }
448     }
449   }
450 
451   public void preModifyTableHandler(final TableName tableName, final HTableDescriptor htd)
452       throws IOException {
453     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
454     for (MasterEnvironment env : coprocessors) {
455       if (env.getInstance() instanceof MasterObserver) {
456         ctx = ObserverContext.createAndPrepare(env, ctx);
457         Thread currentThread = Thread.currentThread();
458         ClassLoader cl = currentThread.getContextClassLoader();
459         try {
460           currentThread.setContextClassLoader(env.getClassLoader());
461           ((MasterObserver) env.getInstance()).preModifyTableHandler(ctx, tableName, htd);
462         } catch (Throwable e) {
463           handleCoprocessorThrowable(env, e);
464         } finally {
465           currentThread.setContextClassLoader(cl);
466         }
467         if (ctx.shouldComplete()) {
468           break;
469         }
470       }
471     }
472   }
473 
474   public void postModifyTableHandler(final TableName tableName, final HTableDescriptor htd)
475       throws IOException {
476     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
477     for (MasterEnvironment env : coprocessors) {
478       if (env.getInstance() instanceof MasterObserver) {
479         ctx = ObserverContext.createAndPrepare(env, ctx);
480         Thread currentThread = Thread.currentThread();
481         ClassLoader cl = currentThread.getContextClassLoader();
482         try {
483           currentThread.setContextClassLoader(env.getClassLoader());
484           ((MasterObserver) env.getInstance()).postModifyTableHandler(ctx, tableName, htd);
485         } catch (Throwable e) {
486           handleCoprocessorThrowable(env, e);
487         } finally {
488           currentThread.setContextClassLoader(cl);
489         }
490         if (ctx.shouldComplete()) {
491           break;
492         }
493       }
494     }
495   }
496 
497   public boolean preAddColumn(final TableName tableName, final HColumnDescriptor column)
498       throws IOException {
499     boolean bypass = false;
500     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
501     for (MasterEnvironment env: coprocessors) {
502       if (env.getInstance() instanceof MasterObserver) {
503         ctx = ObserverContext.createAndPrepare(env, ctx);
504         Thread currentThread = Thread.currentThread();
505         ClassLoader cl = currentThread.getContextClassLoader();
506         try {
507           currentThread.setContextClassLoader(env.getClassLoader());
508           ((MasterObserver)env.getInstance()).preAddColumn(ctx, tableName, column);
509         } catch (Throwable e) {
510           handleCoprocessorThrowable(env, e);
511         } finally {
512           currentThread.setContextClassLoader(cl);
513         }
514         bypass |= ctx.shouldBypass();
515         if (ctx.shouldComplete()) {
516           break;
517         }
518       }
519     }
520     return bypass;
521   }
522 
523   public void postAddColumn(final TableName tableName, final HColumnDescriptor column)
524       throws IOException {
525     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
526     for (MasterEnvironment env: coprocessors) {
527       if (env.getInstance() instanceof MasterObserver) {
528         ctx = ObserverContext.createAndPrepare(env, ctx);
529         Thread currentThread = Thread.currentThread();
530         ClassLoader cl = currentThread.getContextClassLoader();
531         try {
532           currentThread.setContextClassLoader(env.getClassLoader());
533           ((MasterObserver)env.getInstance()).postAddColumn(ctx, tableName, column);
534         } catch (Throwable e) {
535           handleCoprocessorThrowable(env, e);
536         } finally {
537           currentThread.setContextClassLoader(cl);
538         }
539         if (ctx.shouldComplete()) {
540           break;
541         }
542       }
543     }
544   }
545 
546   public boolean preAddColumnHandler(final TableName tableName, final HColumnDescriptor column)
547       throws IOException {
548     boolean bypass = false;
549     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
550     for (MasterEnvironment env : coprocessors) {
551       if (env.getInstance() instanceof MasterObserver) {
552         ctx = ObserverContext.createAndPrepare(env, ctx);
553         Thread currentThread = Thread.currentThread();
554         ClassLoader cl = currentThread.getContextClassLoader();
555         try {
556           currentThread.setContextClassLoader(env.getClassLoader());
557           ((MasterObserver) env.getInstance()).preAddColumnHandler(ctx, tableName, column);
558         } catch (Throwable e) {
559           handleCoprocessorThrowable(env, e);
560         } finally {
561           currentThread.setContextClassLoader(cl);
562         }
563         bypass |= ctx.shouldBypass();
564         if (ctx.shouldComplete()) {
565           break;
566         }
567       }
568     }
569     return bypass;
570   }
571 
572   public void postAddColumnHandler(final TableName tableName, final HColumnDescriptor column)
573       throws IOException {
574     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
575     for (MasterEnvironment env : coprocessors) {
576       if (env.getInstance() instanceof MasterObserver) {
577         ctx = ObserverContext.createAndPrepare(env, ctx);
578         Thread currentThread = Thread.currentThread();
579         ClassLoader cl = currentThread.getContextClassLoader();
580         try {
581           currentThread.setContextClassLoader(env.getClassLoader());
582           ((MasterObserver) env.getInstance()).postAddColumnHandler(ctx, tableName, column);
583         } catch (Throwable e) {
584           handleCoprocessorThrowable(env, e);
585         } finally {
586           currentThread.setContextClassLoader(cl);
587         }
588         if (ctx.shouldComplete()) {
589           break;
590         }
591       }
592     }
593   }
594 
595   public boolean preModifyColumn(final TableName tableName, final HColumnDescriptor descriptor)
596       throws IOException {
597     boolean bypass = false;
598     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
599     for (MasterEnvironment env: coprocessors) {
600       if (env.getInstance() instanceof MasterObserver) {
601         ctx = ObserverContext.createAndPrepare(env, ctx);
602         Thread currentThread = Thread.currentThread();
603         ClassLoader cl = currentThread.getContextClassLoader();
604         try {
605           currentThread.setContextClassLoader(env.getClassLoader());
606           ((MasterObserver)env.getInstance()).preModifyColumn(ctx, tableName, descriptor);
607         } catch (Throwable e) {
608           handleCoprocessorThrowable(env, e);
609         } finally {
610           currentThread.setContextClassLoader(cl);
611         }
612         bypass |= ctx.shouldBypass();
613         if (ctx.shouldComplete()) {
614           break;
615         }
616       }
617     }
618     return bypass;
619   }
620 
621   public void postModifyColumn(final TableName tableName, final HColumnDescriptor descriptor)
622       throws IOException {
623     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
624     for (MasterEnvironment env: coprocessors) {
625       if (env.getInstance() instanceof MasterObserver) {
626         ctx = ObserverContext.createAndPrepare(env, ctx);
627         Thread currentThread = Thread.currentThread();
628         ClassLoader cl = currentThread.getContextClassLoader();
629         try {
630           currentThread.setContextClassLoader(env.getClassLoader());
631           ((MasterObserver)env.getInstance()).postModifyColumn(ctx, tableName, descriptor);
632         } catch (Throwable e) {
633           handleCoprocessorThrowable(env, e);
634         } finally {
635           currentThread.setContextClassLoader(cl);
636         }
637         if (ctx.shouldComplete()) {
638           break;
639         }
640       }
641     }
642   }
643 
644   public boolean preModifyColumnHandler(final TableName tableName,
645       final HColumnDescriptor descriptor) throws IOException {
646     boolean bypass = false;
647     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
648     for (MasterEnvironment env : coprocessors) {
649       if (env.getInstance() instanceof MasterObserver) {
650         ctx = ObserverContext.createAndPrepare(env, ctx);
651         Thread currentThread = Thread.currentThread();
652         ClassLoader cl = currentThread.getContextClassLoader();
653         try {
654           currentThread.setContextClassLoader(env.getClassLoader());
655           ((MasterObserver) env.getInstance()).preModifyColumnHandler(ctx, tableName, descriptor);
656         } catch (Throwable e) {
657           handleCoprocessorThrowable(env, e);
658         } finally {
659           currentThread.setContextClassLoader(cl);
660         }
661         bypass |= ctx.shouldBypass();
662         if (ctx.shouldComplete()) {
663           break;
664         }
665       }
666     }
667     return bypass;
668   }
669 
670   public void postModifyColumnHandler(final TableName tableName,
671       final HColumnDescriptor descriptor) throws IOException {
672     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
673     for (MasterEnvironment env : coprocessors) {
674       if (env.getInstance() instanceof MasterObserver) {
675         ctx = ObserverContext.createAndPrepare(env, ctx);
676         Thread currentThread = Thread.currentThread();
677         ClassLoader cl = currentThread.getContextClassLoader();
678         try {
679           currentThread.setContextClassLoader(env.getClassLoader());
680           ((MasterObserver) env.getInstance()).postModifyColumnHandler(ctx, tableName, descriptor);
681         } catch (Throwable e) {
682           handleCoprocessorThrowable(env, e);
683         } finally {
684           currentThread.setContextClassLoader(cl);
685         }
686         if (ctx.shouldComplete()) {
687           break;
688         }
689       }
690     }
691   }
692 
693   public boolean preDeleteColumn(final TableName tableName, final byte [] c) throws IOException {
694     boolean bypass = false;
695     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
696     for (MasterEnvironment env: coprocessors) {
697       if (env.getInstance() instanceof MasterObserver) {
698         ctx = ObserverContext.createAndPrepare(env, ctx);
699         Thread currentThread = Thread.currentThread();
700         ClassLoader cl = currentThread.getContextClassLoader();
701         try {
702           currentThread.setContextClassLoader(env.getClassLoader());
703           ((MasterObserver)env.getInstance()).preDeleteColumn(ctx, tableName, c);
704         } catch (Throwable e) {
705           handleCoprocessorThrowable(env, e);
706         } finally {
707           currentThread.setContextClassLoader(cl);
708         }
709         bypass |= ctx.shouldBypass();
710         if (ctx.shouldComplete()) {
711           break;
712         }
713       }
714     }
715     return bypass;
716   }
717 
718   public void postDeleteColumn(final TableName tableName, final byte [] c) throws IOException {
719     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
720     for (MasterEnvironment env: coprocessors) {
721       if (env.getInstance() instanceof MasterObserver) {
722         ctx = ObserverContext.createAndPrepare(env, ctx);
723         Thread currentThread = Thread.currentThread();
724         ClassLoader cl = currentThread.getContextClassLoader();
725         try {
726           currentThread.setContextClassLoader(env.getClassLoader());
727           ((MasterObserver)env.getInstance()).postDeleteColumn(ctx, tableName, c);
728         } catch (Throwable e) {
729           handleCoprocessorThrowable(env, e);
730         } finally {
731           currentThread.setContextClassLoader(cl);
732         }
733         if (ctx.shouldComplete()) {
734           break;
735         }
736       }
737     }
738   }
739 
740   public boolean preDeleteColumnHandler(final TableName tableName, final byte[] c)
741       throws IOException {
742     boolean bypass = false;
743     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
744     for (MasterEnvironment env : coprocessors) {
745       if (env.getInstance() instanceof MasterObserver) {
746         ctx = ObserverContext.createAndPrepare(env, ctx);
747         Thread currentThread = Thread.currentThread();
748         ClassLoader cl = currentThread.getContextClassLoader();
749         try {
750           currentThread.setContextClassLoader(env.getClassLoader());
751           ((MasterObserver) env.getInstance()).preDeleteColumnHandler(ctx, tableName, c);
752         } catch (Throwable e) {
753           handleCoprocessorThrowable(env, e);
754         } finally {
755           currentThread.setContextClassLoader(cl);
756         }
757         bypass |= ctx.shouldBypass();
758         if (ctx.shouldComplete()) {
759           break;
760         }
761       }
762     }
763     return bypass;
764   }
765 
766   public void postDeleteColumnHandler(final TableName tableName, final byte[] c)
767       throws IOException {
768     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
769     for (MasterEnvironment env : coprocessors) {
770       if (env.getInstance() instanceof MasterObserver) {
771         ctx = ObserverContext.createAndPrepare(env, ctx);
772         Thread currentThread = Thread.currentThread();
773         ClassLoader cl = currentThread.getContextClassLoader();
774         try {
775           currentThread.setContextClassLoader(env.getClassLoader());
776           ((MasterObserver) env.getInstance()).postDeleteColumnHandler(ctx, tableName, c);
777         } catch (Throwable e) {
778           handleCoprocessorThrowable(env, e);
779         } finally {
780           currentThread.setContextClassLoader(cl);
781         }
782         if (ctx.shouldComplete()) {
783           break;
784         }
785       }
786     }
787   }
788 
789   public void preEnableTable(final TableName tableName) throws IOException {
790     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
791     for (MasterEnvironment env: coprocessors) {
792       if (env.getInstance() instanceof MasterObserver) {
793         ctx = ObserverContext.createAndPrepare(env, ctx);
794         Thread currentThread = Thread.currentThread();
795         ClassLoader cl = currentThread.getContextClassLoader();
796         try {
797           currentThread.setContextClassLoader(env.getClassLoader());
798           ((MasterObserver)env.getInstance()).preEnableTable(ctx, tableName);
799         } catch (Throwable e) {
800           handleCoprocessorThrowable(env, e);
801         } finally {
802           currentThread.setContextClassLoader(cl);
803         }
804         if (ctx.shouldComplete()) {
805           break;
806         }
807       }
808     }
809   }
810 
811   public void postEnableTable(final TableName tableName) throws IOException {
812     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
813     for (MasterEnvironment env: coprocessors) {
814       if (env.getInstance() instanceof MasterObserver) {
815         ctx = ObserverContext.createAndPrepare(env, ctx);
816         Thread currentThread = Thread.currentThread();
817         ClassLoader cl = currentThread.getContextClassLoader();
818         try {
819           currentThread.setContextClassLoader(env.getClassLoader());
820           ((MasterObserver)env.getInstance()).postEnableTable(ctx, tableName);
821         } catch (Throwable e) {
822           handleCoprocessorThrowable(env, e);
823         } finally {
824           currentThread.setContextClassLoader(cl);
825         }
826         if (ctx.shouldComplete()) {
827           break;
828         }
829       }
830     }
831   }
832 
833   public void preEnableTableHandler(final TableName tableName) throws IOException {
834     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
835     for (MasterEnvironment env : coprocessors) {
836       if (env.getInstance() instanceof MasterObserver) {
837         ctx = ObserverContext.createAndPrepare(env, ctx);
838         Thread currentThread = Thread.currentThread();
839         ClassLoader cl = currentThread.getContextClassLoader();
840         try {
841           currentThread.setContextClassLoader(env.getClassLoader());
842           ((MasterObserver) env.getInstance()).preEnableTableHandler(ctx, tableName);
843         } catch (Throwable e) {
844           handleCoprocessorThrowable(env, e);
845         } finally {
846           currentThread.setContextClassLoader(cl);
847         }
848         if (ctx.shouldComplete()) {
849           break;
850         }
851       }
852     }
853   }
854 
855   public void postEnableTableHandler(final TableName tableName) throws IOException {
856     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
857     for (MasterEnvironment env : coprocessors) {
858       if (env.getInstance() instanceof MasterObserver) {
859         ctx = ObserverContext.createAndPrepare(env, ctx);
860         Thread currentThread = Thread.currentThread();
861         ClassLoader cl = currentThread.getContextClassLoader();
862         try {
863           currentThread.setContextClassLoader(env.getClassLoader());
864           ((MasterObserver) env.getInstance()).postEnableTableHandler(ctx, tableName);
865         } catch (Throwable e) {
866           handleCoprocessorThrowable(env, e);
867         } finally {
868           currentThread.setContextClassLoader(cl);
869         }
870         if (ctx.shouldComplete()) {
871           break;
872         }
873       }
874     }
875   }
876 
877   public void preDisableTable(final TableName tableName) throws IOException {
878     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
879     for (MasterEnvironment env: coprocessors) {
880       if (env.getInstance() instanceof MasterObserver) {
881         ctx = ObserverContext.createAndPrepare(env, ctx);
882         Thread currentThread = Thread.currentThread();
883         ClassLoader cl = currentThread.getContextClassLoader();
884         try {
885           currentThread.setContextClassLoader(env.getClassLoader());
886           ((MasterObserver)env.getInstance()).preDisableTable(ctx, tableName);
887         } catch (Throwable e) {
888           handleCoprocessorThrowable(env, e);
889         } finally {
890           currentThread.setContextClassLoader(cl);
891         }
892         if (ctx.shouldComplete()) {
893           break;
894         }
895       }
896     }
897   }
898 
899   public void postDisableTable(final TableName tableName) throws IOException {
900     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
901     for (MasterEnvironment env: coprocessors) {
902       if (env.getInstance() instanceof MasterObserver) {
903         ctx = ObserverContext.createAndPrepare(env, ctx);
904         Thread currentThread = Thread.currentThread();
905         ClassLoader cl = currentThread.getContextClassLoader();
906         try {
907           currentThread.setContextClassLoader(env.getClassLoader());
908           ((MasterObserver)env.getInstance()).postDisableTable(ctx, tableName);
909         } catch (Throwable e) {
910           handleCoprocessorThrowable(env, e);
911         } finally {
912           currentThread.setContextClassLoader(cl);
913         }
914         if (ctx.shouldComplete()) {
915           break;
916         }
917       }
918     }
919   }
920 
921   public void preDisableTableHandler(final TableName tableName) throws IOException {
922     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
923     for (MasterEnvironment env : coprocessors) {
924       if (env.getInstance() instanceof MasterObserver) {
925         ctx = ObserverContext.createAndPrepare(env, ctx);
926         Thread currentThread = Thread.currentThread();
927         ClassLoader cl = currentThread.getContextClassLoader();
928         try {
929           currentThread.setContextClassLoader(env.getClassLoader());
930           ((MasterObserver) env.getInstance()).preDisableTableHandler(ctx, tableName);
931         } catch (Throwable e) {
932           handleCoprocessorThrowable(env, e);
933         } finally {
934           currentThread.setContextClassLoader(cl);
935         }
936         if (ctx.shouldComplete()) {
937           break;
938         }
939       }
940     }
941   }
942 
943   public void postDisableTableHandler(final TableName tableName) throws IOException {
944     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
945     for (MasterEnvironment env : coprocessors) {
946       if (env.getInstance() instanceof MasterObserver) {
947         ctx = ObserverContext.createAndPrepare(env, ctx);
948         Thread currentThread = Thread.currentThread();
949         ClassLoader cl = currentThread.getContextClassLoader();
950         try {
951           currentThread.setContextClassLoader(env.getClassLoader());
952           ((MasterObserver) env.getInstance()).postDisableTableHandler(ctx, tableName);
953         } catch (Throwable e) {
954           handleCoprocessorThrowable(env, e);
955         } finally {
956           currentThread.setContextClassLoader(cl);
957         }
958         if (ctx.shouldComplete()) {
959           break;
960         }
961       }
962     }
963   }
964 
965   public boolean preMove(final HRegionInfo region, final ServerName srcServer,
966       final ServerName destServer) throws IOException {
967     boolean bypass = false;
968     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
969     for (MasterEnvironment env: coprocessors) {
970       if (env.getInstance() instanceof MasterObserver) {
971         ctx = ObserverContext.createAndPrepare(env, ctx);
972         Thread currentThread = Thread.currentThread();
973         ClassLoader cl = currentThread.getContextClassLoader();
974         try {
975           currentThread.setContextClassLoader(env.getClassLoader());
976           ((MasterObserver)env.getInstance()).preMove(ctx, region, srcServer, destServer);
977         } catch (Throwable e) {
978           handleCoprocessorThrowable(env, e);
979         } finally {
980           currentThread.setContextClassLoader(cl);
981         }
982         bypass |= ctx.shouldBypass();
983         if (ctx.shouldComplete()) {
984           break;
985         }
986       }
987     }
988     return bypass;
989   }
990 
991   public void postMove(final HRegionInfo region, final ServerName srcServer,
992       final ServerName destServer) throws IOException {
993     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
994     for (MasterEnvironment env: coprocessors) {
995       if (env.getInstance() instanceof MasterObserver) {
996         ctx = ObserverContext.createAndPrepare(env, ctx);
997         Thread currentThread = Thread.currentThread();
998         ClassLoader cl = currentThread.getContextClassLoader();
999         try {
1000           currentThread.setContextClassLoader(env.getClassLoader());
1001           ((MasterObserver)env.getInstance()).postMove(ctx, region, srcServer, destServer);
1002         } catch (Throwable e) {
1003           handleCoprocessorThrowable(env, e);
1004         } finally {
1005           currentThread.setContextClassLoader(cl);
1006         }
1007         if (ctx.shouldComplete()) {
1008           break;
1009         }
1010       }
1011     }
1012   }
1013 
1014   public boolean preAssign(final HRegionInfo regionInfo) throws IOException {
1015     boolean bypass = false;
1016     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
1017     for (MasterEnvironment env: coprocessors) {
1018       if (env.getInstance() instanceof MasterObserver) {
1019         ctx = ObserverContext.createAndPrepare(env, ctx);
1020         Thread currentThread = Thread.currentThread();
1021         ClassLoader cl = currentThread.getContextClassLoader();
1022         try {
1023           currentThread.setContextClassLoader(env.getClassLoader());
1024           ((MasterObserver) env.getInstance()).preAssign(ctx, regionInfo);
1025         } catch (Throwable e) {
1026           handleCoprocessorThrowable(env, e);
1027         } finally {
1028           currentThread.setContextClassLoader(cl);
1029         }
1030         bypass |= ctx.shouldBypass();
1031         if (ctx.shouldComplete()) {
1032           break;
1033         }
1034       }
1035     }
1036     return bypass;
1037   }
1038 
1039   public void postAssign(final HRegionInfo regionInfo) throws IOException {
1040     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
1041     for (MasterEnvironment env: coprocessors) {
1042       if (env.getInstance() instanceof MasterObserver) {
1043         ctx = ObserverContext.createAndPrepare(env, ctx);
1044         Thread currentThread = Thread.currentThread();
1045         ClassLoader cl = currentThread.getContextClassLoader();
1046         try {
1047           currentThread.setContextClassLoader(env.getClassLoader());
1048           ((MasterObserver)env.getInstance()).postAssign(ctx, regionInfo);
1049         } catch (Throwable e) {
1050           handleCoprocessorThrowable(env, e);
1051         } finally {
1052           currentThread.setContextClassLoader(cl);
1053         }
1054         if (ctx.shouldComplete()) {
1055           break;
1056         }
1057       }
1058     }
1059   }
1060 
1061   public boolean preUnassign(final HRegionInfo regionInfo, final boolean force)
1062       throws IOException {
1063     boolean bypass = false;
1064     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
1065     for (MasterEnvironment env: coprocessors) {
1066       if (env.getInstance() instanceof MasterObserver) {
1067         ctx = ObserverContext.createAndPrepare(env, ctx);
1068         Thread currentThread = Thread.currentThread();
1069         ClassLoader cl = currentThread.getContextClassLoader();
1070         try {
1071           currentThread.setContextClassLoader(env.getClassLoader());
1072           ((MasterObserver)env.getInstance()).preUnassign(ctx, regionInfo, force);
1073         } catch (Throwable e) {
1074           handleCoprocessorThrowable(env, e);
1075         } finally {
1076           currentThread.setContextClassLoader(cl);
1077         }
1078         bypass |= ctx.shouldBypass();
1079         if (ctx.shouldComplete()) {
1080           break;
1081         }
1082       }
1083     }
1084     return bypass;
1085   }
1086 
1087   public void postUnassign(final HRegionInfo regionInfo, final boolean force) throws IOException {
1088     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
1089     for (MasterEnvironment env: coprocessors) {
1090       if (env.getInstance() instanceof MasterObserver) {
1091         ctx = ObserverContext.createAndPrepare(env, ctx);
1092         Thread currentThread = Thread.currentThread();
1093         ClassLoader cl = currentThread.getContextClassLoader();
1094         try {
1095           currentThread.setContextClassLoader(env.getClassLoader());
1096           ((MasterObserver)env.getInstance()).postUnassign(ctx, regionInfo, force);
1097         } catch (Throwable e) {
1098           handleCoprocessorThrowable(env, e);
1099         } finally {
1100           currentThread.setContextClassLoader(cl);
1101         }
1102         if (ctx.shouldComplete()) {
1103           break;
1104         }
1105       }
1106     }
1107   }
1108 
1109   public void preRegionOffline(final HRegionInfo regionInfo) throws IOException {
1110     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
1111     for (MasterEnvironment env : coprocessors) {
1112       if (env.getInstance() instanceof MasterObserver) {
1113         ctx = ObserverContext.createAndPrepare(env, ctx);
1114         Thread currentThread = Thread.currentThread();
1115         ClassLoader cl = currentThread.getContextClassLoader();
1116         try {
1117           currentThread.setContextClassLoader(env.getClassLoader());
1118           ((MasterObserver) env.getInstance()).preRegionOffline(ctx, regionInfo);
1119         } catch (Throwable e) {
1120           handleCoprocessorThrowable(env, e);
1121         } finally {
1122           currentThread.setContextClassLoader(cl);
1123         }
1124         if (ctx.shouldComplete()) {
1125           break;
1126         }
1127       }
1128     }
1129   }
1130 
1131   public void postRegionOffline(final HRegionInfo regionInfo) throws IOException {
1132     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
1133     for (MasterEnvironment env : coprocessors) {
1134       if (env.getInstance() instanceof MasterObserver) {
1135         ctx = ObserverContext.createAndPrepare(env, ctx);
1136         Thread currentThread = Thread.currentThread();
1137         ClassLoader cl = currentThread.getContextClassLoader();
1138         try {
1139           currentThread.setContextClassLoader(env.getClassLoader());
1140           ((MasterObserver) env.getInstance()).postRegionOffline(ctx, regionInfo);
1141         } catch (Throwable e) {
1142           handleCoprocessorThrowable(env, e);
1143         } finally {
1144           currentThread.setContextClassLoader(cl);
1145         }
1146         if (ctx.shouldComplete()) {
1147           break;
1148         }
1149       }
1150     }
1151   }
1152 
1153   public boolean preBalance() throws IOException {
1154     boolean bypass = false;
1155     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
1156     for (MasterEnvironment env: coprocessors) {
1157       if (env.getInstance() instanceof MasterObserver) {
1158         ctx = ObserverContext.createAndPrepare(env, ctx);
1159         Thread currentThread = Thread.currentThread();
1160         ClassLoader cl = currentThread.getContextClassLoader();
1161         try {
1162           currentThread.setContextClassLoader(env.getClassLoader());
1163           ((MasterObserver)env.getInstance()).preBalance(ctx);
1164         } catch (Throwable e) {
1165           handleCoprocessorThrowable(env, e);
1166         } finally {
1167           currentThread.setContextClassLoader(cl);
1168         }
1169         bypass |= ctx.shouldBypass();
1170         if (ctx.shouldComplete()) {
1171           break;
1172         }
1173       }
1174     }
1175     return bypass;
1176   }
1177 
1178   public void postBalance(final List<RegionPlan> plans) throws IOException {
1179     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
1180     for (MasterEnvironment env: coprocessors) {
1181       if (env.getInstance() instanceof MasterObserver) {
1182         ctx = ObserverContext.createAndPrepare(env, ctx);
1183         Thread currentThread = Thread.currentThread();
1184         ClassLoader cl = currentThread.getContextClassLoader();
1185         try {
1186           currentThread.setContextClassLoader(env.getClassLoader());
1187           ((MasterObserver)env.getInstance()).postBalance(ctx, plans);
1188         } catch (Throwable e) {
1189           handleCoprocessorThrowable(env, e);
1190         } finally {
1191           currentThread.setContextClassLoader(cl);
1192         }
1193         if (ctx.shouldComplete()) {
1194           break;
1195         }
1196       }
1197     }
1198   }
1199 
1200   public boolean preBalanceSwitch(final boolean b) throws IOException {
1201     boolean balance = b;
1202     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
1203     for (MasterEnvironment env: coprocessors) {
1204       if (env.getInstance() instanceof MasterObserver) {
1205         ctx = ObserverContext.createAndPrepare(env, ctx);
1206         Thread currentThread = Thread.currentThread();
1207         ClassLoader cl = currentThread.getContextClassLoader();
1208         try {
1209           currentThread.setContextClassLoader(env.getClassLoader());
1210           balance = ((MasterObserver)env.getInstance()).preBalanceSwitch(ctx, balance);
1211         } catch (Throwable e) {
1212           handleCoprocessorThrowable(env, e);
1213         } finally {
1214           currentThread.setContextClassLoader(cl);
1215         }
1216         if (ctx.shouldComplete()) {
1217           break;
1218         }
1219       }
1220     }
1221     return balance;
1222   }
1223 
1224   void postBalanceSwitch(final boolean oldValue, final boolean newValue)
1225       throws IOException {
1226     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
1227     for (MasterEnvironment env: coprocessors) {
1228       if (env.getInstance() instanceof MasterObserver) {
1229         ctx = ObserverContext.createAndPrepare(env, ctx);
1230         Thread currentThread = Thread.currentThread();
1231         ClassLoader cl = currentThread.getContextClassLoader();
1232         try {
1233           currentThread.setContextClassLoader(env.getClassLoader());
1234           ((MasterObserver)env.getInstance()).postBalanceSwitch(ctx, oldValue, newValue);
1235         } catch (Throwable e) {
1236           handleCoprocessorThrowable(env, e);
1237         } finally {
1238           currentThread.setContextClassLoader(cl);
1239         }
1240         if (ctx.shouldComplete()) {
1241           break;
1242         }
1243       }
1244     }
1245   }
1246 
1247   public void preShutdown() throws IOException {
1248     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
1249     for (MasterEnvironment env: coprocessors) {
1250       if (env.getInstance() instanceof MasterObserver) {
1251         ctx = ObserverContext.createAndPrepare(env, ctx);
1252         Thread currentThread = Thread.currentThread();
1253         ClassLoader cl = currentThread.getContextClassLoader();
1254         try {
1255           currentThread.setContextClassLoader(env.getClassLoader());
1256           ((MasterObserver)env.getInstance()).preShutdown(ctx);
1257         } catch (Throwable e) {
1258           handleCoprocessorThrowable(env, e);
1259         } finally {
1260           currentThread.setContextClassLoader(cl);
1261         }
1262         if (ctx.shouldComplete()) {
1263           break;
1264         }
1265       }
1266       // invoke coprocessor stop method
1267       shutdown(env);
1268     }
1269   }
1270 
1271   public void preStopMaster() throws IOException {
1272     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
1273     for (MasterEnvironment env: coprocessors) {
1274       if (env.getInstance() instanceof MasterObserver) {
1275         ctx = ObserverContext.createAndPrepare(env, ctx);
1276         Thread currentThread = Thread.currentThread();
1277         ClassLoader cl = currentThread.getContextClassLoader();
1278         try {
1279           currentThread.setContextClassLoader(env.getClassLoader());
1280           ((MasterObserver)env.getInstance()).preStopMaster(ctx);
1281         } catch (Throwable e) {
1282           handleCoprocessorThrowable(env, e);
1283         } finally {
1284           currentThread.setContextClassLoader(cl);
1285         }
1286         if (ctx.shouldComplete()) {
1287           break;
1288         }
1289       }
1290       // invoke coprocessor stop method
1291       shutdown(env);
1292     }
1293   }
1294 
1295   public void preMasterInitialization() throws IOException {
1296     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
1297     for (MasterEnvironment env : coprocessors) {
1298       if (env.getInstance() instanceof MasterObserver) {
1299         ctx = ObserverContext.createAndPrepare(env, ctx);
1300         Thread currentThread = Thread.currentThread();
1301         ClassLoader cl = currentThread.getContextClassLoader();
1302         try {
1303           currentThread.setContextClassLoader(env.getClassLoader());
1304           ((MasterObserver) env.getInstance()).preMasterInitialization(ctx);
1305         } catch (Throwable e) {
1306           handleCoprocessorThrowable(env, e);
1307         } finally {
1308           currentThread.setContextClassLoader(cl);
1309         }
1310         if (ctx.shouldComplete()) {
1311           break;
1312         }
1313       }
1314     }
1315   }
1316 
1317   public void postStartMaster() throws IOException {
1318     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
1319     for (MasterEnvironment env: coprocessors) {
1320       if (env.getInstance() instanceof MasterObserver) {
1321         ctx = ObserverContext.createAndPrepare(env, ctx);
1322         Thread currentThread = Thread.currentThread();
1323         ClassLoader cl = currentThread.getContextClassLoader();
1324         try {
1325           currentThread.setContextClassLoader(env.getClassLoader());
1326           ((MasterObserver)env.getInstance()).postStartMaster(ctx);
1327         } catch (Throwable e) {
1328           handleCoprocessorThrowable(env, e);
1329         } finally {
1330           currentThread.setContextClassLoader(cl);
1331         }
1332         if (ctx.shouldComplete()) {
1333           break;
1334         }
1335       }
1336     }
1337   }
1338 
1339   public void preSnapshot(final SnapshotDescription snapshot,
1340       final HTableDescriptor hTableDescriptor) throws IOException {
1341     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
1342     for (MasterEnvironment env: coprocessors) {
1343       if (env.getInstance() instanceof MasterObserver) {
1344         ctx = ObserverContext.createAndPrepare(env, ctx);
1345         Thread currentThread = Thread.currentThread();
1346         ClassLoader cl = currentThread.getContextClassLoader();
1347         try {
1348           currentThread.setContextClassLoader(env.getClassLoader());
1349           ((MasterObserver)env.getInstance()).preSnapshot(ctx, snapshot, hTableDescriptor);
1350         } catch (Throwable e) {
1351           handleCoprocessorThrowable(env, e);
1352         } finally {
1353           currentThread.setContextClassLoader(cl);
1354         }
1355         if (ctx.shouldComplete()) {
1356           break;
1357         }
1358       }
1359     }
1360   }
1361 
1362   public void postSnapshot(final SnapshotDescription snapshot,
1363       final HTableDescriptor hTableDescriptor) throws IOException {
1364     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
1365     for (MasterEnvironment env: coprocessors) {
1366       if (env.getInstance() instanceof MasterObserver) {
1367         ctx = ObserverContext.createAndPrepare(env, ctx);
1368         Thread currentThread = Thread.currentThread();
1369         ClassLoader cl = currentThread.getContextClassLoader();
1370         try {
1371           currentThread.setContextClassLoader(env.getClassLoader());
1372           ((MasterObserver)env.getInstance()).postSnapshot(ctx, snapshot, hTableDescriptor);
1373         } catch (Throwable e) {
1374           handleCoprocessorThrowable(env, e);
1375         } finally {
1376           currentThread.setContextClassLoader(cl);
1377         }
1378         if (ctx.shouldComplete()) {
1379           break;
1380         }
1381       }
1382     }
1383   }
1384 
1385   public void preCloneSnapshot(final SnapshotDescription snapshot,
1386       final HTableDescriptor hTableDescriptor) throws IOException {
1387     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
1388     for (MasterEnvironment env: coprocessors) {
1389       if (env.getInstance() instanceof MasterObserver) {
1390         ctx = ObserverContext.createAndPrepare(env, ctx);
1391         Thread currentThread = Thread.currentThread();
1392         ClassLoader cl = currentThread.getContextClassLoader();
1393         try {
1394           currentThread.setContextClassLoader(env.getClassLoader());
1395           ((MasterObserver)env.getInstance()).preCloneSnapshot(ctx, snapshot,
1396             hTableDescriptor);
1397         } catch (Throwable e) {
1398           handleCoprocessorThrowable(env, e);
1399         } finally {
1400           currentThread.setContextClassLoader(cl);
1401         }
1402         if (ctx.shouldComplete()) {
1403           break;
1404         }
1405       }
1406     }
1407   }
1408 
1409   public void postCloneSnapshot(final SnapshotDescription snapshot,
1410       final HTableDescriptor hTableDescriptor) throws IOException {
1411     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
1412     for (MasterEnvironment env: coprocessors) {
1413       if (env.getInstance() instanceof MasterObserver) {
1414         ctx = ObserverContext.createAndPrepare(env, ctx);
1415         Thread currentThread = Thread.currentThread();
1416         ClassLoader cl = currentThread.getContextClassLoader();
1417         try {
1418           currentThread.setContextClassLoader(env.getClassLoader());
1419           ((MasterObserver)env.getInstance()).postCloneSnapshot(ctx, snapshot,
1420             hTableDescriptor);
1421         } catch (Throwable e) {
1422           handleCoprocessorThrowable(env, e);
1423         } finally {
1424           currentThread.setContextClassLoader(cl);
1425         }
1426         if (ctx.shouldComplete()) {
1427           break;
1428         }
1429       }
1430     }
1431   }
1432 
1433   public void preRestoreSnapshot(final SnapshotDescription snapshot,
1434       final HTableDescriptor hTableDescriptor) throws IOException {
1435     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
1436     for (MasterEnvironment env: coprocessors) {
1437       if (env.getInstance() instanceof MasterObserver) {
1438         ctx = ObserverContext.createAndPrepare(env, ctx);
1439         Thread currentThread = Thread.currentThread();
1440         ClassLoader cl = currentThread.getContextClassLoader();
1441         try {
1442           currentThread.setContextClassLoader(env.getClassLoader());
1443           ((MasterObserver)env.getInstance()).preRestoreSnapshot(ctx, snapshot,
1444             hTableDescriptor);
1445         } catch (Throwable e) {
1446           handleCoprocessorThrowable(env, e);
1447         } finally {
1448           currentThread.setContextClassLoader(cl);
1449         }
1450         if (ctx.shouldComplete()) {
1451           break;
1452         }
1453       }
1454     }
1455   }
1456 
1457   public void postRestoreSnapshot(final SnapshotDescription snapshot,
1458       final HTableDescriptor hTableDescriptor) throws IOException {
1459     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
1460     for (MasterEnvironment env: coprocessors) {
1461       if (env.getInstance() instanceof MasterObserver) {
1462         ctx = ObserverContext.createAndPrepare(env, ctx);
1463         Thread currentThread = Thread.currentThread();
1464         ClassLoader cl = currentThread.getContextClassLoader();
1465         try {
1466           currentThread.setContextClassLoader(env.getClassLoader());
1467           ((MasterObserver)env.getInstance()).postRestoreSnapshot(ctx, snapshot,
1468             hTableDescriptor);
1469         } catch (Throwable e) {
1470           handleCoprocessorThrowable(env, e);
1471         } finally {
1472           currentThread.setContextClassLoader(cl);
1473         }
1474         if (ctx.shouldComplete()) {
1475           break;
1476         }
1477       }
1478     }
1479   }
1480 
1481   public void preDeleteSnapshot(final SnapshotDescription snapshot) throws IOException {
1482     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
1483     for (MasterEnvironment env: coprocessors) {
1484       if (env.getInstance() instanceof MasterObserver) {
1485         ctx = ObserverContext.createAndPrepare(env, ctx);
1486         Thread currentThread = Thread.currentThread();
1487         ClassLoader cl = currentThread.getContextClassLoader();
1488         try {
1489           currentThread.setContextClassLoader(env.getClassLoader());
1490           ((MasterObserver)env.getInstance()).preDeleteSnapshot(ctx, snapshot);
1491         } catch (Throwable e) {
1492           handleCoprocessorThrowable(env, e);
1493         } finally {
1494           currentThread.setContextClassLoader(cl);
1495         }
1496         if (ctx.shouldComplete()) {
1497           break;
1498         }
1499       }
1500     }
1501   }
1502 
1503   public void postDeleteSnapshot(final SnapshotDescription snapshot) throws IOException {
1504     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
1505     for (MasterEnvironment env: coprocessors) {
1506       if (env.getInstance() instanceof MasterObserver) {
1507         ctx = ObserverContext.createAndPrepare(env, ctx);
1508         Thread currentThread = Thread.currentThread();
1509         ClassLoader cl = currentThread.getContextClassLoader();
1510         try {
1511           currentThread.setContextClassLoader(env.getClassLoader());
1512           ((MasterObserver)env.getInstance()).postDeleteSnapshot(ctx, snapshot);
1513         } catch (Throwable e) {
1514           handleCoprocessorThrowable(env, e);
1515         } finally {
1516           currentThread.setContextClassLoader(cl);
1517         }
1518         if (ctx.shouldComplete()) {
1519           break;
1520         }
1521       }
1522     }
1523   }
1524 
1525   public boolean preGetTableDescriptors(final List<TableName> tableNamesList,
1526       final List<HTableDescriptor> descriptors) throws IOException {
1527     boolean bypass = false;
1528     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
1529     for (MasterEnvironment env : coprocessors) {
1530       if (env.getInstance() instanceof MasterObserver) {
1531         ctx = ObserverContext.createAndPrepare(env, ctx);
1532         Thread currentThread = Thread.currentThread();
1533         ClassLoader cl = currentThread.getContextClassLoader();
1534         try {
1535           currentThread.setContextClassLoader(env.getClassLoader());
1536           ((MasterObserver) env.getInstance()).preGetTableDescriptors(ctx,
1537             tableNamesList, descriptors);
1538         } catch (Throwable e) {
1539           handleCoprocessorThrowable(env, e);
1540         } finally {
1541           currentThread.setContextClassLoader(cl);
1542         }
1543         bypass |= ctx.shouldBypass();
1544         if (ctx.shouldComplete()) {
1545           break;
1546         }
1547       }
1548     }
1549     return bypass;
1550   }
1551 
1552   public void postGetTableDescriptors(final List<HTableDescriptor> descriptors)
1553       throws IOException {
1554     ObserverContext<MasterCoprocessorEnvironment> ctx = null;
1555     for (MasterEnvironment env: coprocessors) {
1556       if (env.getInstance() instanceof MasterObserver) {
1557         ctx = ObserverContext.createAndPrepare(env, ctx);
1558         Thread currentThread = Thread.currentThread();
1559         ClassLoader cl = currentThread.getContextClassLoader();
1560         try {
1561           currentThread.setContextClassLoader(env.getClassLoader());
1562           ((MasterObserver)env.getInstance()).postGetTableDescriptors(ctx, descriptors);
1563         } catch (Throwable e) {
1564           handleCoprocessorThrowable(env, e);
1565         } finally {
1566           currentThread.setContextClassLoader(cl);
1567         }
1568         if (ctx.shouldComplete()) {
1569           break;
1570         }
1571       }
1572     }
1573   }
1574 
1575 }