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
162
163 public void preCreateTable(final HTableDescriptor htd, final HRegionInfo[] regions)
164 throws IOException {
165 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
166 @Override
167 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
168 throws IOException {
169 oserver.preCreateTable(ctx, htd, regions);
170 }
171 });
172 }
173
174 public void postCreateTable(final HTableDescriptor htd, final HRegionInfo[] regions)
175 throws IOException {
176 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
177 @Override
178 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
179 throws IOException {
180 oserver.postCreateTable(ctx, htd, regions);
181 }
182 });
183 }
184
185 public void preCreateTableHandler(final HTableDescriptor htd, final HRegionInfo[] regions)
186 throws IOException {
187 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
188 @Override
189 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
190 throws IOException {
191 oserver.preCreateTableHandler(ctx, htd, regions);
192 }
193 });
194 }
195
196 public void postCreateTableHandler(final HTableDescriptor htd, final HRegionInfo[] regions)
197 throws IOException {
198 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
199 @Override
200 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
201 throws IOException {
202 oserver.postCreateTableHandler(ctx, htd, regions);
203 }
204 });
205 }
206
207 public void preDeleteTable(final TableName tableName) throws IOException {
208 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
209 @Override
210 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
211 throws IOException {
212 oserver.preDeleteTable(ctx, tableName);
213 }
214 });
215 }
216
217 public void postDeleteTable(final TableName tableName) throws IOException {
218 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
219 @Override
220 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
221 throws IOException {
222 oserver.postDeleteTable(ctx, tableName);
223 }
224 });
225 }
226
227 public void preDeleteTableHandler(final TableName tableName) throws IOException {
228 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
229 @Override
230 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
231 throws IOException {
232 oserver.preDeleteTableHandler(ctx, tableName);
233 }
234 });
235 }
236
237 public void postDeleteTableHandler(final TableName tableName) throws IOException {
238 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
239 @Override
240 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
241 throws IOException {
242 oserver.postDeleteTableHandler(ctx, tableName);
243 }
244 });
245 }
246
247 public void preTruncateTable(TableName tableName) throws IOException {
248 ObserverContext<MasterCoprocessorEnvironment> ctx = null;
249 for (MasterEnvironment env: coprocessors) {
250 if (env.getInstance() instanceof MasterObserver) {
251 ctx = ObserverContext.createAndPrepare(env, ctx);
252 try {
253 ((MasterObserver)env.getInstance()).preTruncateTable(ctx, tableName);
254 } catch (Throwable e) {
255 handleCoprocessorThrowable(env, e);
256 }
257 if (ctx.shouldComplete()) {
258 break;
259 }
260 }
261 }
262 }
263
264 public void postTruncateTable(TableName tableName) throws IOException {
265 ObserverContext<MasterCoprocessorEnvironment> ctx = null;
266 for (MasterEnvironment env: coprocessors) {
267 if (env.getInstance() instanceof MasterObserver) {
268 ctx = ObserverContext.createAndPrepare(env, ctx);
269 try {
270 ((MasterObserver)env.getInstance()).postTruncateTable(ctx, tableName);
271 } catch (Throwable e) {
272 handleCoprocessorThrowable(env, e);
273 }
274 if (ctx.shouldComplete()) {
275 break;
276 }
277 }
278 }
279 }
280
281 public void preTruncateTableHandler(TableName tableName) throws IOException {
282 ObserverContext<MasterCoprocessorEnvironment> ctx = null;
283 for (MasterEnvironment env : coprocessors) {
284 if (env.getInstance() instanceof MasterObserver) {
285 ctx = ObserverContext.createAndPrepare(env, ctx);
286 try {
287 ((MasterObserver) env.getInstance()).preTruncateTableHandler(ctx, tableName);
288 } catch (Throwable e) {
289 handleCoprocessorThrowable(env, e);
290 }
291 if (ctx.shouldComplete()) {
292 break;
293 }
294 }
295 }
296 }
297
298 public void postTruncateTableHandler(TableName tableName) throws IOException {
299 ObserverContext<MasterCoprocessorEnvironment> ctx = null;
300 for (MasterEnvironment env : coprocessors) {
301 if (env.getInstance() instanceof MasterObserver) {
302 ctx = ObserverContext.createAndPrepare(env, ctx);
303 try {
304 ((MasterObserver) env.getInstance()).postTruncateTableHandler(ctx, tableName);
305 } catch (Throwable e) {
306 handleCoprocessorThrowable(env, e);
307 }
308 if (ctx.shouldComplete()) {
309 break;
310 }
311 }
312 }
313 }
314
315 public void preModifyTable(final TableName tableName, final HTableDescriptor htd)
316 throws IOException {
317 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
318 @Override
319 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
320 throws IOException {
321 oserver.preModifyTable(ctx, tableName, htd);
322 }
323 });
324 }
325
326 public void postModifyTable(final TableName tableName, final HTableDescriptor htd)
327 throws IOException {
328 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
329 @Override
330 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
331 throws IOException {
332 oserver.postModifyTable(ctx, tableName, htd);
333 }
334 });
335 }
336
337 public void preModifyTableHandler(final TableName tableName, final HTableDescriptor htd)
338 throws IOException {
339 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
340 @Override
341 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
342 throws IOException {
343 oserver.preModifyTableHandler(ctx, tableName, htd);
344 }
345 });
346 }
347
348 public void postModifyTableHandler(final TableName tableName, final HTableDescriptor htd)
349 throws IOException {
350 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
351 @Override
352 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
353 throws IOException {
354 oserver.postModifyTableHandler(ctx, tableName, htd);
355 }
356 });
357 }
358
359 public boolean preAddColumn(final TableName tableName, final HColumnDescriptor column)
360 throws IOException {
361 return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
362 @Override
363 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
364 throws IOException {
365 oserver.preAddColumn(ctx, tableName, column);
366 }
367 });
368 }
369
370 public void postAddColumn(final TableName tableName, final HColumnDescriptor column)
371 throws IOException {
372 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
373 @Override
374 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
375 throws IOException {
376 oserver.postAddColumn(ctx, tableName, column);
377 }
378 });
379 }
380
381 public boolean preAddColumnHandler(final TableName tableName, final HColumnDescriptor column)
382 throws IOException {
383 return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
384 @Override
385 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
386 throws IOException {
387 oserver.preAddColumnHandler(ctx, tableName, column);
388 }
389 });
390 }
391
392 public void postAddColumnHandler(final TableName tableName, final HColumnDescriptor column)
393 throws IOException {
394 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
395 @Override
396 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
397 throws IOException {
398 oserver.postAddColumnHandler(ctx, tableName, column);
399 }
400 });
401 }
402
403 public boolean preModifyColumn(final TableName tableName, final HColumnDescriptor descriptor)
404 throws IOException {
405 return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
406 @Override
407 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
408 throws IOException {
409 oserver.preModifyColumn(ctx, tableName, descriptor);
410 }
411 });
412 }
413
414 public void postModifyColumn(final TableName tableName, final HColumnDescriptor descriptor)
415 throws IOException {
416 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
417 @Override
418 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
419 throws IOException {
420 oserver.postModifyColumn(ctx, tableName, descriptor);
421 }
422 });
423 }
424
425 public boolean preModifyColumnHandler(final TableName tableName,
426 final HColumnDescriptor descriptor) throws IOException {
427 return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
428 @Override
429 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
430 throws IOException {
431 oserver.preModifyColumnHandler(ctx, tableName, descriptor);
432 }
433 });
434 }
435
436 public void postModifyColumnHandler(final TableName tableName,
437 final HColumnDescriptor descriptor) throws IOException {
438 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
439 @Override
440 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
441 throws IOException {
442 oserver.postModifyColumnHandler(ctx, tableName, descriptor);
443 }
444 });
445 }
446
447 public boolean preDeleteColumn(final TableName tableName, final byte [] c) throws IOException {
448 return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
449 @Override
450 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
451 throws IOException {
452 oserver.preDeleteColumn(ctx, tableName, c);
453 }
454 });
455 }
456
457 public void postDeleteColumn(final TableName tableName, final byte [] c) throws IOException {
458 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
459 @Override
460 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
461 throws IOException {
462 oserver.postDeleteColumn(ctx, tableName, c);
463 }
464 });
465 }
466
467 public boolean preDeleteColumnHandler(final TableName tableName, final byte[] c)
468 throws IOException {
469 return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
470 @Override
471 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
472 throws IOException {
473 oserver.preDeleteColumnHandler(ctx, tableName, c);
474 }
475 });
476 }
477
478 public void postDeleteColumnHandler(final TableName tableName, final byte[] c)
479 throws IOException {
480 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
481 @Override
482 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
483 throws IOException {
484 oserver.postDeleteColumnHandler(ctx, tableName, c);
485 }
486 });
487 }
488
489 public void preEnableTable(final TableName tableName) throws IOException {
490 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
491 @Override
492 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
493 throws IOException {
494 oserver.preEnableTable(ctx, tableName);
495 }
496 });
497 }
498
499 public void postEnableTable(final TableName tableName) throws IOException {
500 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
501 @Override
502 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
503 throws IOException {
504 oserver.postEnableTable(ctx, tableName);
505 }
506 });
507 }
508
509 public void preEnableTableHandler(final TableName tableName) throws IOException {
510 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
511 @Override
512 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
513 throws IOException {
514 oserver.preEnableTableHandler(ctx, tableName);
515 }
516 });
517 }
518
519 public void postEnableTableHandler(final TableName tableName) throws IOException {
520 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
521 @Override
522 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
523 throws IOException {
524 oserver.postEnableTableHandler(ctx, tableName);
525 }
526 });
527 }
528
529 public void preDisableTable(final TableName tableName) throws IOException {
530 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
531 @Override
532 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
533 throws IOException {
534 oserver.preDisableTable(ctx, tableName);
535 }
536 });
537 }
538
539 public void postDisableTable(final TableName tableName) throws IOException {
540 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
541 @Override
542 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
543 throws IOException {
544 oserver.postDisableTable(ctx, tableName);
545 }
546 });
547 }
548
549 public void preDisableTableHandler(final TableName tableName) throws IOException {
550 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
551 @Override
552 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
553 throws IOException {
554 oserver.preDisableTableHandler(ctx, tableName);
555 }
556 });
557 }
558
559 public void postDisableTableHandler(final TableName tableName) throws IOException {
560 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
561 @Override
562 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
563 throws IOException {
564 oserver.postDisableTableHandler(ctx, tableName);
565 }
566 });
567 }
568
569 public boolean preMove(final HRegionInfo region, final ServerName srcServer,
570 final ServerName destServer) throws IOException {
571 return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
572 @Override
573 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
574 throws IOException {
575 oserver.preMove(ctx, region, srcServer, destServer);
576 }
577 });
578 }
579
580 public void postMove(final HRegionInfo region, final ServerName srcServer,
581 final ServerName destServer) throws IOException {
582 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
583 @Override
584 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
585 throws IOException {
586 oserver.postMove(ctx, region, srcServer, destServer);
587 }
588 });
589 }
590
591 public boolean preAssign(final HRegionInfo regionInfo) throws IOException {
592 return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
593 @Override
594 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
595 throws IOException {
596 oserver.preAssign(ctx, regionInfo);
597 }
598 });
599 }
600
601 public void postAssign(final HRegionInfo regionInfo) throws IOException {
602 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
603 @Override
604 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
605 throws IOException {
606 oserver.postAssign(ctx, regionInfo);
607 }
608 });
609 }
610
611 public boolean preUnassign(final HRegionInfo regionInfo, final boolean force)
612 throws IOException {
613 return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
614 @Override
615 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
616 throws IOException {
617 oserver.preUnassign(ctx, regionInfo, force);
618 }
619 });
620 }
621
622 public void postUnassign(final HRegionInfo regionInfo, final boolean force) throws IOException {
623 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
624 @Override
625 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
626 throws IOException {
627 oserver.postUnassign(ctx, regionInfo, force);
628 }
629 });
630 }
631
632 public void preRegionOffline(final HRegionInfo regionInfo) throws IOException {
633 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
634 @Override
635 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
636 throws IOException {
637 oserver.preRegionOffline(ctx, regionInfo);
638 }
639 });
640 }
641
642 public void postRegionOffline(final HRegionInfo regionInfo) throws IOException {
643 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
644 @Override
645 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
646 throws IOException {
647 oserver.postRegionOffline(ctx, regionInfo);
648 }
649 });
650 }
651
652 public boolean preBalance() throws IOException {
653 return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
654 @Override
655 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
656 throws IOException {
657 oserver.preBalance(ctx);
658 }
659 });
660 }
661
662 public void postBalance(final List<RegionPlan> plans) throws IOException {
663 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
664 @Override
665 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
666 throws IOException {
667 oserver.postBalance(ctx, plans);
668 }
669 });
670 }
671
672 public boolean preBalanceSwitch(final boolean b) throws IOException {
673 return execOperationWithResult(b, coprocessors.isEmpty() ? null :
674 new CoprocessorOperationWithResult<Boolean>() {
675 @Override
676 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
677 throws IOException {
678 setResult(oserver.preBalanceSwitch(ctx, getResult()));
679 }
680 });
681 }
682
683 public void postBalanceSwitch(final boolean oldValue, final boolean newValue)
684 throws IOException {
685 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
686 @Override
687 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
688 throws IOException {
689 oserver.postBalanceSwitch(ctx, oldValue, newValue);
690 }
691 });
692 }
693
694 public void preShutdown() throws IOException {
695 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
696 @Override
697 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
698 throws IOException {
699 oserver.preShutdown(ctx);
700 }
701 @Override
702 public void postEnvCall(MasterEnvironment env) {
703
704 shutdown(env);
705 }
706 });
707 }
708
709 public void preStopMaster() throws IOException {
710 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
711 @Override
712 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
713 throws IOException {
714 oserver.preStopMaster(ctx);
715 }
716 @Override
717 public void postEnvCall(MasterEnvironment env) {
718
719 shutdown(env);
720 }
721 });
722 }
723
724 public void preMasterInitialization() throws IOException {
725 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
726 @Override
727 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
728 throws IOException {
729 oserver.preMasterInitialization(ctx);
730 }
731 });
732 }
733
734 public void postStartMaster() throws IOException {
735 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
736 @Override
737 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
738 throws IOException {
739 oserver.postStartMaster(ctx);
740 }
741 });
742 }
743
744 public void preSnapshot(final SnapshotDescription snapshot,
745 final HTableDescriptor hTableDescriptor) throws IOException {
746 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
747 @Override
748 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
749 throws IOException {
750 oserver.preSnapshot(ctx, snapshot, hTableDescriptor);
751 }
752 });
753 }
754
755 public void postSnapshot(final SnapshotDescription snapshot,
756 final HTableDescriptor hTableDescriptor) throws IOException {
757 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
758 @Override
759 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
760 throws IOException {
761 oserver.postSnapshot(ctx, snapshot, hTableDescriptor);
762 }
763 });
764 }
765
766 public void preCloneSnapshot(final SnapshotDescription snapshot,
767 final HTableDescriptor hTableDescriptor) throws IOException {
768 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
769 @Override
770 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
771 throws IOException {
772 oserver.preCloneSnapshot(ctx, snapshot, hTableDescriptor);
773 }
774 });
775 }
776
777 public void postCloneSnapshot(final SnapshotDescription snapshot,
778 final HTableDescriptor hTableDescriptor) throws IOException {
779 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
780 @Override
781 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
782 throws IOException {
783 oserver.postCloneSnapshot(ctx, snapshot, hTableDescriptor);
784 }
785 });
786 }
787
788 public void preRestoreSnapshot(final SnapshotDescription snapshot,
789 final HTableDescriptor hTableDescriptor) throws IOException {
790 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
791 @Override
792 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
793 throws IOException {
794 oserver.preRestoreSnapshot(ctx, snapshot, hTableDescriptor);
795 }
796 });
797 }
798
799 public void postRestoreSnapshot(final SnapshotDescription snapshot,
800 final HTableDescriptor hTableDescriptor) throws IOException {
801 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
802 @Override
803 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
804 throws IOException {
805 oserver.postRestoreSnapshot(ctx, snapshot, hTableDescriptor);
806 }
807 });
808 }
809
810 public void preDeleteSnapshot(final SnapshotDescription snapshot) throws IOException {
811 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
812 @Override
813 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
814 throws IOException {
815 oserver.preDeleteSnapshot(ctx, snapshot);
816 }
817 });
818 }
819
820 public void postDeleteSnapshot(final SnapshotDescription snapshot) throws IOException {
821 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
822 @Override
823 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
824 throws IOException {
825 oserver.postDeleteSnapshot(ctx, snapshot);
826 }
827 });
828 }
829
830 public boolean preGetTableDescriptors(final List<TableName> tableNamesList,
831 final List<HTableDescriptor> descriptors) throws IOException {
832 return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
833 @Override
834 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
835 throws IOException {
836 oserver.preGetTableDescriptors(ctx, tableNamesList, descriptors);
837 }
838 });
839 }
840
841 public void postGetTableDescriptors(final List<HTableDescriptor> descriptors)
842 throws IOException {
843 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
844 @Override
845 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
846 throws IOException {
847 oserver.postGetTableDescriptors(ctx, descriptors);
848 }
849 });
850 }
851
852 private static abstract class CoprocessorOperation
853 extends ObserverContext<MasterCoprocessorEnvironment> {
854 public CoprocessorOperation() {
855 }
856
857 public abstract void call(MasterObserver oserver,
858 ObserverContext<MasterCoprocessorEnvironment> ctx) throws IOException;
859
860 public void postEnvCall(MasterEnvironment env) {
861 }
862 }
863
864 private static abstract class CoprocessorOperationWithResult<T> extends CoprocessorOperation {
865 private T result = null;
866 public void setResult(final T result) { this.result = result; }
867 public T getResult() { return this.result; }
868 }
869
870 private <T> T execOperationWithResult(final T defaultValue,
871 final CoprocessorOperationWithResult<T> ctx) throws IOException {
872 if (ctx == null) return defaultValue;
873 ctx.setResult(defaultValue);
874 execOperation(ctx);
875 return ctx.getResult();
876 }
877
878 private boolean execOperation(final CoprocessorOperation ctx) throws IOException {
879 if (ctx == null) return false;
880 boolean bypass = false;
881 for (MasterEnvironment env: coprocessors) {
882 if (env.getInstance() instanceof MasterObserver) {
883 ctx.prepare(env);
884 Thread currentThread = Thread.currentThread();
885 ClassLoader cl = currentThread.getContextClassLoader();
886 try {
887 currentThread.setContextClassLoader(env.getClassLoader());
888 ctx.call((MasterObserver)env.getInstance(), ctx);
889 } catch (Throwable e) {
890 handleCoprocessorThrowable(env, e);
891 } finally {
892 currentThread.setContextClassLoader(cl);
893 }
894 bypass |= ctx.shouldBypass();
895 if (ctx.shouldComplete()) {
896 break;
897 }
898 }
899 ctx.postEnvCall(env);
900 }
901 return bypass;
902 }
903 }