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