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.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 preModifyTable(final TableName tableName, final HTableDescriptor htd)
229 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.preModifyTable(ctx, tableName, htd);
235 }
236 });
237 }
238
239 public void postModifyTable(final TableName tableName, final HTableDescriptor htd)
240 throws IOException {
241 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
242 @Override
243 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
244 throws IOException {
245 oserver.postModifyTable(ctx, tableName, htd);
246 }
247 });
248 }
249
250 public void preModifyTableHandler(final TableName tableName, final HTableDescriptor htd)
251 throws IOException {
252 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
253 @Override
254 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
255 throws IOException {
256 oserver.preModifyTableHandler(ctx, tableName, htd);
257 }
258 });
259 }
260
261 public void postModifyTableHandler(final TableName tableName, final HTableDescriptor htd)
262 throws IOException {
263 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
264 @Override
265 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
266 throws IOException {
267 oserver.postModifyTableHandler(ctx, tableName, htd);
268 }
269 });
270 }
271
272 public boolean preAddColumn(final TableName tableName, final HColumnDescriptor column)
273 throws IOException {
274 return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
275 @Override
276 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
277 throws IOException {
278 oserver.preAddColumn(ctx, tableName, column);
279 }
280 });
281 }
282
283 public void postAddColumn(final TableName tableName, final HColumnDescriptor column)
284 throws IOException {
285 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
286 @Override
287 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
288 throws IOException {
289 oserver.postAddColumn(ctx, tableName, column);
290 }
291 });
292 }
293
294 public boolean preAddColumnHandler(final TableName tableName, final HColumnDescriptor column)
295 throws IOException {
296 return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
297 @Override
298 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
299 throws IOException {
300 oserver.preAddColumnHandler(ctx, tableName, column);
301 }
302 });
303 }
304
305 public void postAddColumnHandler(final TableName tableName, final HColumnDescriptor column)
306 throws IOException {
307 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
308 @Override
309 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
310 throws IOException {
311 oserver.postAddColumnHandler(ctx, tableName, column);
312 }
313 });
314 }
315
316 public boolean preModifyColumn(final TableName tableName, final HColumnDescriptor descriptor)
317 throws IOException {
318 return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
319 @Override
320 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
321 throws IOException {
322 oserver.preModifyColumn(ctx, tableName, descriptor);
323 }
324 });
325 }
326
327 public void postModifyColumn(final TableName tableName, final HColumnDescriptor descriptor)
328 throws IOException {
329 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
330 @Override
331 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
332 throws IOException {
333 oserver.postModifyColumn(ctx, tableName, descriptor);
334 }
335 });
336 }
337
338 public boolean preModifyColumnHandler(final TableName tableName,
339 final HColumnDescriptor descriptor) throws IOException {
340 return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
341 @Override
342 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
343 throws IOException {
344 oserver.preModifyColumnHandler(ctx, tableName, descriptor);
345 }
346 });
347 }
348
349 public void postModifyColumnHandler(final TableName tableName,
350 final HColumnDescriptor descriptor) throws IOException {
351 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
352 @Override
353 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
354 throws IOException {
355 oserver.postModifyColumnHandler(ctx, tableName, descriptor);
356 }
357 });
358 }
359
360 public boolean preDeleteColumn(final TableName tableName, final byte [] c) throws IOException {
361 return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
362 @Override
363 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
364 throws IOException {
365 oserver.preDeleteColumn(ctx, tableName, c);
366 }
367 });
368 }
369
370 public void postDeleteColumn(final TableName tableName, final byte [] c) throws IOException {
371 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
372 @Override
373 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
374 throws IOException {
375 oserver.postDeleteColumn(ctx, tableName, c);
376 }
377 });
378 }
379
380 public boolean preDeleteColumnHandler(final TableName tableName, final byte[] c)
381 throws IOException {
382 return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
383 @Override
384 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
385 throws IOException {
386 oserver.preDeleteColumnHandler(ctx, tableName, c);
387 }
388 });
389 }
390
391 public void postDeleteColumnHandler(final TableName tableName, final byte[] c)
392 throws IOException {
393 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
394 @Override
395 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
396 throws IOException {
397 oserver.postDeleteColumnHandler(ctx, tableName, c);
398 }
399 });
400 }
401
402 public void preEnableTable(final TableName tableName) throws IOException {
403 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
404 @Override
405 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
406 throws IOException {
407 oserver.preEnableTable(ctx, tableName);
408 }
409 });
410 }
411
412 public void postEnableTable(final TableName tableName) throws IOException {
413 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
414 @Override
415 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
416 throws IOException {
417 oserver.postEnableTable(ctx, tableName);
418 }
419 });
420 }
421
422 public void preEnableTableHandler(final TableName tableName) throws IOException {
423 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
424 @Override
425 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
426 throws IOException {
427 oserver.preEnableTableHandler(ctx, tableName);
428 }
429 });
430 }
431
432 public void postEnableTableHandler(final TableName tableName) throws IOException {
433 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
434 @Override
435 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
436 throws IOException {
437 oserver.postEnableTableHandler(ctx, tableName);
438 }
439 });
440 }
441
442 public void preDisableTable(final TableName tableName) throws IOException {
443 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
444 @Override
445 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
446 throws IOException {
447 oserver.preDisableTable(ctx, tableName);
448 }
449 });
450 }
451
452 public void postDisableTable(final TableName tableName) throws IOException {
453 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
454 @Override
455 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
456 throws IOException {
457 oserver.postDisableTable(ctx, tableName);
458 }
459 });
460 }
461
462 public void preDisableTableHandler(final TableName tableName) throws IOException {
463 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
464 @Override
465 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
466 throws IOException {
467 oserver.preDisableTableHandler(ctx, tableName);
468 }
469 });
470 }
471
472 public void postDisableTableHandler(final TableName tableName) throws IOException {
473 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
474 @Override
475 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
476 throws IOException {
477 oserver.postDisableTableHandler(ctx, tableName);
478 }
479 });
480 }
481
482 public boolean preMove(final HRegionInfo region, final ServerName srcServer,
483 final ServerName destServer) throws IOException {
484 return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
485 @Override
486 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
487 throws IOException {
488 oserver.preMove(ctx, region, srcServer, destServer);
489 }
490 });
491 }
492
493 public void postMove(final HRegionInfo region, final ServerName srcServer,
494 final ServerName destServer) throws IOException {
495 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
496 @Override
497 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
498 throws IOException {
499 oserver.postMove(ctx, region, srcServer, destServer);
500 }
501 });
502 }
503
504 public boolean preAssign(final HRegionInfo regionInfo) throws IOException {
505 return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
506 @Override
507 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
508 throws IOException {
509 oserver.preAssign(ctx, regionInfo);
510 }
511 });
512 }
513
514 public void postAssign(final HRegionInfo regionInfo) throws IOException {
515 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
516 @Override
517 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
518 throws IOException {
519 oserver.postAssign(ctx, regionInfo);
520 }
521 });
522 }
523
524 public boolean preUnassign(final HRegionInfo regionInfo, final boolean force)
525 throws IOException {
526 return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
527 @Override
528 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
529 throws IOException {
530 oserver.preUnassign(ctx, regionInfo, force);
531 }
532 });
533 }
534
535 public void postUnassign(final HRegionInfo regionInfo, final boolean force) 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.postUnassign(ctx, regionInfo, force);
541 }
542 });
543 }
544
545 public void preRegionOffline(final HRegionInfo regionInfo) 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.preRegionOffline(ctx, regionInfo);
551 }
552 });
553 }
554
555 public void postRegionOffline(final HRegionInfo regionInfo) 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.postRegionOffline(ctx, regionInfo);
561 }
562 });
563 }
564
565 public boolean preBalance() throws IOException {
566 return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
567 @Override
568 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
569 throws IOException {
570 oserver.preBalance(ctx);
571 }
572 });
573 }
574
575 public void postBalance(final List<RegionPlan> plans) 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.postBalance(ctx, plans);
581 }
582 });
583 }
584
585 public boolean preBalanceSwitch(final boolean b) throws IOException {
586 return execOperationWithResult(b, coprocessors.isEmpty() ? null :
587 new CoprocessorOperationWithResult<Boolean>() {
588 @Override
589 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
590 throws IOException {
591 setResult(oserver.preBalanceSwitch(ctx, getResult()));
592 }
593 });
594 }
595
596 public void postBalanceSwitch(final boolean oldValue, final boolean newValue)
597 throws IOException {
598 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
599 @Override
600 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
601 throws IOException {
602 oserver.postBalanceSwitch(ctx, oldValue, newValue);
603 }
604 });
605 }
606
607 public void preShutdown() throws IOException {
608 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
609 @Override
610 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
611 throws IOException {
612 oserver.preShutdown(ctx);
613 }
614 @Override
615 public void postEnvCall(MasterEnvironment env) {
616
617 shutdown(env);
618 }
619 });
620 }
621
622 public void preStopMaster() throws IOException {
623 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
624 @Override
625 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
626 throws IOException {
627 oserver.preStopMaster(ctx);
628 }
629 @Override
630 public void postEnvCall(MasterEnvironment env) {
631
632 shutdown(env);
633 }
634 });
635 }
636
637 public void preMasterInitialization() throws IOException {
638 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
639 @Override
640 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
641 throws IOException {
642 oserver.preMasterInitialization(ctx);
643 }
644 });
645 }
646
647 public void postStartMaster() 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.postStartMaster(ctx);
653 }
654 });
655 }
656
657 public void preSnapshot(final SnapshotDescription snapshot,
658 final HTableDescriptor hTableDescriptor) throws IOException {
659 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
660 @Override
661 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
662 throws IOException {
663 oserver.preSnapshot(ctx, snapshot, hTableDescriptor);
664 }
665 });
666 }
667
668 public void postSnapshot(final SnapshotDescription snapshot,
669 final HTableDescriptor hTableDescriptor) throws IOException {
670 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
671 @Override
672 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
673 throws IOException {
674 oserver.postSnapshot(ctx, snapshot, hTableDescriptor);
675 }
676 });
677 }
678
679 public void preCloneSnapshot(final SnapshotDescription snapshot,
680 final HTableDescriptor hTableDescriptor) throws IOException {
681 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
682 @Override
683 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
684 throws IOException {
685 oserver.preCloneSnapshot(ctx, snapshot, hTableDescriptor);
686 }
687 });
688 }
689
690 public void postCloneSnapshot(final SnapshotDescription snapshot,
691 final HTableDescriptor hTableDescriptor) throws IOException {
692 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
693 @Override
694 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
695 throws IOException {
696 oserver.postCloneSnapshot(ctx, snapshot, hTableDescriptor);
697 }
698 });
699 }
700
701 public void preRestoreSnapshot(final SnapshotDescription snapshot,
702 final HTableDescriptor hTableDescriptor) throws IOException {
703 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
704 @Override
705 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
706 throws IOException {
707 oserver.preRestoreSnapshot(ctx, snapshot, hTableDescriptor);
708 }
709 });
710 }
711
712 public void postRestoreSnapshot(final SnapshotDescription snapshot,
713 final HTableDescriptor hTableDescriptor) throws IOException {
714 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
715 @Override
716 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
717 throws IOException {
718 oserver.postRestoreSnapshot(ctx, snapshot, hTableDescriptor);
719 }
720 });
721 }
722
723 public void preDeleteSnapshot(final SnapshotDescription snapshot) throws IOException {
724 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
725 @Override
726 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
727 throws IOException {
728 oserver.preDeleteSnapshot(ctx, snapshot);
729 }
730 });
731 }
732
733 public void postDeleteSnapshot(final SnapshotDescription snapshot) throws IOException {
734 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
735 @Override
736 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
737 throws IOException {
738 oserver.postDeleteSnapshot(ctx, snapshot);
739 }
740 });
741 }
742
743 public boolean preGetTableDescriptors(final List<TableName> tableNamesList,
744 final List<HTableDescriptor> descriptors) throws IOException {
745 return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
746 @Override
747 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
748 throws IOException {
749 oserver.preGetTableDescriptors(ctx, tableNamesList, descriptors);
750 }
751 });
752 }
753
754 public void postGetTableDescriptors(final List<HTableDescriptor> descriptors)
755 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.postGetTableDescriptors(ctx, descriptors);
761 }
762 });
763 }
764
765 private static abstract class CoprocessorOperation
766 extends ObserverContext<MasterCoprocessorEnvironment> {
767 public CoprocessorOperation() {
768 }
769
770 public abstract void call(MasterObserver oserver,
771 ObserverContext<MasterCoprocessorEnvironment> ctx) throws IOException;
772
773 public void postEnvCall(MasterEnvironment env) {
774 }
775 }
776
777 private static abstract class CoprocessorOperationWithResult<T> extends CoprocessorOperation {
778 private T result = null;
779 public void setResult(final T result) { this.result = result; }
780 public T getResult() { return this.result; }
781 }
782
783 private <T> T execOperationWithResult(final T defaultValue,
784 final CoprocessorOperationWithResult<T> ctx) throws IOException {
785 if (ctx == null) return defaultValue;
786 ctx.setResult(defaultValue);
787 execOperation(ctx);
788 return ctx.getResult();
789 }
790
791 private boolean execOperation(final CoprocessorOperation ctx) throws IOException {
792 if (ctx == null) return false;
793 boolean bypass = false;
794 for (MasterEnvironment env: coprocessors) {
795 if (env.getInstance() instanceof MasterObserver) {
796 ctx.prepare(env);
797 Thread currentThread = Thread.currentThread();
798 ClassLoader cl = currentThread.getContextClassLoader();
799 try {
800 currentThread.setContextClassLoader(env.getClassLoader());
801 ctx.call((MasterObserver)env.getInstance(), ctx);
802 } catch (Throwable e) {
803 handleCoprocessorThrowable(env, e);
804 } finally {
805 currentThread.setContextClassLoader(cl);
806 }
807 bypass |= ctx.shouldBypass();
808 if (ctx.shouldComplete()) {
809 break;
810 }
811 }
812 ctx.postEnvCall(env);
813 }
814 return bypass;
815 }
816 }