Source:
<code>private void handleBody(InputStream payload, MessageMetadata messageMetadata, MessageInfo messageInfo) throws IOException, MessageFormatException { ByteBuffer encryptionKey = messageMetadata == null ? null : messageMetadata.getEncryptionKey(); serverBlobProperties = MessageFormatRecord.deserializeBlobProperties(payload); updateTtlIfRequired(serverBlobProperties, messageInfo); ByteBuffer userMetadata = MessageFormatRecord.deserializeUserMetadata(payload); if (encryptionKey == null) { <START> BlobInfo blobInfo = new BlobInfo(serverBlobProperties, userMetadata.array()); <END> blobInfo.setLifeVersion(messageInfo.getLifeVersion()); operationResult = new GetBlobResultInternal(new GetBlobResult(blobInfo, null), null); } else { progressTracker.initializeCryptoJobTracker(CryptoJobType.DECRYPTION); logger.trace("Submitting decrypt job for {}", blobId); decryptJobMetricsTracker.onJobSubmission(); long startTimeMs = System.currentTimeMillis(); cryptoJobHandler.submitJob( new DecryptJob(blobId, encryptionKey.duplicate(), null, userMetadata, cryptoService, kms, decryptJobMetricsTracker, (DecryptJob.DecryptJobResult result, Exception exception) -> { decryptJobMetricsTracker.onJobResultProcessingStart(); logger.trace("Handling decrypt job callback results for {}", blobId); routerMetrics.decryptTimeMs.update(System.currentTimeMillis() - startTimeMs); if (exception == null) { logger.trace("Successfully updating decrypt job callback results for {}", blobId); BlobInfo blobInfo = new BlobInfo(serverBlobProperties, result.getDecryptedUserMetadata().array()); blobInfo.setLifeVersion(messageInfo.getLifeVersion()); operationResult = new GetBlobResultInternal(new GetBlobResult(blobInfo, null), null); progressTracker.setCryptoJobSuccess(); } else { decryptJobMetricsTracker.incrementOperationError(); logger.trace("Exception thrown on decryption for {}", exception, blobId); setOperationException( new RouterException("Exception thrown on decrypting the content for " + blobId, exception, RouterErrorCode.UnexpectedInternalError)); progressTracker.setCryptoJobFailed(); } decryptJobMetricsTracker.onJobResultProcessingComplete(); routerCallback.onPollReady(); })); } }</code><technical_language>in places, setLifeVersion is called right new BlobInfo. Instead of adding a new setter, alternative making BlobInfo.lifeVersion final adding a new constructor takes life version argument</technical_language>

Target:
private void handleBody(InputStream payload, MessageMetadata messageMetadata, MessageInfo messageInfo) throws IOException, MessageFormatException { ByteBuffer encryptionKey = messageMetadata == null ? null : messageMetadata.getEncryptionKey(); serverBlobProperties = MessageFormatRecord.deserializeBlobProperties(payload); updateTtlIfRequired(serverBlobProperties, messageInfo); ByteBuffer userMetadata = MessageFormatRecord.deserializeUserMetadata(payload); if (encryptionKey == null) { BlobInfo blobInfo = new BlobInfo(serverBlobProperties, userMetadata.array(), messageInfo.getLifeVersion()); operationResult = new GetBlobResultInternal(new GetBlobResult(blobInfo, null), null); } else { progressTracker.initializeCryptoJobTracker(CryptoJobType.DECRYPTION); logger.trace("Submitting decrypt job for {}", blobId); decryptJobMetricsTracker.onJobSubmission(); long startTimeMs = System.currentTimeMillis(); cryptoJobHandler.submitJob( new DecryptJob(blobId, encryptionKey.duplicate(), null, userMetadata, cryptoService, kms, decryptJobMetricsTracker, (DecryptJob.DecryptJobResult result, Exception exception) -> { decryptJobMetricsTracker.onJobResultProcessingStart(); logger.trace("Handling decrypt job callback results for {}", blobId); routerMetrics.decryptTimeMs.update(System.currentTimeMillis() - startTimeMs); if (exception == null) { logger.trace("Successfully updating decrypt job callback results for {}", blobId); BlobInfo blobInfo = new BlobInfo(serverBlobProperties, result.getDecryptedUserMetadata().array(), messageInfo.getLifeVersion()); operationResult = new GetBlobResultInternal(new GetBlobResult(blobInfo, null), null); progressTracker.setCryptoJobSuccess(); } else { decryptJobMetricsTracker.incrementOperationError(); logger.trace("Exception thrown on decryption for {}", exception, blobId); setOperationException( new RouterException("Exception thrown on decrypting the content for " + blobId, exception, RouterErrorCode.UnexpectedInternalError)); progressTracker.setCryptoJobFailed(); } decryptJobMetricsTracker.onJobResultProcessingComplete(); routerCallback.onPollReady(); })); } }