2020package org .apache .iotdb .confignode .procedure .impl .sync ;
2121
2222import org .apache .iotdb .common .rpc .thrift .TDataNodeConfiguration ;
23+ import org .apache .iotdb .common .rpc .thrift .TDataNodeLocation ;
2324import org .apache .iotdb .common .rpc .thrift .TSStatus ;
2425import org .apache .iotdb .commons .conf .CommonConfig ;
2526import org .apache .iotdb .commons .conf .CommonDescriptor ;
2627import org .apache .iotdb .commons .exception .IoTDBException ;
2728import org .apache .iotdb .commons .utils .ThriftCommonsSerDeUtils ;
28- import org .apache .iotdb .confignode .client .sync .CnToDnSyncRequestType ;
29- import org .apache .iotdb .confignode .client .sync .SyncDataNodeClientPool ;
29+ import org .apache .iotdb .confignode .client .async .CnToDnAsyncRequestType ;
30+ import org .apache .iotdb .confignode .client .async .CnToDnInternalServiceAsyncRequestManager ;
31+ import org .apache .iotdb .confignode .client .async .handlers .DataNodeAsyncRequestContext ;
3032import org .apache .iotdb .confignode .consensus .request .ConfigPhysicalPlan ;
3133import org .apache .iotdb .confignode .consensus .request .ConfigPhysicalPlanType ;
3234import org .apache .iotdb .confignode .consensus .request .write .auth .AuthorPlan ;
3335import org .apache .iotdb .confignode .consensus .request .write .pipe .payload .PipeEnrichedPlan ;
3436import org .apache .iotdb .confignode .i18n .ProcedureMessages ;
37+ import org .apache .iotdb .confignode .manager .lease .ClusterCachePropagator ;
3538import org .apache .iotdb .confignode .procedure .env .ConfigNodeProcedureEnv ;
3639import org .apache .iotdb .confignode .procedure .exception .ProcedureException ;
3740import org .apache .iotdb .confignode .procedure .impl .node .AbstractNodeProcedure ;
41+ import org .apache .iotdb .confignode .procedure .impl .schema .SchemaUtils ;
3842import org .apache .iotdb .confignode .procedure .state .auth .AuthOperationProcedureState ;
3943import org .apache .iotdb .confignode .procedure .store .ProcedureType ;
4044import org .apache .iotdb .consensus .exception .ConsensusException ;
5054import java .io .IOException ;
5155import java .nio .ByteBuffer ;
5256import java .util .ArrayList ;
53- import java .util .Iterator ;
5457import java .util .List ;
58+ import java .util .Map ;
5559import java .util .Objects ;
5660
5761import static org .apache .iotdb .confignode .procedure .state .auth .AuthOperationProcedureState .DATANODE_AUTHCACHE_INVALIDING ;
@@ -68,7 +72,6 @@ public class AuthOperationProcedure extends AbstractNodeProcedure<AuthOperationP
6872 private static final String CONSENSUS_WRITE_ERROR =
6973 ProcedureMessages .FAILED_IN_THE_WRITE_API_EXECUTING_THE_CONSENSUS_LAYER_DUE ;
7074
71- private static final int RETRY_THRESHOLD = 2 ;
7275 private static final CommonConfig commonConfig = CommonDescriptor .getInstance ().getConfig ();
7376
7477 private final List <Pair <TDataNodeConfiguration , Long >> dataNodesToInvalid = new ArrayList <>();
@@ -97,54 +100,40 @@ protected Flow executeFromState(ConfigNodeProcedureEnv env, AuthOperationProcedu
97100 writePlan (env );
98101 return Flow .HAS_MORE_STATE ;
99102 case DATANODE_AUTHCACHE_INVALIDING :
100- TInvalidatePermissionCacheReq req = new TInvalidatePermissionCacheReq ();
101- TSStatus status ;
102- req .setUsername (user );
103- req .setRoleName (role );
103+ TInvalidatePermissionCacheReq req = new TInvalidatePermissionCacheReq (user , role );
104104 if (plan .getAuthorType () == ConfigPhysicalPlanType .AccountUnlock
105105 || plan .getAuthorType () == ConfigPhysicalPlanType .RAccountUnlock ) {
106106 // For account unlock, role carries the optional login address.
107107 req .setNeedDisconnect (true );
108108 }
109- Iterator <Pair <TDataNodeConfiguration , Long >> it = dataNodesToInvalid .iterator ();
110- while (it .hasNext ()) {
111- Pair <TDataNodeConfiguration , Long > pair = it .next ();
112- if (pair .getRight () + this .timeoutMS < System .currentTimeMillis ()) {
113- it .remove ();
114- continue ;
115- }
116- status =
117- (TSStatus )
118- SyncDataNodeClientPool .getInstance ()
119- .sendSyncRequestToDataNodeWithRetry (
120- pair .getLeft ().getLocation ().getInternalEndPoint (),
121- req ,
122- CnToDnSyncRequestType .INVALIDATE_PERMISSION_CACHE );
123- if (status .getCode () == TSStatusCode .SUCCESS_STATUS .getStatusCode ()) {
124- it .remove ();
125- }
126- }
127- if (dataNodesToInvalid .isEmpty ()) {
109+ final boolean proceeded =
110+ new ClusterCachePropagator (SchemaUtils .filterFencedDataNode (env .getConfigManager ()))
111+ .propagate (targets -> broadcastAuthorityCache (req , targets ));
112+
113+ if (proceeded ) {
128114 LOGGER .info (ProcedureMessages .AUTH_PROCEDURE_CLEAN_DATANODE_CACHE_SUCCESSFULLY );
129115 return Flow .NO_MORE_STATE ;
130- } else {
131- setNextState (AuthOperationProcedureState .DATANODE_AUTHCACHE_INVALIDING );
132116 }
133- break ;
117+ LOGGER .warn (ProcedureMessages .AUTH_PROCEDURE_CACHE_INVALIDATION_FAILED );
118+ setFailure (
119+ new ProcedureException (
120+ new IoTDBException (
121+ ProcedureMessages .AUTH_PROCEDURE_CACHE_INVALIDATION_FAILED ,
122+ TSStatusCode .AUTH_OPERATE_EXCEPTION .getStatusCode ())));
123+ return Flow .NO_MORE_STATE ;
134124 }
135125 } catch (Exception e ) {
136126 if (isRollbackSupported (state )) {
137127 LOGGER .error (ProcedureMessages .FAIL_WHEN_EXECUTE , plan );
138128 setFailure (new ProcedureException (e ));
139129 } else {
140- LOGGER .error (
141- ProcedureMessages .RETRIEVABLE_ERROR_TRYING_TO_EXECUTE_PLAN_STATE , plan , state , e );
142- if (getCycles () > RETRY_THRESHOLD ) {
143- setFailure (
144- new ProcedureException (
145- String .format (
146- ProcedureMessages .FAIL_TO_EXECUTE_PLAN_AT_STATE , plan .toString (), state )));
147- }
130+ LOGGER .warn (ProcedureMessages .AUTH_PROCEDURE_CACHE_INVALIDATION_FAILED , e );
131+ setFailure (
132+ new ProcedureException (
133+ new IoTDBException (
134+ ProcedureMessages .AUTH_PROCEDURE_CACHE_INVALIDATION_FAILED ,
135+ e ,
136+ TSStatusCode .AUTH_OPERATE_EXCEPTION .getStatusCode ())));
148137 }
149138 }
150139 return Flow .HAS_MORE_STATE ;
@@ -164,19 +153,26 @@ private void writePlan(ConfigNodeProcedureEnv env) {
164153 }
165154 if (res .code == TSStatusCode .SUCCESS_STATUS .getStatusCode ()) {
166155 setNextState (DATANODE_AUTHCACHE_INVALIDING );
167- for (TDataNodeConfiguration item : datanodes ) {
168- this .dataNodesToInvalid .add (new Pair <>(item , System .currentTimeMillis ()));
169- }
170- LOGGER .info (
171- ProcedureMessages .EXECUTE_AUTH_PLAN_SUCCESS_TO_INVALIDATE_DATANODES ,
172- plan ,
173- dataNodesToInvalid );
156+ LOGGER .info (ProcedureMessages .EXECUTE_AUTH_PLAN_SUCCESS_TO_INVALIDATE_DATANODES , plan );
174157 } else {
175158 LOGGER .info (ProcedureMessages .FAILED_TO_EXECUTE_PLAN_BECAUSE , plan , res .message );
176159 setFailure (new ProcedureException (new IoTDBException (res )));
177160 }
178161 }
179162
163+ private static Map <Integer , TSStatus > broadcastAuthorityCache (
164+ final TInvalidatePermissionCacheReq req , final Map <Integer , TDataNodeLocation > targets ) {
165+ final DataNodeAsyncRequestContext <TInvalidatePermissionCacheReq , TSStatus > clientHandler =
166+ new DataNodeAsyncRequestContext <>(
167+ CnToDnAsyncRequestType .INVALIDATE_PERMISSION_CACHE , req , targets );
168+ CnToDnInternalServiceAsyncRequestManager .getInstance ()
169+ .sendAsyncRequest (
170+ clientHandler ,
171+ ClusterCachePropagator .BROADCAST_RPC_RETRY ,
172+ ClusterCachePropagator .BROADCAST_RPC_TIMEOUT_MS );
173+ return clientHandler .getResponseMap ();
174+ }
175+
180176 @ Override
181177 protected boolean isRollbackSupported (AuthOperationProcedureState state ) {
182178 return state == AuthOperationProcedureState .INIT ;
0 commit comments