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.ProcedureInfo;
35 import org.apache.hadoop.hbase.ServerName;
36 import org.apache.hadoop.hbase.TableName;
37 import org.apache.hadoop.hbase.classification.InterfaceAudience;
38 import org.apache.hadoop.hbase.client.Admin;
39 import org.apache.hadoop.hbase.coprocessor.*;
40 import org.apache.hadoop.hbase.master.procedure.MasterProcedureEnv;
41 import org.apache.hadoop.hbase.procedure2.ProcedureExecutor;
42 import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.SnapshotDescription;
43 import org.apache.hadoop.hbase.protobuf.generated.QuotaProtos.Quotas;
44
45
46
47
48
49
50 @InterfaceAudience.Private
51 public class MasterCoprocessorHost
52 extends CoprocessorHost<MasterCoprocessorHost.MasterEnvironment> {
53
54 private static final Log LOG = LogFactory.getLog(MasterCoprocessorHost.class);
55
56
57
58
59
60 static class MasterEnvironment extends CoprocessorHost.Environment
61 implements MasterCoprocessorEnvironment {
62 private MasterServices masterServices;
63
64 public MasterEnvironment(final Class<?> implClass, final Coprocessor impl,
65 final int priority, final int seq, final Configuration conf,
66 final MasterServices services) {
67 super(impl, priority, seq, conf);
68 this.masterServices = services;
69 }
70
71 public MasterServices getMasterServices() {
72 return masterServices;
73 }
74 }
75
76 private MasterServices masterServices;
77
78 public MasterCoprocessorHost(final MasterServices services, final Configuration conf) {
79 super(services);
80 this.conf = conf;
81 this.masterServices = services;
82
83
84
85 boolean coprocessorsEnabled = conf.getBoolean(COPROCESSORS_ENABLED_CONF_KEY,
86 DEFAULT_COPROCESSORS_ENABLED);
87 LOG.info("System coprocessor loading is " + (coprocessorsEnabled ? "enabled" : "disabled"));
88 loadSystemCoprocessors(conf, MASTER_COPROCESSOR_CONF_KEY);
89 }
90
91 @Override
92 public MasterEnvironment createEnvironment(final Class<?> implClass,
93 final Coprocessor instance, final int priority, final int seq,
94 final Configuration conf) {
95 for (Object itf : ClassUtils.getAllInterfaces(implClass)) {
96 Class<?> c = (Class<?>) itf;
97 if (CoprocessorService.class.isAssignableFrom(c)) {
98 masterServices.registerService(((CoprocessorService)instance).getService());
99 }
100 }
101 return new MasterEnvironment(implClass, instance, priority, seq, conf,
102 masterServices);
103 }
104
105 public boolean preCreateNamespace(final NamespaceDescriptor ns) throws IOException {
106 return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
107 @Override
108 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
109 throws IOException {
110 oserver.preCreateNamespace(ctx, ns);
111 }
112 });
113 }
114
115 public void postCreateNamespace(final NamespaceDescriptor ns) throws IOException {
116 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
117 @Override
118 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
119 throws IOException {
120 oserver.postCreateNamespace(ctx, ns);
121 }
122 });
123 }
124
125 public boolean preDeleteNamespace(final String namespaceName) throws IOException {
126 return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
127 @Override
128 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
129 throws IOException {
130 oserver.preDeleteNamespace(ctx, namespaceName);
131 }
132 });
133 }
134
135 public void postDeleteNamespace(final String namespaceName) throws IOException {
136 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
137 @Override
138 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
139 throws IOException {
140 oserver.postDeleteNamespace(ctx, namespaceName);
141 }
142 });
143 }
144
145 public boolean preModifyNamespace(final NamespaceDescriptor ns) throws IOException {
146 return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
147 @Override
148 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
149 throws IOException {
150 oserver.preModifyNamespace(ctx, ns);
151 }
152 });
153 }
154
155 public void postModifyNamespace(final NamespaceDescriptor ns) throws IOException {
156 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
157 @Override
158 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
159 throws IOException {
160 oserver.postModifyNamespace(ctx, ns);
161 }
162 });
163 }
164
165 public void preGetNamespaceDescriptor(final String namespaceName)
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.preGetNamespaceDescriptor(ctx, namespaceName);
172 }
173 });
174 }
175
176 public void postGetNamespaceDescriptor(final NamespaceDescriptor ns)
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.postGetNamespaceDescriptor(ctx, ns);
183 }
184 });
185 }
186
187 public boolean preListNamespaceDescriptors(final List<NamespaceDescriptor> descriptors)
188 throws IOException {
189 return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
190 @Override
191 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
192 throws IOException {
193 oserver.preListNamespaceDescriptors(ctx, descriptors);
194 }
195 });
196 }
197
198 public void postListNamespaceDescriptors(final List<NamespaceDescriptor> descriptors)
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.postListNamespaceDescriptors(ctx, descriptors);
205 }
206 });
207 }
208
209
210
211 public void preCreateTable(final HTableDescriptor htd, final HRegionInfo[] regions)
212 throws IOException {
213 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
214 @Override
215 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
216 throws IOException {
217 oserver.preCreateTable(ctx, htd, regions);
218 }
219 });
220 }
221
222 public void postCreateTable(final HTableDescriptor htd, final HRegionInfo[] regions)
223 throws IOException {
224 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
225 @Override
226 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
227 throws IOException {
228 oserver.postCreateTable(ctx, htd, regions);
229 }
230 });
231 }
232
233 public void preCreateTableHandler(final HTableDescriptor htd, final HRegionInfo[] regions)
234 throws IOException {
235 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
236 @Override
237 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
238 throws IOException {
239 oserver.preCreateTableHandler(ctx, htd, regions);
240 }
241 });
242 }
243
244 public void postCreateTableHandler(final HTableDescriptor htd, final HRegionInfo[] regions)
245 throws IOException {
246 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
247 @Override
248 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
249 throws IOException {
250 oserver.postCreateTableHandler(ctx, htd, regions);
251 }
252 });
253 }
254
255 public void preDeleteTable(final TableName tableName) throws IOException {
256 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
257 @Override
258 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
259 throws IOException {
260 oserver.preDeleteTable(ctx, tableName);
261 }
262 });
263 }
264
265 public void postDeleteTable(final TableName tableName) throws IOException {
266 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
267 @Override
268 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
269 throws IOException {
270 oserver.postDeleteTable(ctx, tableName);
271 }
272 });
273 }
274
275 public void preDeleteTableHandler(final TableName tableName) throws IOException {
276 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
277 @Override
278 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
279 throws IOException {
280 oserver.preDeleteTableHandler(ctx, tableName);
281 }
282 });
283 }
284
285 public void postDeleteTableHandler(final TableName tableName) throws IOException {
286 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
287 @Override
288 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
289 throws IOException {
290 oserver.postDeleteTableHandler(ctx, tableName);
291 }
292 });
293 }
294
295 public void preTruncateTable(final TableName tableName) throws IOException {
296 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
297 @Override
298 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
299 throws IOException {
300 oserver.preTruncateTable(ctx, tableName);
301 }
302 });
303 }
304
305 public void postTruncateTable(final TableName tableName) throws IOException {
306 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
307 @Override
308 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
309 throws IOException {
310 oserver.postTruncateTable(ctx, tableName);
311 }
312 });
313 }
314
315 public void preTruncateTableHandler(final TableName tableName) throws IOException {
316 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
317 @Override
318 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
319 throws IOException {
320 oserver.preTruncateTableHandler(ctx, tableName);
321 }
322 });
323 }
324
325 public void postTruncateTableHandler(final TableName tableName) throws IOException {
326 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
327 @Override
328 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
329 throws IOException {
330 oserver.postTruncateTableHandler(ctx, tableName);
331 }
332 });
333 }
334
335 public void preModifyTable(final TableName tableName, final HTableDescriptor htd)
336 throws IOException {
337 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
338 @Override
339 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
340 throws IOException {
341 oserver.preModifyTable(ctx, tableName, htd);
342 }
343 });
344 }
345
346 public void postModifyTable(final TableName tableName, final HTableDescriptor htd)
347 throws IOException {
348 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
349 @Override
350 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
351 throws IOException {
352 oserver.postModifyTable(ctx, tableName, htd);
353 }
354 });
355 }
356
357 public void preModifyTableHandler(final TableName tableName, final HTableDescriptor htd)
358 throws IOException {
359 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
360 @Override
361 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
362 throws IOException {
363 oserver.preModifyTableHandler(ctx, tableName, htd);
364 }
365 });
366 }
367
368 public void postModifyTableHandler(final TableName tableName, final HTableDescriptor htd)
369 throws IOException {
370 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
371 @Override
372 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
373 throws IOException {
374 oserver.postModifyTableHandler(ctx, tableName, htd);
375 }
376 });
377 }
378
379 public boolean preAddColumn(final TableName tableName, final HColumnDescriptor column)
380 throws IOException {
381 return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
382 @Override
383 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
384 throws IOException {
385 oserver.preAddColumn(ctx, tableName, column);
386 }
387 });
388 }
389
390 public void postAddColumn(final TableName tableName, final HColumnDescriptor column)
391 throws IOException {
392 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
393 @Override
394 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
395 throws IOException {
396 oserver.postAddColumn(ctx, tableName, column);
397 }
398 });
399 }
400
401 public boolean preAddColumnHandler(final TableName tableName, final HColumnDescriptor column)
402 throws IOException {
403 return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
404 @Override
405 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
406 throws IOException {
407 oserver.preAddColumnHandler(ctx, tableName, column);
408 }
409 });
410 }
411
412 public void postAddColumnHandler(final TableName tableName, final HColumnDescriptor column)
413 throws IOException {
414 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
415 @Override
416 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
417 throws IOException {
418 oserver.postAddColumnHandler(ctx, tableName, column);
419 }
420 });
421 }
422
423 public boolean preModifyColumn(final TableName tableName, final HColumnDescriptor descriptor)
424 throws IOException {
425 return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
426 @Override
427 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
428 throws IOException {
429 oserver.preModifyColumn(ctx, tableName, descriptor);
430 }
431 });
432 }
433
434 public void postModifyColumn(final TableName tableName, final HColumnDescriptor descriptor)
435 throws IOException {
436 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
437 @Override
438 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
439 throws IOException {
440 oserver.postModifyColumn(ctx, tableName, descriptor);
441 }
442 });
443 }
444
445 public boolean preModifyColumnHandler(final TableName tableName,
446 final HColumnDescriptor descriptor) throws IOException {
447 return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
448 @Override
449 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
450 throws IOException {
451 oserver.preModifyColumnHandler(ctx, tableName, descriptor);
452 }
453 });
454 }
455
456 public void postModifyColumnHandler(final TableName tableName,
457 final HColumnDescriptor descriptor) throws IOException {
458 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
459 @Override
460 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
461 throws IOException {
462 oserver.postModifyColumnHandler(ctx, tableName, descriptor);
463 }
464 });
465 }
466
467 public boolean preDeleteColumn(final TableName tableName, final byte [] c) throws IOException {
468 return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
469 @Override
470 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
471 throws IOException {
472 oserver.preDeleteColumn(ctx, tableName, c);
473 }
474 });
475 }
476
477 public void postDeleteColumn(final TableName tableName, final byte [] c) throws IOException {
478 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
479 @Override
480 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
481 throws IOException {
482 oserver.postDeleteColumn(ctx, tableName, c);
483 }
484 });
485 }
486
487 public boolean preDeleteColumnHandler(final TableName tableName, final byte[] c)
488 throws IOException {
489 return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
490 @Override
491 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
492 throws IOException {
493 oserver.preDeleteColumnHandler(ctx, tableName, c);
494 }
495 });
496 }
497
498 public void postDeleteColumnHandler(final TableName tableName, final byte[] c)
499 throws IOException {
500 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
501 @Override
502 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
503 throws IOException {
504 oserver.postDeleteColumnHandler(ctx, tableName, c);
505 }
506 });
507 }
508
509 public void preEnableTable(final TableName tableName) throws IOException {
510 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
511 @Override
512 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
513 throws IOException {
514 oserver.preEnableTable(ctx, tableName);
515 }
516 });
517 }
518
519 public void postEnableTable(final TableName tableName) throws IOException {
520 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
521 @Override
522 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
523 throws IOException {
524 oserver.postEnableTable(ctx, tableName);
525 }
526 });
527 }
528
529 public void preEnableTableHandler(final TableName tableName) throws IOException {
530 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
531 @Override
532 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
533 throws IOException {
534 oserver.preEnableTableHandler(ctx, tableName);
535 }
536 });
537 }
538
539 public void postEnableTableHandler(final TableName tableName) throws IOException {
540 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
541 @Override
542 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
543 throws IOException {
544 oserver.postEnableTableHandler(ctx, tableName);
545 }
546 });
547 }
548
549 public void preDisableTable(final TableName tableName) throws IOException {
550 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
551 @Override
552 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
553 throws IOException {
554 oserver.preDisableTable(ctx, tableName);
555 }
556 });
557 }
558
559 public void postDisableTable(final TableName tableName) throws IOException {
560 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
561 @Override
562 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
563 throws IOException {
564 oserver.postDisableTable(ctx, tableName);
565 }
566 });
567 }
568
569 public void preDisableTableHandler(final TableName tableName) throws IOException {
570 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
571 @Override
572 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
573 throws IOException {
574 oserver.preDisableTableHandler(ctx, tableName);
575 }
576 });
577 }
578
579 public void postDisableTableHandler(final TableName tableName) throws IOException {
580 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
581 @Override
582 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
583 throws IOException {
584 oserver.postDisableTableHandler(ctx, tableName);
585 }
586 });
587 }
588
589 public boolean preAbortProcedure(
590 final ProcedureExecutor<MasterProcedureEnv> procEnv,
591 final long procId) throws IOException {
592 return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
593 @Override
594 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
595 throws IOException {
596 oserver.preAbortProcedure(ctx, procEnv, procId);
597 }
598 });
599 }
600
601 public void postAbortProcedure() throws IOException {
602 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
603 @Override
604 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
605 throws IOException {
606 oserver.postAbortProcedure(ctx);
607 }
608 });
609 }
610
611 public boolean preListProcedures() throws IOException {
612 return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
613 @Override
614 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
615 throws IOException {
616 oserver.preListProcedures(ctx);
617 }
618 });
619 }
620
621 public void postListProcedures(final List<ProcedureInfo> procInfoList) throws IOException {
622 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
623 @Override
624 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
625 throws IOException {
626 oserver.postListProcedures(ctx, procInfoList);
627 }
628 });
629 }
630
631 public boolean preMove(final HRegionInfo region, final ServerName srcServer,
632 final ServerName destServer) throws IOException {
633 return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
634 @Override
635 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
636 throws IOException {
637 oserver.preMove(ctx, region, srcServer, destServer);
638 }
639 });
640 }
641
642 public void postMove(final HRegionInfo region, final ServerName srcServer,
643 final ServerName destServer) throws IOException {
644 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
645 @Override
646 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
647 throws IOException {
648 oserver.postMove(ctx, region, srcServer, destServer);
649 }
650 });
651 }
652
653 public boolean preAssign(final HRegionInfo regionInfo) throws IOException {
654 return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
655 @Override
656 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
657 throws IOException {
658 oserver.preAssign(ctx, regionInfo);
659 }
660 });
661 }
662
663 public void postAssign(final HRegionInfo regionInfo) throws IOException {
664 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
665 @Override
666 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
667 throws IOException {
668 oserver.postAssign(ctx, regionInfo);
669 }
670 });
671 }
672
673 public boolean preUnassign(final HRegionInfo regionInfo, final boolean force)
674 throws IOException {
675 return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
676 @Override
677 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
678 throws IOException {
679 oserver.preUnassign(ctx, regionInfo, force);
680 }
681 });
682 }
683
684 public void postUnassign(final HRegionInfo regionInfo, final boolean force) throws IOException {
685 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
686 @Override
687 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
688 throws IOException {
689 oserver.postUnassign(ctx, regionInfo, force);
690 }
691 });
692 }
693
694 public void preRegionOffline(final HRegionInfo regionInfo) throws IOException {
695 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
696 @Override
697 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
698 throws IOException {
699 oserver.preRegionOffline(ctx, regionInfo);
700 }
701 });
702 }
703
704 public void postRegionOffline(final HRegionInfo regionInfo) throws IOException {
705 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
706 @Override
707 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
708 throws IOException {
709 oserver.postRegionOffline(ctx, regionInfo);
710 }
711 });
712 }
713
714 public void preDispatchMerge(final HRegionInfo regionInfoA, final HRegionInfo regionInfoB)
715 throws IOException {
716 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
717 @Override
718 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
719 throws IOException {
720 oserver.preDispatchMerge(ctx, regionInfoA, regionInfoB);
721 }
722 });
723 }
724
725 public void postDispatchMerge(final HRegionInfo regionInfoA, final HRegionInfo regionInfoB)
726 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.postDispatchMerge(ctx, regionInfoA, regionInfoB);
732 }
733 });
734 }
735
736 public boolean preBalance() throws IOException {
737 return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
738 @Override
739 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
740 throws IOException {
741 oserver.preBalance(ctx);
742 }
743 });
744 }
745
746 public void postBalance(final List<RegionPlan> plans) throws IOException {
747 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
748 @Override
749 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
750 throws IOException {
751 oserver.postBalance(ctx, plans);
752 }
753 });
754 }
755
756 public boolean preSetSplitOrMergeEnabled(final boolean newValue,
757 final Admin.MasterSwitchType switchType) throws IOException {
758 return execOperation(coprocessors.isEmpty() ? null :
759 new CoprocessorOperation() {
760 @Override
761 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
762 throws IOException {
763 oserver.preSetSplitOrMergeEnabled(ctx, newValue, switchType);
764 }
765 });
766 }
767
768 public void postSetSplitOrMergeEnabled(final boolean newValue,
769 final Admin.MasterSwitchType switchType) 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.postSetSplitOrMergeEnabled(ctx, newValue, switchType);
775 }
776 });
777 }
778
779 public boolean preBalanceSwitch(final boolean b) throws IOException {
780 return execOperationWithResult(b, coprocessors.isEmpty() ? null :
781 new CoprocessorOperationWithResult<Boolean>() {
782 @Override
783 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
784 throws IOException {
785 setResult(oserver.preBalanceSwitch(ctx, getResult()));
786 }
787 });
788 }
789
790 public void postBalanceSwitch(final boolean oldValue, final boolean newValue)
791 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.postBalanceSwitch(ctx, oldValue, newValue);
797 }
798 });
799 }
800
801 public void preShutdown() throws IOException {
802
803
804 execShutdown(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
805 @Override
806 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
807 throws IOException {
808 oserver.preShutdown(ctx);
809 }
810 @Override
811 public void postEnvCall(MasterEnvironment env) {
812
813 shutdown(env);
814 }
815 });
816 }
817
818 public void preStopMaster() throws IOException {
819
820
821 execShutdown(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
822 @Override
823 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
824 throws IOException {
825 oserver.preStopMaster(ctx);
826 }
827 @Override
828 public void postEnvCall(MasterEnvironment env) {
829
830 shutdown(env);
831 }
832 });
833 }
834
835 public void preMasterInitialization() 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.preMasterInitialization(ctx);
841 }
842 });
843 }
844
845 public void postStartMaster() throws IOException {
846 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
847 @Override
848 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
849 throws IOException {
850 oserver.postStartMaster(ctx);
851 }
852 });
853 }
854
855 public void preSnapshot(final SnapshotDescription snapshot,
856 final HTableDescriptor hTableDescriptor) 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.preSnapshot(ctx, snapshot, hTableDescriptor);
862 }
863 });
864 }
865
866 public void postSnapshot(final SnapshotDescription snapshot,
867 final HTableDescriptor hTableDescriptor) throws IOException {
868 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
869 @Override
870 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
871 throws IOException {
872 oserver.postSnapshot(ctx, snapshot, hTableDescriptor);
873 }
874 });
875 }
876
877 public void preListSnapshot(final SnapshotDescription snapshot) throws IOException {
878 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
879 @Override
880 public void call(MasterObserver observer, ObserverContext<MasterCoprocessorEnvironment> ctx)
881 throws IOException {
882 observer.preListSnapshot(ctx, snapshot);
883 }
884 });
885 }
886
887 public void postListSnapshot(final SnapshotDescription snapshot) throws IOException {
888 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
889 @Override
890 public void call(MasterObserver observer, ObserverContext<MasterCoprocessorEnvironment> ctx)
891 throws IOException {
892 observer.postListSnapshot(ctx, snapshot);
893 }
894 });
895 }
896
897 public void preCloneSnapshot(final SnapshotDescription snapshot,
898 final HTableDescriptor hTableDescriptor) throws IOException {
899 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
900 @Override
901 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
902 throws IOException {
903 oserver.preCloneSnapshot(ctx, snapshot, hTableDescriptor);
904 }
905 });
906 }
907
908 public void postCloneSnapshot(final SnapshotDescription snapshot,
909 final HTableDescriptor hTableDescriptor) throws IOException {
910 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
911 @Override
912 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
913 throws IOException {
914 oserver.postCloneSnapshot(ctx, snapshot, hTableDescriptor);
915 }
916 });
917 }
918
919 public void preRestoreSnapshot(final SnapshotDescription snapshot,
920 final HTableDescriptor hTableDescriptor) throws IOException {
921 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
922 @Override
923 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
924 throws IOException {
925 oserver.preRestoreSnapshot(ctx, snapshot, hTableDescriptor);
926 }
927 });
928 }
929
930 public void postRestoreSnapshot(final SnapshotDescription snapshot,
931 final HTableDescriptor hTableDescriptor) throws IOException {
932 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
933 @Override
934 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
935 throws IOException {
936 oserver.postRestoreSnapshot(ctx, snapshot, hTableDescriptor);
937 }
938 });
939 }
940
941 public void preDeleteSnapshot(final SnapshotDescription snapshot) throws IOException {
942 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
943 @Override
944 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
945 throws IOException {
946 oserver.preDeleteSnapshot(ctx, snapshot);
947 }
948 });
949 }
950
951 public void postDeleteSnapshot(final SnapshotDescription snapshot) throws IOException {
952 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
953 @Override
954 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
955 throws IOException {
956 oserver.postDeleteSnapshot(ctx, snapshot);
957 }
958 });
959 }
960
961 @Deprecated
962 public boolean preGetTableDescriptors(final List<TableName> tableNamesList,
963 final List<HTableDescriptor> descriptors) throws IOException {
964 return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
965 @Override
966 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
967 throws IOException {
968 oserver.preGetTableDescriptors(ctx, tableNamesList, descriptors);
969 }
970 });
971 }
972
973 @Deprecated
974 public void postGetTableDescriptors(final List<HTableDescriptor> descriptors)
975 throws IOException {
976 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
977 @Override
978 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
979 throws IOException {
980 oserver.postGetTableDescriptors(ctx, descriptors);
981 }
982 });
983 }
984
985 public boolean preGetTableDescriptors(final List<TableName> tableNamesList,
986 final List<HTableDescriptor> descriptors, final String regex) throws IOException {
987 return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
988 @Override
989 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
990 throws IOException {
991 oserver.preGetTableDescriptors(ctx, tableNamesList, descriptors, regex);
992 }
993 });
994 }
995
996 public void postGetTableDescriptors(final List<TableName> tableNamesList,
997 final List<HTableDescriptor> descriptors, final String regex) throws IOException {
998 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
999 @Override
1000 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
1001 throws IOException {
1002 oserver.postGetTableDescriptors(ctx, tableNamesList, descriptors, regex);
1003 }
1004 });
1005 }
1006
1007 public boolean preGetTableNames(final List<HTableDescriptor> descriptors,
1008 final String regex) throws IOException {
1009 return execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
1010 @Override
1011 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
1012 throws IOException {
1013 oserver.preGetTableNames(ctx, descriptors, regex);
1014 }
1015 });
1016 }
1017
1018 public void postGetTableNames(final List<HTableDescriptor> descriptors,
1019 final String regex) throws IOException {
1020 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
1021 @Override
1022 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
1023 throws IOException {
1024 oserver.postGetTableNames(ctx, descriptors, regex);
1025 }
1026 });
1027 }
1028
1029 public void preTableFlush(final TableName tableName) throws IOException {
1030 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
1031 @Override
1032 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
1033 throws IOException {
1034 oserver.preTableFlush(ctx, tableName);
1035 }
1036 });
1037 }
1038
1039 public void postTableFlush(final TableName tableName) throws IOException {
1040 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
1041 @Override
1042 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
1043 throws IOException {
1044 oserver.postTableFlush(ctx, tableName);
1045 }
1046 });
1047 }
1048
1049 public void preSetUserQuota(final String user, final Quotas quotas) throws IOException {
1050 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
1051 @Override
1052 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
1053 throws IOException {
1054 oserver.preSetUserQuota(ctx, user, quotas);
1055 }
1056 });
1057 }
1058
1059 public void postSetUserQuota(final String user, final Quotas quotas) throws IOException {
1060 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
1061 @Override
1062 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
1063 throws IOException {
1064 oserver.postSetUserQuota(ctx, user, quotas);
1065 }
1066 });
1067 }
1068
1069 public void preSetUserQuota(final String user, final TableName table, final Quotas quotas)
1070 throws IOException {
1071 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
1072 @Override
1073 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
1074 throws IOException {
1075 oserver.preSetUserQuota(ctx, user, table, quotas);
1076 }
1077 });
1078 }
1079
1080 public void postSetUserQuota(final String user, final TableName table, final Quotas quotas)
1081 throws IOException {
1082 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
1083 @Override
1084 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
1085 throws IOException {
1086 oserver.postSetUserQuota(ctx, user, table, quotas);
1087 }
1088 });
1089 }
1090
1091 public void preSetUserQuota(final String user, final String namespace, final Quotas quotas)
1092 throws IOException {
1093 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
1094 @Override
1095 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
1096 throws IOException {
1097 oserver.preSetUserQuota(ctx, user, namespace, quotas);
1098 }
1099 });
1100 }
1101
1102 public void postSetUserQuota(final String user, final String namespace, final Quotas quotas)
1103 throws IOException {
1104 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
1105 @Override
1106 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
1107 throws IOException {
1108 oserver.postSetUserQuota(ctx, user, namespace, quotas);
1109 }
1110 });
1111 }
1112
1113 public void preSetTableQuota(final TableName table, final Quotas quotas) throws IOException {
1114 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
1115 @Override
1116 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
1117 throws IOException {
1118 oserver.preSetTableQuota(ctx, table, quotas);
1119 }
1120 });
1121 }
1122
1123 public void postSetTableQuota(final TableName table, final Quotas quotas) throws IOException {
1124 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
1125 @Override
1126 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
1127 throws IOException {
1128 oserver.postSetTableQuota(ctx, table, quotas);
1129 }
1130 });
1131 }
1132
1133 public void preSetNamespaceQuota(final String namespace, final Quotas quotas) throws IOException {
1134 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
1135 @Override
1136 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
1137 throws IOException {
1138 oserver.preSetNamespaceQuota(ctx, namespace, quotas);
1139 }
1140 });
1141 }
1142
1143 public void postSetNamespaceQuota(final String namespace, final Quotas quotas)
1144 throws IOException {
1145 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() {
1146 @Override
1147 public void call(MasterObserver oserver, ObserverContext<MasterCoprocessorEnvironment> ctx)
1148 throws IOException {
1149 oserver.postSetNamespaceQuota(ctx, namespace, quotas);
1150 }
1151 });
1152 }
1153
1154 private static abstract class CoprocessorOperation
1155 extends ObserverContext<MasterCoprocessorEnvironment> {
1156 public CoprocessorOperation() {
1157 }
1158
1159 public abstract void call(MasterObserver oserver,
1160 ObserverContext<MasterCoprocessorEnvironment> ctx) throws IOException;
1161
1162 public void postEnvCall(MasterEnvironment env) {
1163 }
1164 }
1165
1166 private static abstract class CoprocessorOperationWithResult<T> extends CoprocessorOperation {
1167 private T result = null;
1168 public void setResult(final T result) { this.result = result; }
1169 public T getResult() { return this.result; }
1170 }
1171
1172 private <T> T execOperationWithResult(final T defaultValue,
1173 final CoprocessorOperationWithResult<T> ctx) throws IOException {
1174 if (ctx == null) return defaultValue;
1175 ctx.setResult(defaultValue);
1176 execOperation(ctx);
1177 return ctx.getResult();
1178 }
1179
1180 private boolean execOperation(final CoprocessorOperation ctx) throws IOException {
1181 if (ctx == null) return false;
1182 boolean bypass = false;
1183 List<MasterEnvironment> envs = coprocessors.get();
1184 for (int i = 0; i < envs.size(); i++) {
1185 MasterEnvironment env = envs.get(i);
1186 if (env.getInstance() instanceof MasterObserver) {
1187 ctx.prepare(env);
1188 Thread currentThread = Thread.currentThread();
1189 ClassLoader cl = currentThread.getContextClassLoader();
1190 try {
1191 currentThread.setContextClassLoader(env.getClassLoader());
1192 ctx.call((MasterObserver)env.getInstance(), ctx);
1193 } catch (Throwable e) {
1194 handleCoprocessorThrowable(env, e);
1195 } finally {
1196 currentThread.setContextClassLoader(cl);
1197 }
1198 bypass |= ctx.shouldBypass();
1199 if (ctx.shouldComplete()) {
1200 break;
1201 }
1202 }
1203 ctx.postEnvCall(env);
1204 }
1205 return bypass;
1206 }
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220 private boolean execShutdown(final CoprocessorOperation ctx) throws IOException {
1221 if (ctx == null) return false;
1222 boolean bypass = false;
1223 List<MasterEnvironment> envs = coprocessors.get();
1224 int envsSize = envs.size();
1225
1226 for (int i = 0; i < envsSize; i++) {
1227 MasterEnvironment env = envs.get(i);
1228 if (env.getInstance() instanceof MasterObserver) {
1229 ctx.prepare(env);
1230 Thread currentThread = Thread.currentThread();
1231 ClassLoader cl = currentThread.getContextClassLoader();
1232 try {
1233 currentThread.setContextClassLoader(env.getClassLoader());
1234 ctx.call((MasterObserver) env.getInstance(), ctx);
1235 } catch (Throwable e) {
1236 handleCoprocessorThrowable(env, e);
1237 } finally {
1238 currentThread.setContextClassLoader(cl);
1239 }
1240 bypass |= ctx.shouldBypass();
1241 if (ctx.shouldComplete()) {
1242 break;
1243 }
1244 }
1245 }
1246
1247
1248 for (int i = 0; i < envsSize; i++) {
1249 MasterEnvironment env = envs.get(i);
1250 ctx.postEnvCall(env);
1251 }
1252 return bypass;
1253 }
1254
1255 }