HDDS-1974. Implement OM CancelDelegationToken request to use Cache and DoubleBuffer. (#1308)
This commit is contained in:
parent
3bba8086e0
commit
b83eae7bdb
@ -287,6 +287,10 @@ public OzoneTokenIdentifier cancelToken(Token<OzoneTokenIdentifier> token,
|
|||||||
throw new AccessControlException(canceller
|
throw new AccessControlException(canceller
|
||||||
+ " is not authorized to cancel the token " + formatTokenId(id));
|
+ " is not authorized to cancel the token " + formatTokenId(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For HA ratis will take care of removal.
|
||||||
|
// This check will be removed, when HA/Non-HA code is merged.
|
||||||
|
if (!isRatisEnabled) {
|
||||||
try {
|
try {
|
||||||
store.removeToken(id);
|
store.removeToken(id);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
@ -296,9 +300,27 @@ public OzoneTokenIdentifier cancelToken(Token<OzoneTokenIdentifier> token,
|
|||||||
if (info == null) {
|
if (info == null) {
|
||||||
throw new InvalidToken("Token not found " + formatTokenId(id));
|
throw new InvalidToken("Token not found " + formatTokenId(id));
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// Check whether token is there in-memory map of tokens or not on the
|
||||||
|
// OM leader.
|
||||||
|
TokenInfo info = currentTokens.get(id);
|
||||||
|
if (info == null) {
|
||||||
|
throw new InvalidToken("Token not found in-memory map of tokens" +
|
||||||
|
formatTokenId(id));
|
||||||
|
}
|
||||||
|
}
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the expired token from in-memory map.
|
||||||
|
* @param ozoneTokenIdentifier
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public void removeToken(OzoneTokenIdentifier ozoneTokenIdentifier) {
|
||||||
|
currentTokens.remove(ozoneTokenIdentifier);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte[] retrievePassword(OzoneTokenIdentifier identifier)
|
public byte[] retrievePassword(OzoneTokenIdentifier identifier)
|
||||||
throws InvalidToken {
|
throws InvalidToken {
|
||||||
|
@ -152,6 +152,7 @@ public OMClientResponse validateAndUpdateCache(OzoneManager ozoneManager,
|
|||||||
throw new OMException("Volume doesn't exist",
|
throw new OMException("Volume doesn't exist",
|
||||||
OMException.ResultCodes.VOLUME_NOT_FOUND);
|
OMException.ResultCodes.VOLUME_NOT_FOUND);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Check if bucket already exists
|
//Check if bucket already exists
|
||||||
if (metadataManager.getBucketTable().get(bucketKey) != null) {
|
if (metadataManager.getBucketTable().get(bucketKey) != null) {
|
||||||
LOG.debug("bucket: {} already exists ", bucketName);
|
LOG.debug("bucket: {} already exists ", bucketName);
|
||||||
|
@ -0,0 +1,125 @@
|
|||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
* <p>
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* <p>
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.apache.hadoop.ozone.om.request.security;
|
||||||
|
|
||||||
|
import com.google.common.base.Optional;
|
||||||
|
import org.apache.hadoop.ozone.om.OMMetadataManager;
|
||||||
|
import org.apache.hadoop.ozone.om.OzoneManager;
|
||||||
|
import org.apache.hadoop.ozone.om.ratis.utils.OzoneManagerDoubleBufferHelper;
|
||||||
|
import org.apache.hadoop.ozone.om.request.OMClientRequest;
|
||||||
|
import org.apache.hadoop.ozone.om.response.OMClientResponse;
|
||||||
|
import org.apache.hadoop.ozone.om.response.security.OMCancelDelegationTokenResponse;
|
||||||
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos;
|
||||||
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMRequest;
|
||||||
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMResponse;
|
||||||
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.CancelDelegationTokenResponseProto;
|
||||||
|
import org.apache.hadoop.ozone.protocolPB.OMPBHelper;
|
||||||
|
import org.apache.hadoop.ozone.security.OzoneTokenIdentifier;
|
||||||
|
import org.apache.hadoop.security.proto.SecurityProtos;
|
||||||
|
import org.apache.hadoop.security.proto.SecurityProtos.CancelDelegationTokenRequestProto;
|
||||||
|
import org.apache.hadoop.security.token.Token;
|
||||||
|
import org.apache.hadoop.utils.db.cache.CacheKey;
|
||||||
|
import org.apache.hadoop.utils.db.cache.CacheValue;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle CancelDelegationToken Request.
|
||||||
|
*/
|
||||||
|
public class OMCancelDelegationTokenRequest extends OMClientRequest {
|
||||||
|
|
||||||
|
private static final Logger LOG =
|
||||||
|
LoggerFactory.getLogger(OMGetDelegationTokenRequest.class);
|
||||||
|
|
||||||
|
public OMCancelDelegationTokenRequest(OMRequest omRequest) {
|
||||||
|
super(omRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OMRequest preExecute(OzoneManager ozoneManager) throws IOException {
|
||||||
|
|
||||||
|
// Call OM to cancel token, this does check whether we can cancel token
|
||||||
|
// or not. This does not remove token from DB/in-memory.
|
||||||
|
ozoneManager.cancelDelegationToken(getToken());
|
||||||
|
|
||||||
|
return super.preExecute(ozoneManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OMClientResponse validateAndUpdateCache(OzoneManager ozoneManager,
|
||||||
|
long transactionLogIndex,
|
||||||
|
OzoneManagerDoubleBufferHelper ozoneManagerDoubleBufferHelper) {
|
||||||
|
|
||||||
|
OMMetadataManager omMetadataManager = ozoneManager.getMetadataManager();
|
||||||
|
|
||||||
|
OMClientResponse omClientResponse = null;
|
||||||
|
OMResponse.Builder omResponse =
|
||||||
|
OMResponse.newBuilder()
|
||||||
|
.setCmdType(OzoneManagerProtocolProtos.Type.CancelDelegationToken)
|
||||||
|
.setStatus(OzoneManagerProtocolProtos.Status.OK)
|
||||||
|
.setSuccess(true);
|
||||||
|
OzoneTokenIdentifier ozoneTokenIdentifier = null;
|
||||||
|
try {
|
||||||
|
ozoneTokenIdentifier =
|
||||||
|
OzoneTokenIdentifier.readProtoBuf(getToken().getIdentifier());
|
||||||
|
|
||||||
|
// Remove token from in-memory.
|
||||||
|
ozoneManager.getDelegationTokenMgr().removeToken(ozoneTokenIdentifier);
|
||||||
|
|
||||||
|
// Update Cache.
|
||||||
|
omMetadataManager.getDelegationTokenTable().addCacheEntry(
|
||||||
|
new CacheKey<>(ozoneTokenIdentifier),
|
||||||
|
new CacheValue<>(Optional.absent(), transactionLogIndex));
|
||||||
|
|
||||||
|
omClientResponse =
|
||||||
|
new OMCancelDelegationTokenResponse(ozoneTokenIdentifier,
|
||||||
|
omResponse.setCancelDelegationTokenResponse(
|
||||||
|
CancelDelegationTokenResponseProto.newBuilder().setResponse(
|
||||||
|
SecurityProtos.CancelDelegationTokenResponseProto
|
||||||
|
.newBuilder())).build());
|
||||||
|
} catch (IOException ex) {
|
||||||
|
LOG.error("Error in cancel DelegationToken {}", ozoneTokenIdentifier, ex);
|
||||||
|
omClientResponse = new OMCancelDelegationTokenResponse(null,
|
||||||
|
createErrorOMResponse(omResponse, ex));
|
||||||
|
} finally {
|
||||||
|
if (omClientResponse != null) {
|
||||||
|
omClientResponse.setFlushFuture(
|
||||||
|
ozoneManagerDoubleBufferHelper.add(omClientResponse,
|
||||||
|
transactionLogIndex));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LOG.isDebugEnabled()) {
|
||||||
|
LOG.debug("Cancelled delegation token: {}", ozoneTokenIdentifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
return omClientResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Token<OzoneTokenIdentifier> getToken() {
|
||||||
|
CancelDelegationTokenRequestProto cancelDelegationTokenRequest =
|
||||||
|
getOmRequest().getCancelDelegationTokenRequest();
|
||||||
|
|
||||||
|
return OMPBHelper.convertToDelegationToken(
|
||||||
|
cancelDelegationTokenRequest.getToken());
|
||||||
|
}
|
||||||
|
}
|
@ -25,7 +25,7 @@
|
|||||||
import org.apache.hadoop.ozone.om.ratis.utils.OzoneManagerDoubleBufferHelper;
|
import org.apache.hadoop.ozone.om.ratis.utils.OzoneManagerDoubleBufferHelper;
|
||||||
import org.apache.hadoop.ozone.om.request.OMClientRequest;
|
import org.apache.hadoop.ozone.om.request.OMClientRequest;
|
||||||
import org.apache.hadoop.ozone.om.response.OMClientResponse;
|
import org.apache.hadoop.ozone.om.response.OMClientResponse;
|
||||||
import org.apache.hadoop.ozone.om.response.security.OMDelegationTokenResponse;
|
import org.apache.hadoop.ozone.om.response.security.OMGetDelegationTokenResponse;
|
||||||
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos;
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos;
|
||||||
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.GetDelegationTokenResponseProto;
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.GetDelegationTokenResponseProto;
|
||||||
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMRequest;
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMRequest;
|
||||||
@ -65,13 +65,13 @@ public OMRequest preExecute(OzoneManager ozoneManager) throws IOException {
|
|||||||
.getDelegationToken(new Text(getDelegationTokenRequest.getRenewer()));
|
.getDelegationToken(new Text(getDelegationTokenRequest.getRenewer()));
|
||||||
|
|
||||||
|
|
||||||
// Client issues GetDelegationToken request, when received by OM leader will
|
// Client issues GetDelegationToken request, when received by OM leader
|
||||||
// it generate Token. Original GetDelegationToken request is converted to
|
// it will generate a token. Original GetDelegationToken request is
|
||||||
// UpdateGetDelegationToken request with the generated token information.
|
// converted to UpdateGetDelegationToken request with the generated token
|
||||||
// This updated request will be submitted to Ratis. In this way delegation
|
// information. This updated request will be submitted to Ratis. In this
|
||||||
// token created by leader, will be replicated across all OMs.
|
// way delegation token created by leader, will be replicated across all
|
||||||
// And also original GetDelegationToken request from client does not need
|
// OMs. With this approach, original GetDelegationToken request from
|
||||||
// any proto changes.
|
// client does not need any proto changes.
|
||||||
|
|
||||||
// Create UpdateGetDelegationTokenRequest with token response.
|
// Create UpdateGetDelegationTokenRequest with token response.
|
||||||
OMRequest.Builder omRequest = OMRequest.newBuilder()
|
OMRequest.Builder omRequest = OMRequest.newBuilder()
|
||||||
@ -129,14 +129,14 @@ public OMClientResponse validateAndUpdateCache(OzoneManager ozoneManager,
|
|||||||
new CacheValue<>(Optional.of(renewTime), transactionLogIndex));
|
new CacheValue<>(Optional.of(renewTime), transactionLogIndex));
|
||||||
|
|
||||||
omClientResponse =
|
omClientResponse =
|
||||||
new OMDelegationTokenResponse(ozoneTokenIdentifier, renewTime,
|
new OMGetDelegationTokenResponse(ozoneTokenIdentifier, renewTime,
|
||||||
omResponse.setGetDelegationTokenResponse(
|
omResponse.setGetDelegationTokenResponse(
|
||||||
updateGetDelegationTokenRequest
|
updateGetDelegationTokenRequest
|
||||||
.getGetDelegationTokenResponse()).build());
|
.getGetDelegationTokenResponse()).build());
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
LOG.error("Error in Updating DelegationToken {} to DB",
|
LOG.error("Error in Updating DelegationToken {}",
|
||||||
ozoneTokenIdentifierToken, ex);
|
ozoneTokenIdentifierToken, ex);
|
||||||
omClientResponse = new OMDelegationTokenResponse(null, -1L,
|
omClientResponse = new OMGetDelegationTokenResponse(null, -1L,
|
||||||
createErrorOMResponse(omResponse, ex));
|
createErrorOMResponse(omResponse, ex));
|
||||||
} finally {
|
} finally {
|
||||||
if (omClientResponse != null) {
|
if (omClientResponse != null) {
|
||||||
@ -147,7 +147,7 @@ public OMClientResponse validateAndUpdateCache(OzoneManager ozoneManager,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (LOG.isDebugEnabled()) {
|
if (LOG.isDebugEnabled()) {
|
||||||
LOG.debug("Updated delegation token to OM DB: {}",
|
LOG.debug("Updated delegation token in-memory map: {}",
|
||||||
ozoneTokenIdentifierToken);
|
ozoneTokenIdentifierToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,30 +24,32 @@
|
|||||||
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMResponse;
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMResponse;
|
||||||
import org.apache.hadoop.ozone.security.OzoneTokenIdentifier;
|
import org.apache.hadoop.ozone.security.OzoneTokenIdentifier;
|
||||||
import org.apache.hadoop.utils.db.BatchOperation;
|
import org.apache.hadoop.utils.db.BatchOperation;
|
||||||
|
import org.apache.hadoop.utils.db.Table;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle response for DelegationToken request.
|
* Handle response for CancelDelegationToken request.
|
||||||
*/
|
*/
|
||||||
public class OMDelegationTokenResponse extends OMClientResponse {
|
public class OMCancelDelegationTokenResponse extends OMClientResponse {
|
||||||
|
|
||||||
private OzoneTokenIdentifier ozoneTokenIdentifier;
|
private OzoneTokenIdentifier ozoneTokenIdentifier;
|
||||||
private long renewTime;
|
|
||||||
public OMDelegationTokenResponse(OzoneTokenIdentifier ozoneTokenIdentifier,
|
public OMCancelDelegationTokenResponse(
|
||||||
long renewTime, OMResponse omResponse) {
|
@Nullable OzoneTokenIdentifier ozoneTokenIdentifier,
|
||||||
|
@Nonnull OMResponse omResponse) {
|
||||||
super(omResponse);
|
super(omResponse);
|
||||||
this.ozoneTokenIdentifier = ozoneTokenIdentifier;
|
this.ozoneTokenIdentifier = ozoneTokenIdentifier;
|
||||||
this.renewTime = renewTime;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addToDBBatch(OMMetadataManager omMetadataManager,
|
public void addToDBBatch(OMMetadataManager omMetadataManager,
|
||||||
BatchOperation batchOperation) throws IOException {
|
BatchOperation batchOperation) throws IOException {
|
||||||
|
Table table = omMetadataManager.getDelegationTokenTable();
|
||||||
if (getOMResponse().getStatus() == OzoneManagerProtocolProtos.Status.OK) {
|
if (getOMResponse().getStatus() == OzoneManagerProtocolProtos.Status.OK) {
|
||||||
omMetadataManager.getDelegationTokenTable().putWithBatch(batchOperation,
|
table.deleteWithBatch(batchOperation, ozoneTokenIdentifier);
|
||||||
ozoneTokenIdentifier, renewTime);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -0,0 +1,58 @@
|
|||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
* <p>
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* <p>
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.apache.hadoop.ozone.om.response.security;
|
||||||
|
|
||||||
|
import org.apache.hadoop.ozone.om.OMMetadataManager;
|
||||||
|
import org.apache.hadoop.ozone.om.response.OMClientResponse;
|
||||||
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos;
|
||||||
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMResponse;
|
||||||
|
import org.apache.hadoop.ozone.security.OzoneTokenIdentifier;
|
||||||
|
import org.apache.hadoop.utils.db.BatchOperation;
|
||||||
|
import org.apache.hadoop.utils.db.Table;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle response for GetDelegationToken request.
|
||||||
|
*/
|
||||||
|
public class OMGetDelegationTokenResponse extends OMClientResponse {
|
||||||
|
|
||||||
|
private OzoneTokenIdentifier ozoneTokenIdentifier;
|
||||||
|
private long renewTime = -1L;
|
||||||
|
|
||||||
|
public OMGetDelegationTokenResponse(
|
||||||
|
@Nullable OzoneTokenIdentifier ozoneTokenIdentifier,
|
||||||
|
long renewTime, @Nonnull OMResponse omResponse) {
|
||||||
|
super(omResponse);
|
||||||
|
this.ozoneTokenIdentifier = ozoneTokenIdentifier;
|
||||||
|
this.renewTime = renewTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addToDBBatch(OMMetadataManager omMetadataManager,
|
||||||
|
BatchOperation batchOperation) throws IOException {
|
||||||
|
Table table = omMetadataManager.getDelegationTokenTable();
|
||||||
|
if (getOMResponse().getStatus() == OzoneManagerProtocolProtos.Status.OK) {
|
||||||
|
table.putWithBatch(batchOperation, ozoneTokenIdentifier, renewTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user