HBASE-20567 Pass both old and new descriptors to pre/post hooks of modify operations for table and namespace.
Signed-off-by: Mike Drob <mdrob@apache.org>
This commit is contained in:
parent
77eaff0e10
commit
61f2b5f071
|
@ -209,20 +209,52 @@ public interface MasterObserver {
|
||||||
* table RPC call.
|
* table RPC call.
|
||||||
* @param ctx the environment to interact with the framework and master
|
* @param ctx the environment to interact with the framework and master
|
||||||
* @param tableName the name of the table
|
* @param tableName the name of the table
|
||||||
* @param htd the TableDescriptor
|
* @param newDescriptor after modify operation, table will have this descriptor
|
||||||
|
* @deprecated Since 2.1. Will be removed in 3.0.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
default void preModifyTable(final ObserverContext<MasterCoprocessorEnvironment> ctx,
|
||||||
|
final TableName tableName, TableDescriptor newDescriptor) throws IOException {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called prior to modifying a table's properties. Called as part of modify
|
||||||
|
* table RPC call.
|
||||||
|
* @param ctx the environment to interact with the framework and master
|
||||||
|
* @param tableName the name of the table
|
||||||
|
* @param currentDescriptor current TableDescriptor of the table
|
||||||
|
* @param newDescriptor after modify operation, table will have this descriptor
|
||||||
*/
|
*/
|
||||||
default void preModifyTable(final ObserverContext<MasterCoprocessorEnvironment> ctx,
|
default void preModifyTable(final ObserverContext<MasterCoprocessorEnvironment> ctx,
|
||||||
final TableName tableName, TableDescriptor htd) throws IOException {}
|
final TableName tableName, TableDescriptor currentDescriptor, TableDescriptor newDescriptor)
|
||||||
|
throws IOException {
|
||||||
|
preModifyTable(ctx, tableName, newDescriptor);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called after the modifyTable operation has been requested. Called as part
|
* Called after the modifyTable operation has been requested. Called as part
|
||||||
* of modify table RPC call.
|
* of modify table RPC call.
|
||||||
* @param ctx the environment to interact with the framework and master
|
* @param ctx the environment to interact with the framework and master
|
||||||
* @param tableName the name of the table
|
* @param tableName the name of the table
|
||||||
* @param htd the TableDescriptor
|
* @param currentDescriptor current TableDescriptor of the table
|
||||||
|
* @deprecated Since 2.1. Will be removed in 3.0.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
default void postModifyTable(final ObserverContext<MasterCoprocessorEnvironment> ctx,
|
||||||
|
final TableName tableName, TableDescriptor currentDescriptor) throws IOException {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called after the modifyTable operation has been requested. Called as part
|
||||||
|
* of modify table RPC call.
|
||||||
|
* @param ctx the environment to interact with the framework and master
|
||||||
|
* @param tableName the name of the table
|
||||||
|
* @param oldDescriptor descriptor of table before modify operation happened
|
||||||
|
* @param currentDescriptor current TableDescriptor of the table
|
||||||
*/
|
*/
|
||||||
default void postModifyTable(final ObserverContext<MasterCoprocessorEnvironment> ctx,
|
default void postModifyTable(final ObserverContext<MasterCoprocessorEnvironment> ctx,
|
||||||
final TableName tableName, TableDescriptor htd) throws IOException {}
|
final TableName tableName, TableDescriptor oldDescriptor, TableDescriptor currentDescriptor)
|
||||||
|
throws IOException {
|
||||||
|
postModifyTable(ctx, tableName, currentDescriptor);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called prior to modifying a table's properties. Called as part of modify
|
* Called prior to modifying a table's properties. Called as part of modify
|
||||||
|
@ -230,12 +262,31 @@ public interface MasterObserver {
|
||||||
*
|
*
|
||||||
* @param ctx the environment to interact with the framework and master
|
* @param ctx the environment to interact with the framework and master
|
||||||
* @param tableName the name of the table
|
* @param tableName the name of the table
|
||||||
* @param htd the TableDescriptor
|
* @param newDescriptor after modify operation, table will have this descriptor
|
||||||
|
* @deprecated Since 2.1. Will be removed in 3.0.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
default void preModifyTableAction(
|
||||||
|
final ObserverContext<MasterCoprocessorEnvironment> ctx,
|
||||||
|
final TableName tableName,
|
||||||
|
final TableDescriptor newDescriptor) throws IOException {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called prior to modifying a table's properties. Called as part of modify
|
||||||
|
* table procedure and it is async to the modify table RPC call.
|
||||||
|
*
|
||||||
|
* @param ctx the environment to interact with the framework and master
|
||||||
|
* @param tableName the name of the table
|
||||||
|
* @param currentDescriptor current TableDescriptor of the table
|
||||||
|
* @param newDescriptor after modify operation, table will have this descriptor
|
||||||
*/
|
*/
|
||||||
default void preModifyTableAction(
|
default void preModifyTableAction(
|
||||||
final ObserverContext<MasterCoprocessorEnvironment> ctx,
|
final ObserverContext<MasterCoprocessorEnvironment> ctx,
|
||||||
final TableName tableName,
|
final TableName tableName,
|
||||||
final TableDescriptor htd) throws IOException {}
|
final TableDescriptor currentDescriptor,
|
||||||
|
final TableDescriptor newDescriptor) throws IOException {
|
||||||
|
preModifyTableAction(ctx, tableName, newDescriptor);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called after to modifying a table's properties. Called as part of modify
|
* Called after to modifying a table's properties. Called as part of modify
|
||||||
|
@ -243,12 +294,31 @@ public interface MasterObserver {
|
||||||
*
|
*
|
||||||
* @param ctx the environment to interact with the framework and master
|
* @param ctx the environment to interact with the framework and master
|
||||||
* @param tableName the name of the table
|
* @param tableName the name of the table
|
||||||
* @param htd the TableDescriptor
|
* @param currentDescriptor current TableDescriptor of the table
|
||||||
|
* @deprecated Since 2.1. Will be removed in 3.0.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
default void postCompletedModifyTableAction(
|
||||||
|
final ObserverContext<MasterCoprocessorEnvironment> ctx,
|
||||||
|
final TableName tableName,
|
||||||
|
final TableDescriptor currentDescriptor) throws IOException {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called after to modifying a table's properties. Called as part of modify
|
||||||
|
* table procedure and it is async to the modify table RPC call.
|
||||||
|
*
|
||||||
|
* @param ctx the environment to interact with the framework and master
|
||||||
|
* @param tableName the name of the table
|
||||||
|
* @param oldDescriptor descriptor of table before modify operation happened
|
||||||
|
* @param currentDescriptor current TableDescriptor of the table
|
||||||
*/
|
*/
|
||||||
default void postCompletedModifyTableAction(
|
default void postCompletedModifyTableAction(
|
||||||
final ObserverContext<MasterCoprocessorEnvironment> ctx,
|
final ObserverContext<MasterCoprocessorEnvironment> ctx,
|
||||||
final TableName tableName,
|
final TableName tableName,
|
||||||
final TableDescriptor htd) throws IOException {}
|
final TableDescriptor oldDescriptor,
|
||||||
|
final TableDescriptor currentDescriptor) throws IOException {
|
||||||
|
postCompletedModifyTableAction(ctx, tableName, currentDescriptor);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called prior to enabling a table. Called as part of enable table RPC call.
|
* Called prior to enabling a table. Called as part of enable table RPC call.
|
||||||
|
@ -817,18 +887,46 @@ public interface MasterObserver {
|
||||||
/**
|
/**
|
||||||
* Called prior to modifying a namespace's properties.
|
* Called prior to modifying a namespace's properties.
|
||||||
* @param ctx the environment to interact with the framework and master
|
* @param ctx the environment to interact with the framework and master
|
||||||
* @param ns the NamespaceDescriptor
|
* @param newNsDescriptor after modify operation, namespace will have this descriptor
|
||||||
|
* @deprecated Since 2.1. Will be removed in 3.0.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
default void preModifyNamespace(final ObserverContext<MasterCoprocessorEnvironment> ctx,
|
||||||
|
NamespaceDescriptor newNsDescriptor) throws IOException {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called prior to modifying a namespace's properties.
|
||||||
|
* @param ctx the environment to interact with the framework and master
|
||||||
|
* @param currentNsDescriptor current NamespaceDescriptor of the namespace
|
||||||
|
* @param newNsDescriptor after modify operation, namespace will have this descriptor
|
||||||
*/
|
*/
|
||||||
default void preModifyNamespace(final ObserverContext<MasterCoprocessorEnvironment> ctx,
|
default void preModifyNamespace(final ObserverContext<MasterCoprocessorEnvironment> ctx,
|
||||||
NamespaceDescriptor ns) throws IOException {}
|
NamespaceDescriptor currentNsDescriptor, NamespaceDescriptor newNsDescriptor)
|
||||||
|
throws IOException {
|
||||||
|
preModifyNamespace(ctx, newNsDescriptor);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called after the modifyNamespace operation has been requested.
|
* Called after the modifyNamespace operation has been requested.
|
||||||
* @param ctx the environment to interact with the framework and master
|
* @param ctx the environment to interact with the framework and master
|
||||||
* @param ns the NamespaceDescriptor
|
* @param currentNsDescriptor current NamespaceDescriptor of the namespace
|
||||||
|
* @deprecated Since 2.1. Will be removed in 3.0.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
default void postModifyNamespace(final ObserverContext<MasterCoprocessorEnvironment> ctx,
|
||||||
|
NamespaceDescriptor currentNsDescriptor) throws IOException {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called after the modifyNamespace operation has been requested.
|
||||||
|
* @param ctx the environment to interact with the framework and master
|
||||||
|
* @param oldNsDescriptor descriptor of namespace before modify operation happened
|
||||||
|
* @param currentNsDescriptor current NamespaceDescriptor of the namespace
|
||||||
*/
|
*/
|
||||||
default void postModifyNamespace(final ObserverContext<MasterCoprocessorEnvironment> ctx,
|
default void postModifyNamespace(final ObserverContext<MasterCoprocessorEnvironment> ctx,
|
||||||
NamespaceDescriptor ns) throws IOException {}
|
NamespaceDescriptor oldNsDescriptor, NamespaceDescriptor currentNsDescriptor)
|
||||||
|
throws IOException {
|
||||||
|
postModifyNamespace(ctx, currentNsDescriptor);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called before a getNamespaceDescriptor request has been processed.
|
* Called before a getNamespaceDescriptor request has been processed.
|
||||||
|
|
|
@ -2362,16 +2362,18 @@ public class HMaster extends HRegionServer implements MasterServices {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long modifyTable(final TableName tableName, final TableDescriptor descriptor,
|
public long modifyTable(final TableName tableName, final TableDescriptor newDescriptor,
|
||||||
final long nonceGroup, final long nonce) throws IOException {
|
final long nonceGroup, final long nonce) throws IOException {
|
||||||
checkInitialized();
|
checkInitialized();
|
||||||
sanityCheckTableDescriptor(descriptor);
|
sanityCheckTableDescriptor(newDescriptor);
|
||||||
|
|
||||||
return MasterProcedureUtil.submitProcedure(
|
return MasterProcedureUtil.submitProcedure(
|
||||||
new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {
|
new MasterProcedureUtil.NonceProcedureRunnable(this, nonceGroup, nonce) {
|
||||||
@Override
|
@Override
|
||||||
protected void run() throws IOException {
|
protected void run() throws IOException {
|
||||||
getMaster().getMasterCoprocessorHost().preModifyTable(tableName, descriptor);
|
TableDescriptor oldDescriptor = getMaster().getTableDescriptors().get(tableName);
|
||||||
|
getMaster().getMasterCoprocessorHost()
|
||||||
|
.preModifyTable(tableName, oldDescriptor, newDescriptor);
|
||||||
|
|
||||||
LOG.info(getClientIdAuditPrefix() + " modify " + tableName);
|
LOG.info(getClientIdAuditPrefix() + " modify " + tableName);
|
||||||
|
|
||||||
|
@ -2380,11 +2382,12 @@ public class HMaster extends HRegionServer implements MasterServices {
|
||||||
// We need to wait for the procedure to potentially fail due to "prepare" sanity
|
// We need to wait for the procedure to potentially fail due to "prepare" sanity
|
||||||
// checks. This will block only the beginning of the procedure. See HBASE-19953.
|
// checks. This will block only the beginning of the procedure. See HBASE-19953.
|
||||||
ProcedurePrepareLatch latch = ProcedurePrepareLatch.createBlockingLatch();
|
ProcedurePrepareLatch latch = ProcedurePrepareLatch.createBlockingLatch();
|
||||||
submitProcedure(new ModifyTableProcedure(procedureExecutor.getEnvironment(),
|
submitProcedure(
|
||||||
descriptor, latch));
|
new ModifyTableProcedure(procedureExecutor.getEnvironment(), newDescriptor, latch));
|
||||||
latch.await();
|
latch.await();
|
||||||
|
|
||||||
getMaster().getMasterCoprocessorHost().postModifyTable(tableName, descriptor);
|
getMaster().getMasterCoprocessorHost()
|
||||||
|
.postModifyTable(tableName, oldDescriptor, newDescriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -2997,26 +3000,28 @@ public class HMaster extends HRegionServer implements MasterServices {
|
||||||
* <code>nonceGroup</code> (the source must ensure each operation gets a unique id).
|
* <code>nonceGroup</code> (the source must ensure each operation gets a unique id).
|
||||||
* @return procedure id
|
* @return procedure id
|
||||||
*/
|
*/
|
||||||
long modifyNamespace(final NamespaceDescriptor namespaceDescriptor, final long nonceGroup,
|
long modifyNamespace(final NamespaceDescriptor newNsDescriptor, final long nonceGroup,
|
||||||
final long nonce) throws IOException {
|
final long nonce) throws IOException {
|
||||||
checkInitialized();
|
checkInitialized();
|
||||||
|
|
||||||
TableName.isLegalNamespaceName(Bytes.toBytes(namespaceDescriptor.getName()));
|
TableName.isLegalNamespaceName(Bytes.toBytes(newNsDescriptor.getName()));
|
||||||
|
|
||||||
return MasterProcedureUtil.submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this,
|
return MasterProcedureUtil.submitProcedure(new MasterProcedureUtil.NonceProcedureRunnable(this,
|
||||||
nonceGroup, nonce) {
|
nonceGroup, nonce) {
|
||||||
@Override
|
@Override
|
||||||
protected void run() throws IOException {
|
protected void run() throws IOException {
|
||||||
getMaster().getMasterCoprocessorHost().preModifyNamespace(namespaceDescriptor);
|
NamespaceDescriptor oldNsDescriptor = getNamespace(newNsDescriptor.getName());
|
||||||
|
getMaster().getMasterCoprocessorHost().preModifyNamespace(oldNsDescriptor, newNsDescriptor);
|
||||||
// We need to wait for the procedure to potentially fail due to "prepare" sanity
|
// We need to wait for the procedure to potentially fail due to "prepare" sanity
|
||||||
// checks. This will block only the beginning of the procedure. See HBASE-19953.
|
// checks. This will block only the beginning of the procedure. See HBASE-19953.
|
||||||
ProcedurePrepareLatch latch = ProcedurePrepareLatch.createBlockingLatch();
|
ProcedurePrepareLatch latch = ProcedurePrepareLatch.createBlockingLatch();
|
||||||
LOG.info(getClientIdAuditPrefix() + " modify " + namespaceDescriptor);
|
LOG.info(getClientIdAuditPrefix() + " modify " + newNsDescriptor);
|
||||||
// Execute the operation synchronously - wait for the operation to complete before
|
// Execute the operation synchronously - wait for the operation to complete before
|
||||||
// continuing.
|
// continuing.
|
||||||
setProcId(getClusterSchema().modifyNamespace(namespaceDescriptor, getNonceKey(), latch));
|
setProcId(getClusterSchema().modifyNamespace(newNsDescriptor, getNonceKey(), latch));
|
||||||
latch.await();
|
latch.await();
|
||||||
getMaster().getMasterCoprocessorHost().postModifyNamespace(namespaceDescriptor);
|
getMaster().getMasterCoprocessorHost().postModifyNamespace(oldNsDescriptor,
|
||||||
|
newNsDescriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -254,20 +254,22 @@ public class MasterCoprocessorHost
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void preModifyNamespace(final NamespaceDescriptor ns) throws IOException {
|
public void preModifyNamespace(final NamespaceDescriptor currentNsDescriptor,
|
||||||
|
final NamespaceDescriptor newNsDescriptor) throws IOException {
|
||||||
execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
|
execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
|
||||||
@Override
|
@Override
|
||||||
public void call(MasterObserver observer) throws IOException {
|
public void call(MasterObserver observer) throws IOException {
|
||||||
observer.preModifyNamespace(this, ns);
|
observer.preModifyNamespace(this, currentNsDescriptor, newNsDescriptor);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void postModifyNamespace(final NamespaceDescriptor ns) throws IOException {
|
public void postModifyNamespace(final NamespaceDescriptor oldNsDescriptor,
|
||||||
|
final NamespaceDescriptor currentNsDescriptor) throws IOException {
|
||||||
execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
|
execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
|
||||||
@Override
|
@Override
|
||||||
public void call(MasterObserver observer) throws IOException {
|
public void call(MasterObserver observer) throws IOException {
|
||||||
observer.postModifyNamespace(this, ns);
|
observer.postModifyNamespace(this, oldNsDescriptor, currentNsDescriptor);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -429,42 +431,44 @@ public class MasterCoprocessorHost
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void preModifyTable(final TableName tableName, final TableDescriptor htd)
|
public void preModifyTable(final TableName tableName, final TableDescriptor currentDescriptor,
|
||||||
throws IOException {
|
final TableDescriptor newDescriptor) throws IOException {
|
||||||
execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
|
execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
|
||||||
@Override
|
@Override
|
||||||
public void call(MasterObserver observer) throws IOException {
|
public void call(MasterObserver observer) throws IOException {
|
||||||
observer.preModifyTable(this, tableName, htd);
|
observer.preModifyTable(this, tableName, currentDescriptor, newDescriptor);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void postModifyTable(final TableName tableName, final TableDescriptor htd)
|
public void postModifyTable(final TableName tableName, final TableDescriptor oldDescriptor,
|
||||||
throws IOException {
|
final TableDescriptor currentDescriptor) throws IOException {
|
||||||
execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
|
execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation() {
|
||||||
@Override
|
@Override
|
||||||
public void call(MasterObserver observer) throws IOException {
|
public void call(MasterObserver observer) throws IOException {
|
||||||
observer.postModifyTable(this, tableName, htd);
|
observer.postModifyTable(this, tableName, oldDescriptor, currentDescriptor);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void preModifyTableAction(final TableName tableName, final TableDescriptor htd,
|
public void preModifyTableAction(final TableName tableName,
|
||||||
final User user) throws IOException {
|
final TableDescriptor currentDescriptor, final TableDescriptor newDescriptor, final User user)
|
||||||
|
throws IOException {
|
||||||
execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation(user) {
|
execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation(user) {
|
||||||
@Override
|
@Override
|
||||||
public void call(MasterObserver observer) throws IOException {
|
public void call(MasterObserver observer) throws IOException {
|
||||||
observer.preModifyTableAction(this, tableName, htd);
|
observer.preModifyTableAction(this, tableName, currentDescriptor, newDescriptor);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void postCompletedModifyTableAction(final TableName tableName, final TableDescriptor htd,
|
public void postCompletedModifyTableAction(final TableName tableName,
|
||||||
final User user) throws IOException {
|
final TableDescriptor oldDescriptor, final TableDescriptor currentDescriptor, final User user)
|
||||||
|
throws IOException {
|
||||||
execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation(user) {
|
execOperation(coprocEnvironments.isEmpty() ? null : new MasterObserverOperation(user) {
|
||||||
@Override
|
@Override
|
||||||
public void call(MasterObserver observer) throws IOException {
|
public void call(MasterObserver observer) throws IOException {
|
||||||
observer.postCompletedModifyTableAction(this, tableName, htd);
|
observer.postCompletedModifyTableAction(this, tableName, oldDescriptor, currentDescriptor);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -420,10 +420,12 @@ public class ModifyTableProcedure
|
||||||
if (cpHost != null) {
|
if (cpHost != null) {
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case MODIFY_TABLE_PRE_OPERATION:
|
case MODIFY_TABLE_PRE_OPERATION:
|
||||||
cpHost.preModifyTableAction(getTableName(), modifiedTableDescriptor, getUser());
|
cpHost.preModifyTableAction(getTableName(), unmodifiedTableDescriptor,
|
||||||
|
modifiedTableDescriptor, getUser());
|
||||||
break;
|
break;
|
||||||
case MODIFY_TABLE_POST_OPERATION:
|
case MODIFY_TABLE_POST_OPERATION:
|
||||||
cpHost.postCompletedModifyTableAction(getTableName(), modifiedTableDescriptor,getUser());
|
cpHost.postCompletedModifyTableAction(getTableName(), unmodifiedTableDescriptor,
|
||||||
|
modifiedTableDescriptor,getUser());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new UnsupportedOperationException(this + " unhandled state=" + state);
|
throw new UnsupportedOperationException(this + " unhandled state=" + state);
|
||||||
|
|
Loading…
Reference in New Issue