Skip to content

Commit 4fd7fcd

Browse files
authored
HDDS-15320. Reduce duplication in OMAllocateBlockRequest OBS/FSO classes (apache#10327)
1 parent c13a0c0 commit 4fd7fcd

2 files changed

Lines changed: 68 additions & 177 deletions

File tree

hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/key/OMAllocateBlockRequest.java

Lines changed: 49 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import static org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes.KEY_UNDER_LEASE_RECOVERY;
2222
import static org.apache.hadoop.ozone.om.lock.OzoneManagerLock.LeveledResource.BUCKET_LOCK;
2323

24+
import jakarta.annotation.Nonnull;
2425
import java.io.IOException;
2526
import java.nio.file.InvalidPathException;
2627
import java.util.Collections;
@@ -147,7 +148,7 @@ public OMRequest preExecute(OzoneManager ozoneManager) throws IOException {
147148
}
148149

149150
@Override
150-
public OMClientResponse validateAndUpdateCache(OzoneManager ozoneManager, ExecutionContext context) {
151+
public final OMClientResponse validateAndUpdateCache(OzoneManager ozoneManager, ExecutionContext context) {
151152
final long trxnLogIndex = context.getIndex();
152153

153154
OzoneManagerProtocolProtos.AllocateBlockRequest allocateBlockRequest =
@@ -190,12 +191,15 @@ public OMClientResponse validateAndUpdateCache(OzoneManager ozoneManager, Execut
190191
bucketName);
191192

192193
// Here we don't acquire bucket/volume lock because for a single client
193-
// allocateBlock is called in serial fashion.
194+
// allocateBlock is called in serial fashion. With this approach, it
195+
// won't make 'fail-fast' during race condition case on delete/rename op,
196+
// assuming that later it will fail at the key commit operation.
194197

195-
openKeyName = omMetadataManager
196-
.getOpenKey(volumeName, bucketName, keyName, clientID);
198+
openKeyName =
199+
getOpenKeyName(volumeName, bucketName, keyName, clientID, omMetadataManager);
197200
openKeyInfo =
198-
omMetadataManager.getOpenKeyTable(getBucketLayout()).get(openKeyName);
201+
getOpenKeyInfo(omMetadataManager, openKeyName, keyName);
202+
199203
if (openKeyInfo == null) {
200204
throw new OMException("Open Key not found " + openKeyName,
201205
KEY_NOT_FOUND);
@@ -241,22 +245,20 @@ public OMClientResponse validateAndUpdateCache(OzoneManager ozoneManager, Execut
241245
.build();
242246

243247
// Add to cache.
244-
omMetadataManager.getOpenKeyTable(getBucketLayout()).addCacheEntry(
245-
new CacheKey<>(openKeyName),
246-
CacheValue.get(trxnLogIndex, openKeyInfo));
248+
addOpenTableCacheEntry(trxnLogIndex, omMetadataManager,
249+
openKeyName, keyName, openKeyInfo);
247250

248251
omResponse.setAllocateBlockResponse(AllocateBlockResponse.newBuilder()
249252
.setKeyLocation(blockLocation).build());
250-
omClientResponse = new OMAllocateBlockResponse(omResponse.build(),
251-
openKeyInfo, clientID, getBucketLayout());
253+
omClientResponse = getOmClientResponse(clientID, omResponse, openKeyInfo,
254+
omBucketInfo, omMetadataManager);
252255

253256
LOG.debug("Allocated block for Volume:{}, Bucket:{}, OpenKey:{}",
254257
volumeName, bucketName, openKeyName);
255258
} catch (IOException | InvalidPathException ex) {
256259
omMetrics.incNumBlockAllocateCallFails();
257260
exception = ex;
258-
omClientResponse = new OMAllocateBlockResponse(createErrorOMResponse(
259-
omResponse, exception), getBucketLayout());
261+
omClientResponse = getOmClientErrorResponse(omResponse, exception);
260262
LOG.error("Allocate Block failed. Volume:{}, Bucket:{}, OpenKey:{}. " +
261263
"Exception:{}", volumeName, bucketName, openKeyName, exception);
262264
} finally {
@@ -276,6 +278,41 @@ public OMClientResponse validateAndUpdateCache(OzoneManager ozoneManager, Execut
276278
return omClientResponse;
277279
}
278280

281+
protected OmKeyInfo getOpenKeyInfo(OMMetadataManager omMetadataManager,
282+
String openKeyName, String keyName) throws IOException {
283+
return omMetadataManager.getOpenKeyTable(getBucketLayout()).get(openKeyName);
284+
}
285+
286+
protected String getOpenKeyName(String volumeName, String bucketName,
287+
String keyName, long clientID, OMMetadataManager omMetadataManager)
288+
throws IOException {
289+
return omMetadataManager.getOpenKey(volumeName, bucketName, keyName, clientID);
290+
}
291+
292+
protected void addOpenTableCacheEntry(long trxnLogIndex,
293+
OMMetadataManager omMetadataManager, String openKeyName, String keyName,
294+
OmKeyInfo openKeyInfo) {
295+
omMetadataManager.getOpenKeyTable(getBucketLayout()).addCacheEntry(
296+
new CacheKey<>(openKeyName),
297+
CacheValue.get(trxnLogIndex, openKeyInfo));
298+
}
299+
300+
@Nonnull
301+
protected OMClientResponse getOmClientResponse(long clientID,
302+
OMResponse.Builder omResponse, OmKeyInfo openKeyInfo,
303+
OmBucketInfo omBucketInfo, OMMetadataManager omMetadataManager)
304+
throws IOException {
305+
return new OMAllocateBlockResponse(omResponse.build(),
306+
openKeyInfo, clientID, getBucketLayout());
307+
}
308+
309+
@Nonnull
310+
protected OMClientResponse getOmClientErrorResponse(
311+
OMResponse.Builder omResponse, Exception exception) {
312+
return new OMAllocateBlockResponse(createErrorOMResponse(
313+
omResponse, exception), getBucketLayout());
314+
}
315+
279316
@RequestFeatureValidator(
280317
conditions = ValidationCondition.CLUSTER_NEEDS_FINALIZATION,
281318
processingPhase = RequestProcessingPhase.PRE_PROCESS,

hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/request/key/OMAllocateBlockRequestWithFSO.java

Lines changed: 19 additions & 165 deletions
Original file line numberDiff line numberDiff line change
@@ -17,200 +17,42 @@
1717

1818
package org.apache.hadoop.ozone.om.request.key;
1919

20-
import static org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes.KEY_NOT_FOUND;
21-
import static org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes.KEY_UNDER_LEASE_RECOVERY;
22-
import static org.apache.hadoop.ozone.om.lock.OzoneManagerLock.LeveledResource.BUCKET_LOCK;
23-
2420
import jakarta.annotation.Nonnull;
2521
import java.io.IOException;
26-
import java.nio.file.InvalidPathException;
27-
import java.util.Collections;
28-
import java.util.List;
29-
import java.util.Map;
30-
import java.util.Objects;
31-
import org.apache.hadoop.hdds.client.ReplicationConfig;
32-
import org.apache.hadoop.ozone.OzoneConsts;
33-
import org.apache.hadoop.ozone.audit.AuditLogger;
34-
import org.apache.hadoop.ozone.audit.OMAction;
3522
import org.apache.hadoop.ozone.om.OMMetadataManager;
36-
import org.apache.hadoop.ozone.om.OMMetrics;
37-
import org.apache.hadoop.ozone.om.OzoneManager;
38-
import org.apache.hadoop.ozone.om.exceptions.OMException;
39-
import org.apache.hadoop.ozone.om.execution.flowcontrol.ExecutionContext;
4023
import org.apache.hadoop.ozone.om.helpers.BucketLayout;
4124
import org.apache.hadoop.ozone.om.helpers.OmBucketInfo;
4225
import org.apache.hadoop.ozone.om.helpers.OmFSOFile;
4326
import org.apache.hadoop.ozone.om.helpers.OmKeyInfo;
44-
import org.apache.hadoop.ozone.om.helpers.OmKeyLocationInfo;
4527
import org.apache.hadoop.ozone.om.helpers.OzoneFSUtils;
46-
import org.apache.hadoop.ozone.om.helpers.QuotaUtil;
4728
import org.apache.hadoop.ozone.om.request.file.OMFileRequest;
48-
import org.apache.hadoop.ozone.om.request.util.OmResponseUtil;
4929
import org.apache.hadoop.ozone.om.response.OMClientResponse;
5030
import org.apache.hadoop.ozone.om.response.key.OMAllocateBlockResponseWithFSO;
51-
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos;
52-
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.AllocateBlockRequest;
53-
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.AllocateBlockResponse;
54-
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.KeyArgs;
5531
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMRequest;
5632
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMResponse;
57-
import org.slf4j.Logger;
58-
import org.slf4j.LoggerFactory;
5933

6034
/**
6135
* Handles allocate block request - prefix layout.
6236
*/
6337
public class OMAllocateBlockRequestWithFSO extends OMAllocateBlockRequest {
6438

65-
private static final Logger LOG =
66-
LoggerFactory.getLogger(OMAllocateBlockRequestWithFSO.class);
67-
6839
public OMAllocateBlockRequestWithFSO(OMRequest omRequest,
6940
BucketLayout bucketLayout) {
7041
super(omRequest, bucketLayout);
7142
}
7243

7344
@Override
74-
public OMClientResponse validateAndUpdateCache(OzoneManager ozoneManager, ExecutionContext context) {
75-
final long trxnLogIndex = context.getIndex();
76-
77-
AllocateBlockRequest allocateBlockRequest =
78-
getOmRequest().getAllocateBlockRequest();
79-
80-
KeyArgs keyArgs =
81-
allocateBlockRequest.getKeyArgs();
82-
83-
OzoneManagerProtocolProtos.KeyLocation blockLocation =
84-
allocateBlockRequest.getKeyLocation();
85-
Objects.requireNonNull(blockLocation, "blockLocation == null");
86-
87-
String volumeName = keyArgs.getVolumeName();
88-
String bucketName = keyArgs.getBucketName();
89-
String keyName = keyArgs.getKeyName();
90-
long clientID = allocateBlockRequest.getClientID();
91-
92-
OMMetrics omMetrics = ozoneManager.getMetrics();
93-
omMetrics.incNumBlockAllocateCalls();
94-
95-
AuditLogger auditLogger = ozoneManager.getAuditLogger();
96-
97-
Map<String, String> auditMap = buildKeyArgsAuditMap(keyArgs);
98-
auditMap.put(OzoneConsts.CLIENT_ID, String.valueOf(clientID));
99-
100-
OMMetadataManager omMetadataManager = ozoneManager.getMetadataManager();
101-
String openKeyName = null;
102-
103-
OMResponse.Builder omResponse = OmResponseUtil.getOMResponseBuilder(
104-
getOmRequest());
105-
OMClientResponse omClientResponse = null;
106-
107-
OmKeyInfo openKeyInfo = null;
108-
Exception exception = null;
109-
OmBucketInfo omBucketInfo = null;
110-
boolean acquiredLock = false;
111-
112-
try {
113-
validateBucketAndVolume(omMetadataManager, volumeName,
114-
bucketName);
115-
116-
// Here we don't acquire bucket/volume lock because for a single client
117-
// allocateBlock is called in serial fashion. With this approach, it
118-
// won't make 'fail-fast' during race condition case on delete/rename op,
119-
// assuming that later it will fail at the key commit operation.
120-
openKeyName = getOpenKeyName(volumeName, bucketName, keyName, clientID,
121-
ozoneManager);
122-
openKeyInfo = getOpenKeyInfo(omMetadataManager, openKeyName, keyName);
123-
if (openKeyInfo == null) {
124-
throw new OMException("Open Key not found " + openKeyName,
125-
KEY_NOT_FOUND);
126-
}
127-
if (openKeyInfo.getMetadata().containsKey(OzoneConsts.LEASE_RECOVERY)) {
128-
throw new OMException("Open Key " + openKeyName + " is under lease recovery",
129-
KEY_UNDER_LEASE_RECOVERY);
130-
}
131-
if (openKeyInfo.getMetadata().containsKey(OzoneConsts.DELETED_HSYNC_KEY) ||
132-
openKeyInfo.getMetadata().containsKey(OzoneConsts.OVERWRITTEN_HSYNC_KEY)) {
133-
throw new OMException("Open Key " + openKeyName + " is already deleted/overwritten",
134-
KEY_NOT_FOUND);
135-
}
136-
List<OmKeyLocationInfo> newLocationList = Collections.singletonList(
137-
OmKeyLocationInfo.getFromProtobuf(blockLocation));
138-
139-
mergeOmLockDetails(
140-
omMetadataManager.getLock().acquireWriteLock(BUCKET_LOCK,
141-
volumeName, bucketName));
142-
acquiredLock = getOmLockDetails().isLockAcquired();
143-
omBucketInfo = getBucketInfo(omMetadataManager, volumeName, bucketName);
144-
// check bucket and volume quota
145-
long preAllocatedKeySize = newLocationList.size()
146-
* ozoneManager.getScmBlockSize();
147-
long hadAllocatedKeySize =
148-
openKeyInfo.getLatestVersionLocations().getLocationList().size()
149-
* ozoneManager.getScmBlockSize();
150-
ReplicationConfig repConfig = openKeyInfo.getReplicationConfig();
151-
long totalAllocatedSpace = QuotaUtil.getReplicatedSize(
152-
preAllocatedKeySize, repConfig) + QuotaUtil.getReplicatedSize(
153-
hadAllocatedKeySize, repConfig);
154-
checkBucketQuotaInBytes(omMetadataManager, omBucketInfo,
155-
totalAllocatedSpace);
156-
// Append new block
157-
openKeyInfo.appendNewBlocks(newLocationList, false);
158-
159-
// Set modification time.
160-
openKeyInfo.setModificationTime(keyArgs.getModificationTime());
161-
162-
// Set the UpdateID to current transactionLogIndex
163-
openKeyInfo = openKeyInfo.toBuilder()
164-
.setUpdateID(trxnLogIndex)
165-
.build();
166-
167-
// Add to cache.
168-
addOpenTableCacheEntry(trxnLogIndex, omMetadataManager, openKeyName, keyName,
169-
openKeyInfo);
170-
171-
omResponse.setAllocateBlockResponse(AllocateBlockResponse.newBuilder()
172-
.setKeyLocation(blockLocation).build());
173-
long volumeId = omMetadataManager.getVolumeId(volumeName);
174-
omClientResponse = getOmClientResponse(clientID, omResponse,
175-
openKeyInfo, omBucketInfo.copyObject(), volumeId);
176-
LOG.debug("Allocated block for Volume:{}, Bucket:{}, OpenKey:{}",
177-
volumeName, bucketName, openKeyName);
178-
} catch (IOException | InvalidPathException ex) {
179-
omMetrics.incNumBlockAllocateCallFails();
180-
exception = ex;
181-
omClientResponse = new OMAllocateBlockResponseWithFSO(
182-
createErrorOMResponse(omResponse, exception), getBucketLayout());
183-
LOG.error("Allocate Block failed. Volume:{}, Bucket:{}, OpenKey:{}. " +
184-
"Exception:{}", volumeName, bucketName, openKeyName, exception);
185-
} finally {
186-
if (acquiredLock) {
187-
mergeOmLockDetails(
188-
omMetadataManager.getLock().releaseWriteLock(
189-
BUCKET_LOCK, volumeName, bucketName));
190-
}
191-
if (omClientResponse != null) {
192-
omClientResponse.setOmLockDetails(getOmLockDetails());
193-
}
194-
}
195-
196-
markForAudit(auditLogger, buildAuditMessage(OMAction.ALLOCATE_BLOCK, auditMap,
197-
exception, getOmRequest().getUserInfo()));
198-
199-
return omClientResponse;
200-
}
201-
202-
private OmKeyInfo getOpenKeyInfo(OMMetadataManager omMetadataManager,
45+
protected OmKeyInfo getOpenKeyInfo(OMMetadataManager omMetadataManager,
20346
String openKeyName, String keyName) throws IOException {
20447
String fileName = OzoneFSUtils.getFileName(keyName);
20548
return OMFileRequest.getOmKeyInfoFromFileTable(true,
20649
omMetadataManager, openKeyName, fileName);
20750
}
20851

209-
private String getOpenKeyName(String volumeName, String bucketName,
210-
String keyName, long clientID, OzoneManager ozoneManager)
52+
@Override
53+
protected String getOpenKeyName(String volumeName, String bucketName,
54+
String keyName, long clientID, OMMetadataManager omMetadataManager)
21155
throws IOException {
212-
OMMetadataManager omMetadataManager = ozoneManager.getMetadataManager();
213-
21456
return new OmFSOFile.Builder()
21557
.setVolumeName(volumeName)
21658
.setBucketName(bucketName)
@@ -219,18 +61,30 @@ private String getOpenKeyName(String volumeName, String bucketName,
21961
.build().getOpenFileName(clientID);
22062
}
22163

222-
private void addOpenTableCacheEntry(long trxnLogIndex,
64+
@Override
65+
protected void addOpenTableCacheEntry(long trxnLogIndex,
22366
OMMetadataManager omMetadataManager, String openKeyName, String keyName,
22467
OmKeyInfo openKeyInfo) {
22568
OMFileRequest.addOpenFileTableCacheEntry(omMetadataManager, openKeyName,
22669
openKeyInfo, keyName, trxnLogIndex);
22770
}
22871

72+
@Override
22973
@Nonnull
230-
private OMClientResponse getOmClientResponse(long clientID,
74+
protected OMClientResponse getOmClientResponse(long clientID,
23175
OMResponse.Builder omResponse, OmKeyInfo openKeyInfo,
232-
OmBucketInfo omBucketInfo, long volumeId) {
76+
OmBucketInfo omBucketInfo, OMMetadataManager omMetadataManager)
77+
throws IOException {
78+
long volumeId = omMetadataManager.getVolumeId(openKeyInfo.getVolumeName());
23379
return new OMAllocateBlockResponseWithFSO(omResponse.build(), openKeyInfo,
23480
clientID, getBucketLayout(), volumeId, omBucketInfo.getObjectID());
23581
}
82+
83+
@Override
84+
@Nonnull
85+
protected OMClientResponse getOmClientErrorResponse(
86+
OMResponse.Builder omResponse, Exception exception) {
87+
return new OMAllocateBlockResponseWithFSO(
88+
createErrorOMResponse(omResponse, exception), getBucketLayout());
89+
}
23690
}

0 commit comments

Comments
 (0)