diff --git a/hadoop-ozone/client/pom.xml b/hadoop-ozone/client/pom.xml index f7cbd5597a54..b5ba8e7e5376 100644 --- a/hadoop-ozone/client/pom.xml +++ b/hadoop-ozone/client/pom.xml @@ -51,6 +51,10 @@ https://maven.apache.org/xsd/maven-4.0.0.xsd"> org.slf4j slf4j-log4j12 + + + org.mockito + mockito-core test diff --git a/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/BaseFileChecksumHelper.java b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/BaseFileChecksumHelper.java new file mode 100644 index 000000000000..1afbc8a3cf68 --- /dev/null +++ b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/BaseFileChecksumHelper.java @@ -0,0 +1,198 @@ +/* + * 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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.client; + +import com.google.common.annotations.VisibleForTesting; +import org.apache.hadoop.fs.FileChecksum; +import org.apache.hadoop.fs.MD5MD5CRC32GzipFileChecksum; +import org.apache.hadoop.hdds.scm.XceiverClientFactory; +import org.apache.hadoop.io.DataOutputBuffer; +import org.apache.hadoop.io.MD5Hash; +import org.apache.hadoop.ozone.client.protocol.ClientProtocol; +import org.apache.hadoop.ozone.client.rpc.RpcClient; +import org.apache.hadoop.ozone.om.helpers.OmKeyArgs; +import org.apache.hadoop.ozone.om.helpers.OmKeyInfo; +import org.apache.hadoop.ozone.om.helpers.OmKeyLocationInfo; +import org.apache.hadoop.ozone.om.protocol.OzoneManagerProtocol; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.util.List; + +/** + * The base class to support file checksum. + */ +public abstract class BaseFileChecksumHelper { + static final Logger LOG = + LoggerFactory.getLogger(BaseFileChecksumHelper.class); + + private OzoneVolume volume; + private OzoneBucket bucket; + private String keyName; + private final long length; + private ClientProtocol rpcClient; + + private XceiverClientFactory xceiverClientFactory; + private final DataOutputBuffer blockChecksumBuf = new DataOutputBuffer(); + private FileChecksum fileChecksum; + private List keyLocationInfos; + private long remaining = 0L; + private int bytesPerCRC = -1; + private long crcPerBlock = 0; + + // initialization + BaseFileChecksumHelper( + OzoneVolume volume, OzoneBucket bucket, String keyName, + long length, ClientProtocol rpcClient) throws IOException { + + this.volume = volume; + this.bucket = bucket; + this.keyName = keyName; + this.length = length; + this.rpcClient = rpcClient; + this.xceiverClientFactory = + ((RpcClient)rpcClient).getXceiverClientManager(); + if (this.length > 0) { + fetchBlocks(); + } + } + + protected String getSrc() { + return "Volume: " + volume.getName() + " Bucket: " + bucket.getName() + " " + + keyName; + } + + protected long getLength() { + return length; + } + + protected ClientProtocol getRpcClient() { + return rpcClient; + } + + protected XceiverClientFactory getXceiverClientFactory() { + return xceiverClientFactory; + } + + protected DataOutputBuffer getBlockChecksumBuf() { + return blockChecksumBuf; + } + + protected List getKeyLocationInfoList() { + return keyLocationInfos; + } + + protected long getRemaining() { + return remaining; + } + + protected void setRemaining(long remaining) { + this.remaining = remaining; + } + + int getBytesPerCRC() { + return bytesPerCRC; + } + + protected void setBytesPerCRC(int bytesPerCRC) { + this.bytesPerCRC = bytesPerCRC; + } + + /** + * Request the blocks created in the most recent version from Ozone Manager. + * + * @throws IOException + */ + private void fetchBlocks() throws IOException { + OzoneManagerProtocol ozoneManagerClient = + getRpcClient().getOzoneManagerClient(); + OmKeyArgs keyArgs = new OmKeyArgs.Builder() + .setVolumeName(volume.getName()) + .setBucketName(bucket.getName()) + .setKeyName(keyName) + .setRefreshPipeline(true) + .setSortDatanodesInPipeline(true) + .setLatestVersionLocation(true) + .build(); + OmKeyInfo keyInfo = ozoneManagerClient.lookupKey(keyArgs); + + // use OmKeyArgs to call Om.lookup() and get OmKeyInfo + keyLocationInfos = keyInfo + .getLatestVersionLocations().getBlocksLatestVersionOnly(); + } + + /** + * Compute file checksum given the list of chunk checksums requested earlier. + * @throws IOException + */ + public void compute() throws IOException { + /** + * request length is 0 or the file is empty, return one with the + * magic entry that matches the md5 of a 32 byte zero-padded byte array. + */ + if (keyLocationInfos == null || keyLocationInfos.isEmpty()) { + // Explicitly specified here in case the default DataOutputBuffer + // buffer length value is changed in future. + final int lenOfZeroBytes = 32; + byte[] emptyBlockMd5 = new byte[lenOfZeroBytes]; + MD5Hash fileMD5 = MD5Hash.digest(emptyBlockMd5); + fileChecksum = new MD5MD5CRC32GzipFileChecksum(0, 0, fileMD5); + } else { + checksumBlocks(); + fileChecksum = makeFinalResult(); + } + } + + @VisibleForTesting + List getKeyLocationInfos() { + return keyLocationInfos; + } + + + /** + * Compute block checksums block by block and append the raw bytes of the + * block checksums into getBlockChecksumBuf(). + * + * @throws IOException + */ + protected abstract void checksumBlocks() throws IOException; + + /** + * Make final file checksum result given the per-block or per-block-group + * checksums collected into getBlockChecksumBuf(). + */ + private FileChecksum makeFinalResult() throws IOException { + // TODO: support composite CRC + return makeMd5CrcResult(); + } + + private FileChecksum makeMd5CrcResult() { + // TODO: support CRC32C + //compute file MD5 + final MD5Hash fileMD5 = MD5Hash.digest(getBlockChecksumBuf().getData()); + // assume CRC32 for now + return new MD5MD5CRC32GzipFileChecksum(getBytesPerCRC(), + crcPerBlock, fileMD5); + } + + public FileChecksum getFileChecksum() { + return fileChecksum; + } + +} diff --git a/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/ReplicatedFileChecksumHelper.java b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/ReplicatedFileChecksumHelper.java new file mode 100644 index 000000000000..168458a9802b --- /dev/null +++ b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/ReplicatedFileChecksumHelper.java @@ -0,0 +1,181 @@ +/* + * 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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.client; + +import org.apache.hadoop.fs.PathIOException; +import org.apache.hadoop.hdds.client.BlockID; +import org.apache.hadoop.hdds.client.ReplicationConfig; +import org.apache.hadoop.hdds.client.StandaloneReplicationConfig; +import org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos; +import org.apache.hadoop.hdds.protocol.proto.HddsProtos; +import org.apache.hadoop.hdds.scm.XceiverClientSpi; +import org.apache.hadoop.hdds.scm.pipeline.Pipeline; +import org.apache.hadoop.hdds.scm.storage.ContainerProtocolCalls; +import org.apache.hadoop.hdds.security.token.OzoneBlockTokenIdentifier; +import org.apache.hadoop.io.MD5Hash; +import org.apache.hadoop.ozone.client.rpc.RpcClient; +import org.apache.hadoop.ozone.om.helpers.OmKeyLocationInfo; +import org.apache.hadoop.security.token.Token; + +import java.io.IOException; +import java.util.List; + +/** + * The helper class to compute file checksum for replicated files. + */ +public class ReplicatedFileChecksumHelper extends BaseFileChecksumHelper { + private int blockIdx; + + ReplicatedFileChecksumHelper( + OzoneVolume volume, OzoneBucket bucket, String keyName, long length, + RpcClient rpcClient) throws IOException { + super(volume, bucket, keyName, length, rpcClient); + } + + @Override + protected void checksumBlocks() throws IOException { + long currentLength = 0; + for (blockIdx = 0; + blockIdx < getKeyLocationInfoList().size() && getRemaining() >= 0; + blockIdx++) { + OmKeyLocationInfo keyLocationInfo = + getKeyLocationInfoList().get(blockIdx); + currentLength += keyLocationInfo.getLength(); + if (currentLength > getLength()) { + return; + } + + if (!checksumBlock(keyLocationInfo)) { + throw new PathIOException( + getSrc(), "Fail to get block MD5 for " + keyLocationInfo); + } + } + } + + /** + * Return true when sounds good to continue or retry, false when severe + * condition or totally failed. + */ + private boolean checksumBlock(OmKeyLocationInfo keyLocationInfo) + throws IOException { + + long blockNumBytes = keyLocationInfo.getLength(); + + if (getRemaining() < blockNumBytes) { + blockNumBytes = getRemaining(); + } + setRemaining(getRemaining() - blockNumBytes); + // for each block, send request + List chunkInfos = + getChunkInfos(keyLocationInfo); + ContainerProtos.ChecksumData checksumData = + chunkInfos.get(0).getChecksumData(); + int bytesPerChecksum = checksumData.getBytesPerChecksum(); + setBytesPerCRC(bytesPerChecksum); + + byte[] blockChecksum = getBlockChecksumFromChunkChecksums( + keyLocationInfo, chunkInfos); + String blockChecksumForDebug = populateBlockChecksumBuf(blockChecksum); + + LOG.debug("got reply from pipeline {} for block {}: blockChecksum={}, " + + "blockChecksumType={}", + keyLocationInfo.getPipeline(), keyLocationInfo.getBlockID(), + blockChecksumForDebug, checksumData.getType()); + return true; + } + + // copied from BlockInputStream + /** + * Send RPC call to get the block info from the container. + * @return List of chunks in this block. + */ + protected List getChunkInfos( + OmKeyLocationInfo keyLocationInfo) throws IOException { + // irrespective of the container state, we will always read via Standalone + // protocol. + Token token = keyLocationInfo.getToken(); + Pipeline pipeline = keyLocationInfo.getPipeline(); + BlockID blockID = keyLocationInfo.getBlockID(); + if (pipeline.getType() != HddsProtos.ReplicationType.STAND_ALONE) { + pipeline = Pipeline.newBuilder(pipeline) + .setReplicationConfig(new StandaloneReplicationConfig( + ReplicationConfig + .getLegacyFactor(pipeline.getReplicationConfig()))) + .build(); + } + + boolean success = false; + List chunks; + XceiverClientSpi xceiverClientSpi = null; + try { + if (LOG.isDebugEnabled()) { + LOG.debug("Initializing BlockInputStream for get key to access {}", + blockID.getContainerID()); + } + xceiverClientSpi = + getXceiverClientFactory().acquireClientForReadData(pipeline); + + ContainerProtos.DatanodeBlockID datanodeBlockID = blockID + .getDatanodeBlockIDProtobuf(); + ContainerProtos.GetBlockResponseProto response = ContainerProtocolCalls + .getBlock(xceiverClientSpi, datanodeBlockID, token); + + chunks = response.getBlockData().getChunksList(); + success = true; + } finally { + if (!success && xceiverClientSpi != null) { + getXceiverClientFactory().releaseClientForReadData( + xceiverClientSpi, false); + } + } + + return chunks; + } + + // TODO: copy BlockChecksumHelper here + byte[] getBlockChecksumFromChunkChecksums(OmKeyLocationInfo keyLocationInfo, + List chunkInfoList) + throws IOException { + // TODO: support composite CRC + final int lenOfZeroBytes = 32; + byte[] emptyBlockMd5 = new byte[lenOfZeroBytes]; + MD5Hash fileMD5 = MD5Hash.digest(emptyBlockMd5); + return fileMD5.getDigest(); + } + + /** + * Parses out the raw blockChecksum bytes from {@code checksumData} + * according to the blockChecksumType and populates the cumulative + * blockChecksumBuf with it. + * + * @return a debug-string representation of the parsed checksum if + * debug is enabled, otherwise null. + */ + String populateBlockChecksumBuf(byte[] checksumData) + throws IOException { + String blockChecksumForDebug = null; + //read md5 + final MD5Hash md5 = new MD5Hash(checksumData); + md5.write(getBlockChecksumBuf()); + if (LOG.isDebugEnabled()) { + blockChecksumForDebug = md5.toString(); + } + + return blockChecksumForDebug; + } +} diff --git a/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/rpc/RpcClient.java b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/rpc/RpcClient.java index 9ca86939bf48..4f2a4942b1f0 100644 --- a/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/rpc/RpcClient.java +++ b/hadoop-ozone/client/src/main/java/org/apache/hadoop/ozone/client/rpc/RpcClient.java @@ -280,6 +280,10 @@ public void onRemoval( }).build(); } + public XceiverClientFactory getXceiverClientManager() { + return xceiverClientManager; + } + static boolean validateOmVersion(String expectedVersion, List serviceInfoList) { if (expectedVersion == null || expectedVersion.isEmpty()) { diff --git a/hadoop-ozone/client/src/test/java/org/apache/hadoop/ozone/client/TestReplicatedFileChecksumHelper.java b/hadoop-ozone/client/src/test/java/org/apache/hadoop/ozone/client/TestReplicatedFileChecksumHelper.java new file mode 100644 index 000000000000..dfb2ddc652c8 --- /dev/null +++ b/hadoop-ozone/client/src/test/java/org/apache/hadoop/ozone/client/TestReplicatedFileChecksumHelper.java @@ -0,0 +1,230 @@ +/* + * 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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.client; + +import org.apache.hadoop.fs.FileChecksum; +import org.apache.hadoop.fs.MD5MD5CRC32GzipFileChecksum; +import org.apache.hadoop.hdds.client.BlockID; +import org.apache.hadoop.hdds.client.RatisReplicationConfig; +import org.apache.hadoop.hdds.conf.OzoneConfiguration; +import org.apache.hadoop.hdds.protocol.DatanodeDetails; +import org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos; +import org.apache.hadoop.hdds.protocol.proto.HddsProtos; +import org.apache.hadoop.hdds.scm.XceiverClientFactory; +import org.apache.hadoop.hdds.scm.XceiverClientGrpc; +import org.apache.hadoop.hdds.scm.XceiverClientReply; +import org.apache.hadoop.hdds.scm.pipeline.Pipeline; +import org.apache.hadoop.hdds.scm.pipeline.PipelineID; +import org.apache.hadoop.ozone.client.rpc.RpcClient; +import org.apache.hadoop.ozone.om.helpers.OmKeyInfo; +import org.apache.hadoop.ozone.om.helpers.OmKeyLocationInfo; +import org.apache.hadoop.ozone.om.helpers.OmKeyLocationInfoGroup; +import org.apache.hadoop.ozone.om.protocol.OzoneManagerProtocol; +import org.apache.hadoop.util.DataChecksum; +import org.apache.hadoop.util.Time; +import org.apache.ratis.thirdparty.com.google.protobuf.ByteString; +import org.junit.Test; +import org.mockito.Mockito; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.UUID; +import java.util.concurrent.CompletableFuture; + +import static org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos.ChecksumType.CRC32; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; + +/** + * Unit tests for ReplicatedFileChecksumHelper class. + */ +public class TestReplicatedFileChecksumHelper { + + @Test + public void testEmptyBlock() throws IOException { + // test the file checksum of a file with an empty block. + RpcClient rpcClient = Mockito.mock(RpcClient.class); + + OzoneManagerProtocol om = Mockito.mock(OzoneManagerProtocol.class); + when(rpcClient.getOzoneManagerClient()).thenReturn(om); + + OmKeyInfo omKeyInfo = new OmKeyInfo.Builder() + .setVolumeName(null) + .setBucketName(null) + .setKeyName(null) + .setOmKeyLocationInfos(Collections.singletonList( + new OmKeyLocationInfoGroup(0, new ArrayList<>()))) + .setCreationTime(Time.now()) + .setModificationTime(Time.now()) + .setDataSize(0) + .setReplicationConfig(new RatisReplicationConfig( + HddsProtos.ReplicationFactor.ONE)) + .setFileEncryptionInfo(null) + .setAcls(null) + .build(); + + when(om.lookupKey(any())).thenReturn(omKeyInfo); + + OzoneVolume volume = Mockito.mock(OzoneVolume.class); + when(volume.getName()).thenReturn("vol1"); + OzoneBucket bucket = Mockito.mock(OzoneBucket.class); + when(bucket.getName()).thenReturn("bucket1"); + + ReplicatedFileChecksumHelper helper = new ReplicatedFileChecksumHelper( + volume, bucket, "dummy", 10, rpcClient); + helper.compute(); + FileChecksum fileChecksum = helper.getFileChecksum(); + assertTrue(fileChecksum instanceof MD5MD5CRC32GzipFileChecksum); + assertEquals(DataChecksum.Type.CRC32, + ((MD5MD5CRC32GzipFileChecksum)fileChecksum).getCrcType()); + + // test negative length + helper = new ReplicatedFileChecksumHelper( + volume, bucket, "dummy", -1, rpcClient); + helper.compute(); + assertNull(helper.getKeyLocationInfoList()); + } + + @Test + public void testOneBlock() throws IOException { + // test the file checksum of a file with one block. + OzoneConfiguration conf = new OzoneConfiguration(); + + RpcClient rpcClient = Mockito.mock(RpcClient.class); + + List dns = Arrays.asList( + DatanodeDetails.newBuilder().setUuid(UUID.randomUUID()).build()); + Pipeline pipeline; + pipeline = Pipeline.newBuilder() + .setId(PipelineID.randomId()) + .setReplicationConfig( + new RatisReplicationConfig(HddsProtos.ReplicationFactor.THREE)) + .setState(Pipeline.PipelineState.CLOSED) + .setNodes(dns) + .build(); + + XceiverClientGrpc client = new XceiverClientGrpc(pipeline, conf) { + @Override + public XceiverClientReply sendCommandAsync( + ContainerProtos.ContainerCommandRequestProto request, + DatanodeDetails dn) { + return buildValidResponse(); + } + }; + XceiverClientFactory factory = Mockito.mock(XceiverClientFactory.class); + when(factory.acquireClientForReadData(any())).thenReturn(client); + + when(rpcClient.getXceiverClientManager()).thenReturn(factory); + + OzoneManagerProtocol om = Mockito.mock(OzoneManagerProtocol.class); + when(rpcClient.getOzoneManagerClient()).thenReturn(om); + + BlockID blockID = new BlockID(1, 1); + OmKeyLocationInfo omKeyLocationInfo = + new OmKeyLocationInfo.Builder().setPipeline(pipeline) + .setBlockID(blockID) + .build(); + + List omKeyLocationInfoList = + Arrays.asList(omKeyLocationInfo); + + OmKeyInfo omKeyInfo = new OmKeyInfo.Builder() + .setVolumeName(null) + .setBucketName(null) + .setKeyName(null) + .setOmKeyLocationInfos(Collections.singletonList( + new OmKeyLocationInfoGroup(0, omKeyLocationInfoList))) + .setCreationTime(Time.now()) + .setModificationTime(Time.now()) + .setDataSize(0) + .setReplicationConfig(new RatisReplicationConfig( + HddsProtos.ReplicationFactor.ONE)) + .setFileEncryptionInfo(null) + .setAcls(null) + .build(); + + when(om.lookupKey(any())).thenReturn(omKeyInfo); + + OzoneVolume volume = Mockito.mock(OzoneVolume.class); + when(volume.getName()).thenReturn("vol1"); + OzoneBucket bucket = Mockito.mock(OzoneBucket.class); + when(bucket.getName()).thenReturn("bucket1"); + + ReplicatedFileChecksumHelper helper = new ReplicatedFileChecksumHelper( + volume, bucket, "dummy", 10, rpcClient); + + helper.compute(); + FileChecksum fileChecksum = helper.getFileChecksum(); + assertTrue(fileChecksum instanceof MD5MD5CRC32GzipFileChecksum); + assertEquals(1, helper.getKeyLocationInfos().size()); + } + + private XceiverClientReply buildValidResponse() { + // return a GetBlockResponse message of a block and its chunk checksums. + ContainerProtos.DatanodeBlockID blockID = + ContainerProtos.DatanodeBlockID.newBuilder() + .setContainerID(1) + .setLocalID(1) + .setBlockCommitSequenceId(1).build(); + + byte[] byteArray = new byte[10]; + ByteString byteString = ByteString.copyFrom(byteArray); + + ContainerProtos.ChecksumData checksumData = + ContainerProtos.ChecksumData.newBuilder() + .setType(CRC32) + .setBytesPerChecksum(1024) + .addChecksums(byteString) + .build(); + + ContainerProtos.ChunkInfo chunkInfo = + ContainerProtos.ChunkInfo.newBuilder() + .setChunkName("dummy_chunk") + .setOffset(1) + .setLen(10) + .setChecksumData(checksumData) + .build(); + + ContainerProtos.BlockData blockData = + ContainerProtos.BlockData.newBuilder() + .setBlockID(blockID) + .addChunks(chunkInfo) + .build(); + ContainerProtos.GetBlockResponseProto getBlockResponseProto + = ContainerProtos.GetBlockResponseProto.newBuilder() + .setBlockData(blockData) + .build(); + + ContainerProtos.ContainerCommandResponseProto resp = + ContainerProtos.ContainerCommandResponseProto.newBuilder() + .setCmdType(ContainerProtos.Type.GetBlock) + .setResult(ContainerProtos.Result.SUCCESS) + .setGetBlock(getBlockResponseProto) + .build(); + final CompletableFuture + replyFuture = new CompletableFuture<>(); + replyFuture.complete(resp); + return new XceiverClientReply(replyFuture); + } +} \ No newline at end of file diff --git a/hadoop-ozone/client/src/test/resources/log4j.properties b/hadoop-ozone/client/src/test/resources/log4j.properties deleted file mode 100644 index 398786689af3..000000000000 --- a/hadoop-ozone/client/src/test/resources/log4j.properties +++ /dev/null @@ -1,23 +0,0 @@ -# -# 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 -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# 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. -# -# log4j configuration used during build and unit tests - -log4j.rootLogger=INFO,stdout -log4j.threshold=ALL -log4j.appender.stdout=org.apache.log4j.ConsoleAppender -log4j.appender.stdout.layout=org.apache.log4j.PatternLayout -log4j.appender.stdout.layout.ConversionPattern=%d{ISO8601} [%t] %-5p %c{2} (%F:%M(%L)) - %m%n