1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.hadoop.hbase.master;
21
22 import java.io.IOException;
23 import java.util.List;
24
25 import org.apache.commons.logging.Log;
26 import org.apache.commons.logging.LogFactory;
27 import org.apache.hadoop.conf.Configuration;
28 import org.apache.hadoop.hbase.Coprocessor;
29 import org.apache.hadoop.hbase.HColumnDescriptor;
30 import org.apache.hadoop.hbase.HRegionInfo;
31 import org.apache.hadoop.hbase.HTableDescriptor;
32 import org.apache.hadoop.hbase.NamespaceDescriptor;
33 import org.apache.hadoop.hbase.ServerName;
34 import org.apache.hadoop.hbase.TableName;
35 import org.apache.hadoop.hbase.classification.InterfaceAudience;
36 import org.apache.hadoop.hbase.coprocessor.*;
37 import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.SnapshotDescription;
38
39 import java.io.IOException;
40 import java.util.List;
41
42
43
44
45
46
47 @InterfaceAudience.Private
48 public class MasterCoprocessorHost
49 extends CoprocessorHost<MasterCoprocessorHost.MasterEnvironment> {
50
51 private static final Log LOG = LogFactory.getLog(MasterCoprocessorHost.class);
52
53
54
55
56
57 static class MasterEnvironment extends CoprocessorHost.Environment
58 implements MasterCoprocessorEnvironment {
59 private MasterServices masterServices;
60
61 public MasterEnvironment(final Class<?> implClass, final Coprocessor impl,
62 final int priority, final int seq, final Configuration conf,
63 final MasterServices services) {
64 super(impl, priority, seq, conf);
65 this.masterServices = services;
66 }
67
68 public MasterServices getMasterServices() {
69 return masterServices;
70 }
71 }
72
73 private MasterServices masterServices;
74
75 public MasterCoprocessorHost(final MasterServices services, final Configuration conf) {
76 super(services);
77 this.conf = conf;
78 this.masterServices = services;
79
80
81
82 boolean coprocessorsEnabled = conf.getBoolean(COPROCESSORS_ENABLED_CONF_KEY,
83 DEFAULT_COPROCESSORS_ENABLED);
84 LOG.info("System coprocessor loading is " + (coprocessorsEnabled ? "enabled" : "disabled"));
85 loadSystemCoprocessors(conf, MASTER_COPROCESSOR_CONF_KEY);
86 }
87
88 @Override
89 public MasterEnvironment createEnvironment(final Class<?> implClass,
90 final Coprocessor instance, final int priority, final int seq,
91 final Configuration conf) {
92 for (Class<?> c : implClass.getInterfaces()) {
93 if (CoprocessorService.class.isAssignableFrom(c)) {
94 masterServices.registerService(((CoprocessorService)instance).getService());
95 }
96 }
97 return new MasterEnvironment(implClass, instance, priority, seq, conf,
98 masterServices);
99 }
100
101 public boolean preCreateNamespace(final NamespaceDescriptor ns) throws IOException {
102 return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
103 @Override
104 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
105 throws IOException {
106 oserver.preCreateNamespace(ctx, ns);
107 }
108 });
109 }
110
111 public void postCreateNamespace(final NamespaceDescriptor ns) throws IOException {
112 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
113 @Override
114 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
115 throws IOException {
116 oserver.postCreateNamespace(ctx, ns);
117 }
118 });
119 }
120
121 public boolean preDeleteNamespace(final String namespaceName) throws IOException {
122 return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
123 @Override
124 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
125 throws IOException {
126 oserver.preDeleteNamespace(ctx, namespaceName);
127 }
128 });
129 }
130
131 public void postDeleteNamespace(final String namespaceName) throws IOException {
132 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
133 @Override
134 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
135 throws IOException {
136 oserver.postDeleteNamespace(ctx, namespaceName);
137 }
138 });
139 }
140
141 public boolean preModifyNamespace(final NamespaceDescriptor ns) throws IOException {
142 return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
143 @Override
144 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
145 throws IOException {
146 oserver.preModifyNamespace(ctx, ns);
147 }
148 });
149 }
150
151 public void postModifyNamespace(final NamespaceDescriptor ns) throws IOException {
152 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
153 @Override
154 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
155 throws IOException {
156 oserver.postModifyNamespace(ctx, ns);
157 }
158 });
159 }
160
161 public void preGetNamespaceDescriptor(final String namespaceName)
162 throws IOException {
163 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
164 @Override
165 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
166 throws IOException {
167 oserver.preGetNamespaceDescriptor(ctx, namespaceName);
168 }
169 });
170 }
171
172 public void postGetNamespaceDescriptor(final NamespaceDescriptor ns)
173 throws IOException {
174 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
175 @Override
176 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
177 throws IOException {
178 oserver.postGetNamespaceDescriptor(ctx, ns);
179 }
180 });
181 }
182
183 public boolean preListNamespaceDescriptors(final List<NamespaceDescriptor> descriptors)
184 throws IOException {
185 return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
186 @Override
187 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
188 throws IOException {
189 oserver.preListNamespaceDescriptors(ctx, descriptors);
190 }
191 });
192 }
193
194 public void postListNamespaceDescriptors(final List<NamespaceDescriptor> descriptors)
195 throws IOException {
196 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
197 @Override
198 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
199 throws IOException {
200 oserver.postListNamespaceDescriptors(ctx, descriptors);
201 }
202 });
203 }
204
205
206
207 public void preCreateTable(final HTableDescriptor htd, final HRegionInfo[] regions)
208 throws IOException {
209 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
210 @Override
211 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
212 throws IOException {
213 oserver.preCreateTable(ctx, htd, regions);
214 }
215 });
216 }
217
218 public void postCreateTable(final HTableDescriptor htd, final HRegionInfo[] regions)
219 throws IOException {
220 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
221 @Override
222 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
223 throws IOException {
224 oserver.postCreateTable(ctx, htd, regions);
225 }
226 });
227 }
228
229 public void preCreateTableHandler(final HTableDescriptor htd, final HRegionInfo[] regions)
230 throws IOException {
231 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
232 @Override
233 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
234 throws IOException {
235 oserver.preCreateTableHandler(ctx, htd, regions);
236 }
237 });
238 }
239
240 public void postCreateTableHandler(final HTableDescriptor htd, final HRegionInfo[] regions)
241 throws IOException {
242 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
243 @Override
244 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
245 throws IOException {
246 oserver.postCreateTableHandler(ctx, htd, regions);
247 }
248 });
249 }
250
251 public void preDeleteTable(final TableName tableName) throws IOException {
252 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
253 @Override
254 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
255 throws IOException {
256 oserver.preDeleteTable(ctx, tableName);
257 }
258 });
259 }
260
261 public void postDeleteTable(final TableName tableName) throws IOException {
262 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
263 @Override
264 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
265 throws IOException {
266 oserver.postDeleteTable(ctx, tableName);
267 }
268 });
269 }
270
271 public void preDeleteTableHandler(final TableName tableName) throws IOException {
272 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
273 @Override
274 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
275 throws IOException {
276 oserver.preDeleteTableHandler(ctx, tableName);
277 }
278 });
279 }
280
281 public void postDeleteTableHandler(final TableName tableName) throws IOException {
282 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
283 @Override
284 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
285 throws IOException {
286 oserver.postDeleteTableHandler(ctx, tableName);
287 }
288 });
289 }
290
291 public void preTruncateTable(final TableName tableName) throws IOException {
292 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
293 @Override
294 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
295 throws IOException {
296 oserver.preTruncateTable(ctx, tableName);
297 }
298 });
299 }
300
301 public void postTruncateTable(final TableName tableName) throws IOException {
302 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
303 @Override
304 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
305 throws IOException {
306 oserver.postTruncateTable(ctx, tableName);
307 }
308 });
309 }
310
311 public void preTruncateTableHandler(final TableName tableName) throws IOException {
312 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
313 @Override
314 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
315 throws IOException {
316 oserver.preTruncateTableHandler(ctx, tableName);
317 }
318 });
319 }
320
321 public void postTruncateTableHandler(final TableName tableName) throws IOException {
322 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
323 @Override
324 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
325 throws IOException {
326 oserver.postTruncateTableHandler(ctx, tableName);
327 }
328 });
329 }
330
331 public void preModifyTable(final TableName tableName, final HTableDescriptor htd)
332 throws IOException {
333 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
334 @Override
335 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
336 throws IOException {
337 oserver.preModifyTable(ctx, tableName, htd);
338 }
339 });
340 }
341
342 public void postModifyTable(final TableName tableName, final HTableDescriptor htd)
343 throws IOException {
344 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
345 @Override
346 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
347 throws IOException {
348 oserver.postModifyTable(ctx, tableName, htd);
349 }
350 });
351 }
352
353 public void preModifyTableHandler(final TableName tableName, final HTableDescriptor htd)
354 throws IOException {
355 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
356 @Override
357 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
358 throws IOException {
359 oserver.preModifyTableHandler(ctx, tableName, htd);
360 }
361 });
362 }
363
364 public void postModifyTableHandler(final TableName tableName, final HTableDescriptor htd)
365 throws IOException {
366 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
367 @Override
368 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
369 throws IOException {
370 oserver.postModifyTableHandler(ctx, tableName, htd);
371 }
372 });
373 }
374
375 public boolean preAddColumn(final TableName tableName, final HColumnDescriptor column)
376 throws IOException {
377 return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
378 @Override
379 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
380 throws IOException {
381 oserver.preAddColumn(ctx, tableName, column);
382 }
383 });
384 }
385
386 public void postAddColumn(final TableName tableName, final HColumnDescriptor column)
387 throws IOException {
388 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
389 @Override
390 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
391 throws IOException {
392 oserver.postAddColumn(ctx, tableName, column);
393 }
394 });
395 }
396
397 public boolean preAddColumnHandler(final TableName tableName, final HColumnDescriptor column)
398 throws IOException {
399 return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
400 @Override
401 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
402 throws IOException {
403 oserver.preAddColumnHandler(ctx, tableName, column);
404 }
405 });
406 }
407
408 public void postAddColumnHandler(final TableName tableName, final HColumnDescriptor column)
409 throws IOException {
410 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
411 @Override
412 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
413 throws IOException {
414 oserver.postAddColumnHandler(ctx, tableName, column);
415 }
416 });
417 }
418
419 public boolean preModifyColumn(final TableName tableName, final HColumnDescriptor descriptor)
420 throws IOException {
421 return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
422 @Override
423 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
424 throws IOException {
425 oserver.preModifyColumn(ctx, tableName, descriptor);
426 }
427 });
428 }
429
430 public void postModifyColumn(final TableName tableName, final HColumnDescriptor descriptor)
431 throws IOException {
432 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
433 @Override
434 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
435 throws IOException {
436 oserver.postModifyColumn(ctx, tableName, descriptor);
437 }
438 });
439 }
440
441 public boolean preModifyColumnHandler(final TableName tableName,
442 final HColumnDescriptor descriptor) throws IOException {
443 return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
444 @Override
445 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
446 throws IOException {
447 oserver.preModifyColumnHandler(ctx, tableName, descriptor);
448 }
449 });
450 }
451
452 public void postModifyColumnHandler(final TableName tableName,
453 final HColumnDescriptor descriptor) throws IOException {
454 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
455 @Override
456 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
457 throws IOException {
458 oserver.postModifyColumnHandler(ctx, tableName, descriptor);
459 }
460 });
461 }
462
463 public boolean preDeleteColumn(final TableName tableName, final byte [] c) throws IOException {
464 return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
465 @Override
466 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
467 throws IOException {
468 oserver.preDeleteColumn(ctx, tableName, c);
469 }
470 });
471 }
472
473 public void postDeleteColumn(final TableName tableName, final byte [] c) throws IOException {
474 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
475 @Override
476 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
477 throws IOException {
478 oserver.postDeleteColumn(ctx, tableName, c);
479 }
480 });
481 }
482
483 public boolean preDeleteColumnHandler(final TableName tableName, final byte[] c)
484 throws IOException {
485 return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
486 @Override
487 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
488 throws IOException {
489 oserver.preDeleteColumnHandler(ctx, tableName, c);
490 }
491 });
492 }
493
494 public void postDeleteColumnHandler(final TableName tableName, final byte[] c)
495 throws IOException {
496 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
497 @Override
498 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
499 throws IOException {
500 oserver.postDeleteColumnHandler(ctx, tableName, c);
501 }
502 });
503 }
504
505 public void preEnableTable(final TableName tableName) throws IOException {
506 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
507 @Override
508 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
509 throws IOException {
510 oserver.preEnableTable(ctx, tableName);
511 }
512 });
513 }
514
515 public void postEnableTable(final TableName tableName) throws IOException {
516 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
517 @Override
518 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
519 throws IOException {
520 oserver.postEnableTable(ctx, tableName);
521 }
522 });
523 }
524
525 public void preEnableTableHandler(final TableName tableName) throws IOException {
526 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
527 @Override
528 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
529 throws IOException {
530 oserver.preEnableTableHandler(ctx, tableName);
531 }
532 });
533 }
534
535 public void postEnableTableHandler(final TableName tableName) throws IOException {
536 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
537 @Override
538 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
539 throws IOException {
540 oserver.postEnableTableHandler(ctx, tableName);
541 }
542 });
543 }
544
545 public void preDisableTable(final TableName tableName) throws IOException {
546 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
547 @Override
548 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
549 throws IOException {
550 oserver.preDisableTable(ctx, tableName);
551 }
552 });
553 }
554
555 public void postDisableTable(final TableName tableName) throws IOException {
556 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
557 @Override
558 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
559 throws IOException {
560 oserver.postDisableTable(ctx, tableName);
561 }
562 });
563 }
564
565 public void preDisableTableHandler(final TableName tableName) throws IOException {
566 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
567 @Override
568 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
569 throws IOException {
570 oserver.preDisableTableHandler(ctx, tableName);
571 }
572 });
573 }
574
575 public void postDisableTableHandler(final TableName tableName) throws IOException {
576 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
577 @Override
578 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
579 throws IOException {
580 oserver.postDisableTableHandler(ctx, tableName);
581 }
582 });
583 }
584
585 public boolean preMove(final HRegionInfo region, final ServerName srcServer,
586 final ServerName destServer) throws IOException {
587 return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
588 @Override
589 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
590 throws IOException {
591 oserver.preMove(ctx, region, srcServer, destServer);
592 }
593 });
594 }
595
596 public void postMove(final HRegionInfo region, final ServerName srcServer,
597 final ServerName destServer) throws IOException {
598 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
599 @Override
600 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
601 throws IOException {
602 oserver.postMove(ctx, region, srcServer, destServer);
603 }
604 });
605 }
606
607 public boolean preAssign(final HRegionInfo regionInfo) throws IOException {
608 return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
609 @Override
610 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
611 throws IOException {
612 oserver.preAssign(ctx, regionInfo);
613 }
614 });
615 }
616
617 public void postAssign(final HRegionInfo regionInfo) throws IOException {
618 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
619 @Override
620 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
621 throws IOException {
622 oserver.postAssign(ctx, regionInfo);
623 }
624 });
625 }
626
627 public boolean preUnassign(final HRegionInfo regionInfo, final boolean force)
628 throws IOException {
629 return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
630 @Override
631 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
632 throws IOException {
633 oserver.preUnassign(ctx, regionInfo, force);
634 }
635 });
636 }
637
638 public void postUnassign(final HRegionInfo regionInfo, final boolean force) throws IOException {
639 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
640 @Override
641 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
642 throws IOException {
643 oserver.postUnassign(ctx, regionInfo, force);
644 }
645 });
646 }
647
648 public void preRegionOffline(final HRegionInfo regionInfo) throws IOException {
649 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
650 @Override
651 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
652 throws IOException {
653 oserver.preRegionOffline(ctx, regionInfo);
654 }
655 });
656 }
657
658 public void postRegionOffline(final HRegionInfo regionInfo) throws IOException {
659 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
660 @Override
661 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
662 throws IOException {
663 oserver.postRegionOffline(ctx, regionInfo);
664 }
665 });
666 }
667
668 public boolean preBalance() throws IOException {
669 return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
670 @Override
671 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
672 throws IOException {
673 oserver.preBalance(ctx);
674 }
675 });
676 }
677
678 public void postBalance(final List<RegionPlan> plans) throws IOException {
679 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
680 @Override
681 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
682 throws IOException {
683 oserver.postBalance(ctx, plans);
684 }
685 });
686 }
687
688 public boolean preBalanceSwitch(final boolean b) throws IOException {
689 return execOperationWithResult(b, coprocessors.isEmpty() ? null :
690 new CoprocessorOperationWithResult<Boolean>() {
691 @Override
692 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
693 throws IOException {
694 setResult(oserver.preBalanceSwitch(ctx, getResult()));
695 }
696 });
697 }
698
699 public void postBalanceSwitch(final boolean oldValue, final boolean newValue)
700 throws IOException {
701 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
702 @Override
703 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
704 throws IOException {
705 oserver.postBalanceSwitch(ctx, oldValue, newValue);
706 }
707 });
708 }
709
710 public void preShutdown() throws IOException {
711 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
712 @Override
713 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
714 throws IOException {
715 oserver.preShutdown(ctx);
716 }
717 @Override
718 public void postEnvCall(MasterEnvironment env) {
719
720 shutdown(env);
721 }
722 });
723 }
724
725 public void preStopMaster() throws IOException {
726 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
727 @Override
728 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
729 throws IOException {
730 oserver.preStopMaster(ctx);
731 }
732 @Override
733 public void postEnvCall(MasterEnvironment env) {
734
735 shutdown(env);
736 }
737 });
738 }
739
740 public void preMasterInitialization() throws IOException {
741 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
742 @Override
743 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
744 throws IOException {
745 oserver.preMasterInitialization(ctx);
746 }
747 });
748 }
749
750 public void postStartMaster() throws IOException {
751 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
752 @Override
753 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
754 throws IOException {
755 oserver.postStartMaster(ctx);
756 }
757 });
758 }
759
760 public void preSnapshot(final SnapshotDescription snapshot,
761 final HTableDescriptor hTableDescriptor) throws IOException {
762 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
763 @Override
764 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
765 throws IOException {
766 oserver.preSnapshot(ctx, snapshot, hTableDescriptor);
767 }
768 });
769 }
770
771 public void postSnapshot(final SnapshotDescription snapshot,
772 final HTableDescriptor hTableDescriptor) throws IOException {
773 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
774 @Override
775 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
776 throws IOException {
777 oserver.postSnapshot(ctx, snapshot, hTableDescriptor);
778 }
779 });
780 }
781
782 public void preCloneSnapshot(final SnapshotDescription snapshot,
783 final HTableDescriptor hTableDescriptor) throws IOException {
784 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
785 @Override
786 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
787 throws IOException {
788 oserver.preCloneSnapshot(ctx, snapshot, hTableDescriptor);
789 }
790 });
791 }
792
793 public void postCloneSnapshot(final SnapshotDescription snapshot,
794 final HTableDescriptor hTableDescriptor) throws IOException {
795 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
796 @Override
797 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
798 throws IOException {
799 oserver.postCloneSnapshot(ctx, snapshot, hTableDescriptor);
800 }
801 });
802 }
803
804 public void preRestoreSnapshot(final SnapshotDescription snapshot,
805 final HTableDescriptor hTableDescriptor) throws IOException {
806 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
807 @Override
808 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
809 throws IOException {
810 oserver.preRestoreSnapshot(ctx, snapshot, hTableDescriptor);
811 }
812 });
813 }
814
815 public void postRestoreSnapshot(final SnapshotDescription snapshot,
816 final HTableDescriptor hTableDescriptor) throws IOException {
817 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
818 @Override
819 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
820 throws IOException {
821 oserver.postRestoreSnapshot(ctx, snapshot, hTableDescriptor);
822 }
823 });
824 }
825
826 public void preDeleteSnapshot(final SnapshotDescription snapshot) throws IOException {
827 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
828 @Override
829 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
830 throws IOException {
831 oserver.preDeleteSnapshot(ctx, snapshot);
832 }
833 });
834 }
835
836 public void postDeleteSnapshot(final SnapshotDescription snapshot) throws IOException {
837 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
838 @Override
839 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
840 throws IOException {
841 oserver.postDeleteSnapshot(ctx, snapshot);
842 }
843 });
844 }
845
846 @Deprecated
847 public boolean preGetTableDescriptors(final List<TableName> tableNamesList,
848 final List<HTableDescriptor> descriptors) throws IOException {
849 return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
850 @Override
851 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
852 throws IOException {
853 oserver.preGetTableDescriptors(ctx, tableNamesList, descriptors);
854 }
855 });
856 }
857
858 @Deprecated
859 public void postGetTableDescriptors(final List<HTableDescriptor> descriptors)
860 throws IOException {
861 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
862 @Override
863 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
864 throws IOException {
865 oserver.postGetTableDescriptors(ctx, descriptors);
866 }
867 });
868 }
869
870 public boolean preGetTableDescriptors(final List<TableName> tableNamesList,
871 final List<HTableDescriptor> descriptors, final String regex) throws IOException {
872 return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
873 @Override
874 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
875 throws IOException {
876 oserver.preGetTableDescriptors(ctx, tableNamesList, descriptors, regex);
877 }
878 });
879 }
880
881 public void postGetTableDescriptors(final List<TableName> tableNamesList,
882 final List<HTableDescriptor> descriptors, final String regex) throws IOException {
883 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
884 @Override
885 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
886 throws IOException {
887 oserver.postGetTableDescriptors(ctx, tableNamesList, descriptors, regex);
888 }
889 });
890 }
891
892 public boolean preGetTableNames(final List<HTableDescriptor> descriptors,
893 final String regex) throws IOException {
894 return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
895 @Override
896 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
897 throws IOException {
898 oserver.preGetTableNames(ctx, descriptors, regex);
899 }
900 });
901 }
902
903 public void postGetTableNames(final List<HTableDescriptor> descriptors,
904 final String regex) throws IOException {
905 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
906 @Override
907 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
908 throws IOException {
909 oserver.postGetTableNames(ctx, descriptors, regex);
910 }
911 });
912 }
913
914 public void preTableFlush(final TableName tableName) throws IOException {
915 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
916 @Override
917 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
918 throws IOException {
919 oserver.preTableFlush(ctx, tableName);
920 }
921 });
922 }
923
924 public void postTableFlush(final TableName tableName) throws IOException {
925 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
926 @Override
927 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
928 throws IOException {
929 oserver.postTableFlush(ctx, tableName);
930 }
931 });
932 }
933
934 private static abstract class CoprocessorOperation
935 extends ObserverContext<MasterCoprocessorEnvironment> {
936 public CoprocessorOperation() {
937 }
938
939 public abstract void call(MasterObserver oserver,
940 ObserverContext<MasterCoprocessorEnvironment> ctx) throws IOException;
941
942 public void postEnvCall(MasterEnvironment env) {
943 }
944 }
945
946 private static abstract class CoprocessorOperationWithResult<T> extends CoprocessorOperation {
947 private T result = null;
948 public void setResult(final T result) { this.result = result; }
949 public T getResult() { return this.result; }
950 }
951
952 private <T> T execOperationWithResult(final T defaultValue,
953 final CoprocessorOperationWithResult<T> ctx) throws IOException {
954 if (ctx == null) return defaultValue;
955 ctx.setResult(defaultValue);
956 execOperation(ctx);
957 return ctx.getResult();
958 }
959
960 private boolean execOperation(final CoprocessorOperation ctx) throws IOException {
961 if (ctx == null) return false;
962 boolean bypass = false;
963 for (MasterEnvironment env: coprocessors) {
964 if (env.getInstance() instanceof MasterObserver) {
965 ctx.prepare(env);
966 Thread currentThread = Thread.currentThread();
967 ClassLoader cl = currentThread.getContextClassLoader();
968 try {
969 currentThread.setContextClassLoader(env.getClassLoader());
970 ctx.call((MasterObserver)env.getInstance(), ctx);
971 } catch (Throwable e) {
972 handleCoprocessorThrowable(env, e);
973 } finally {
974 currentThread.setContextClassLoader(cl);
975 }
976 bypass |= ctx.shouldBypass();
977 if (ctx.shouldComplete()) {
978 break;
979 }
980 }
981 ctx.postEnvCall(env);
982 }
983 return bypass;
984 }
985 }