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