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