diff --git a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/security/TestOMDelegationTokenRequest.java b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/security/TestOMDelegationTokenRequest.java new file mode 100644 index 000000000000..08c95f6e8f2e --- /dev/null +++ b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/security/TestOMDelegationTokenRequest.java @@ -0,0 +1,71 @@ +/* + * 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.om.request.security; + +import org.apache.hadoop.hdds.conf.ConfigurationSource; +import org.apache.hadoop.hdds.conf.OzoneConfiguration; +import org.apache.hadoop.ozone.om.OMMetadataManager; +import org.apache.hadoop.ozone.om.OMMetrics; +import org.apache.hadoop.ozone.om.OmMetadataManagerImpl; +import org.apache.hadoop.ozone.om.OzoneManager; +import org.apache.hadoop.ozone.om.ratis.utils.OzoneManagerDoubleBufferHelper; +import static org.apache.hadoop.ozone.om.OMConfigKeys.OZONE_OM_DB_DIRS; +import org.junit.Rule; +import org.junit.Before; +import org.junit.After; +import org.junit.rules.TemporaryFolder; +import org.mockito.Mockito; +import static org.mockito.Mockito.when; + +/** + * Base class for testing OM delegation token request. + */ +@SuppressWarnings("visibilitymodifier") +public class TestOMDelegationTokenRequest { + + @Rule + public TemporaryFolder folder = new TemporaryFolder(); + + protected OzoneManager ozoneManager; + protected OMMetrics omMetrics; + protected OMMetadataManager omMetadataManager; + protected ConfigurationSource conf; + + // Just setting OzoneManagerDoubleBuffer which does nothing. + protected OzoneManagerDoubleBufferHelper ozoneManagerDoubleBufferHelper = + ((response, transactionIndex) -> { + return null; + }); + + @Before + public void setup() throws Exception { + ozoneManager = Mockito.mock(OzoneManager.class); + + conf = new OzoneConfiguration(); + ((OzoneConfiguration) conf) + .set(OZONE_OM_DB_DIRS, folder.newFolder().getAbsolutePath()); + omMetadataManager = new OmMetadataManagerImpl((OzoneConfiguration) conf); + when(ozoneManager.getMetadataManager()).thenReturn(omMetadataManager); + } + + @After + public void stop() { + Mockito.framework().clearInlineMocks(); + } +} diff --git a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/security/TestOMGetDelegationTokenRequest.java b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/security/TestOMGetDelegationTokenRequest.java new file mode 100644 index 000000000000..df0fcb9fd19a --- /dev/null +++ b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/security/TestOMGetDelegationTokenRequest.java @@ -0,0 +1,221 @@ +/* + * 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.om.request.security; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import com.google.common.base.Optional; +import java.util.UUID; +import org.apache.hadoop.ozone.om.response.OMClientResponse; +import org.apache.hadoop.ozone.security.OzoneDelegationTokenSecretManager; +import org.apache.hadoop.ozone.security.OzoneTokenIdentifier; +import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.Type; +import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.Status; +import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos + .OMRequest; +import static org.apache.hadoop.ozone.security.OzoneTokenIdentifier.KIND_NAME; +import org.apache.hadoop.security.token.Token; +import org.apache.hadoop.security.proto.SecurityProtos.GetDelegationTokenRequestProto; +import org.apache.commons.lang3.RandomStringUtils; +import org.apache.hadoop.io.Text; +import org.mockito.Mockito; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.Mockito.when; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +/** + * The class tests OMGetDelegationTokenRequest. + */ +public class TestOMGetDelegationTokenRequest extends + TestOMDelegationTokenRequest { + + private OzoneDelegationTokenSecretManager secretManager; + private OzoneTokenIdentifier identifier; + private Token token; + private Text tester; + private OMRequest originalRequest; + private OMRequest modifiedRequest; + private OMGetDelegationTokenRequest omGetDelegationTokenRequest; + final private String checkResponse = ""; + + @Before + public void setupGetDelegationToken() { + secretManager = Mockito.mock(OzoneDelegationTokenSecretManager.class); + when(ozoneManager.getDelegationTokenMgr()).thenReturn(secretManager); + + setupToken(); + setupRequest(); + } + + private void setupRequest() { + GetDelegationTokenRequestProto getDelegationTokenRequestProto = + GetDelegationTokenRequestProto.newBuilder() + .setRenewer(identifier.getRenewer().toString()) + .build(); + + originalRequest = OMRequest.newBuilder() + .setClientId(UUID.randomUUID().toString()) + .setCmdType(Type.GetDelegationToken) + .setGetDelegationTokenRequest(getDelegationTokenRequestProto) + .build(); + + omGetDelegationTokenRequest = + new OMGetDelegationTokenRequest(originalRequest); + + modifiedRequest = null; + } + + private void verifyUnchangedRequest() { + Assert.assertEquals( + originalRequest.getCmdType(), + modifiedRequest.getCmdType()); + Assert.assertEquals( + originalRequest.getClientId(), + modifiedRequest.getClientId()); + } + + private void setupToken() { + tester = new Text("tester"); + identifier = new OzoneTokenIdentifier(tester, tester, tester); + identifier.setOmCertSerialId("certID"); + identifier.setOmServiceId(""); + + byte[] password = RandomStringUtils + .randomAlphabetic(10) + .getBytes(StandardCharsets.UTF_8); + Text service = new Text("OMTest:9862"); + token = new Token<>(identifier.getBytes(), password, KIND_NAME, service); + } + + private OMClientResponse setValidateAndUpdateCache() throws IOException { + modifiedRequest = omGetDelegationTokenRequest.preExecute(ozoneManager); + OMGetDelegationTokenRequest reqPreExecuted = + new OMGetDelegationTokenRequest(modifiedRequest); + + long txLogIndex = 1L; + return reqPreExecuted.validateAndUpdateCache( + ozoneManager, txLogIndex, ozoneManagerDoubleBufferHelper); + } + + @Test + public void testPreExecuteWithNonNullToken() throws Exception { + /* Let token of ozoneManager.getDelegationToken() is nonNull. */ + when(ozoneManager.getDelegationToken(tester)).thenReturn(token); + + long tokenRenewInterval = 1000L; + when(ozoneManager.getDelegationTokenMgr().getTokenRenewInterval()) + .thenReturn(tokenRenewInterval); + + modifiedRequest = omGetDelegationTokenRequest.preExecute(ozoneManager); + verifyUnchangedRequest(); + + long originalInterval = originalRequest.getUpdateGetDelegationTokenRequest() + .getTokenRenewInterval(); + long renewInterval = modifiedRequest.getUpdateGetDelegationTokenRequest() + .getTokenRenewInterval(); + Assert.assertNotEquals(originalInterval, renewInterval); + Assert.assertEquals(tokenRenewInterval, renewInterval); + + /* In preExecute(), if the token is nonNull + we set GetDelegationTokenResponse with response. */ + Assert.assertNotEquals(checkResponse, + modifiedRequest.getUpdateGetDelegationTokenRequest() + .getGetDelegationTokenResponse() + .toString()); + Assert.assertNotNull(modifiedRequest + .getUpdateGetDelegationTokenRequest() + .getGetDelegationTokenResponse()); + } + + @Test + public void testPreExecuteWithNullToken() throws Exception { + /* Let token of ozoneManager.getDelegationToken() is Null. */ + when(ozoneManager.getDelegationToken(tester)).thenReturn(null); + + modifiedRequest = omGetDelegationTokenRequest.preExecute(ozoneManager); + verifyUnchangedRequest(); + + /* In preExecute(), if the token is null + we do not set GetDelegationTokenResponse with response. */ + Assert.assertEquals(checkResponse, + modifiedRequest.getUpdateGetDelegationTokenRequest() + .getGetDelegationTokenResponse() + .toString()); + } + + @Test + public void testValidateAndUpdateCacheWithNonNullToken() throws Exception { + /* Let token of ozoneManager.getDelegationToken() is nonNull. */ + when(ozoneManager.getDelegationToken(tester)).thenReturn(token); + + /* Mock OzoneDelegationTokenSecretManager#updateToken() to + * get specific renewTime for verifying OMClientResponse returned by + * validateAndUpdateCache(). */ + long renewTime = 1000L; + when(secretManager.updateToken( + any(Token.class), any(OzoneTokenIdentifier.class), anyLong())) + .thenReturn(renewTime); + + OMClientResponse clientResponse = setValidateAndUpdateCache(); + + Optional responseRenewTime = Optional.fromNullable( + omMetadataManager.getDelegationTokenTable().get(identifier)); + Assert.assertEquals(Optional.of(renewTime), responseRenewTime); + + Assert.assertEquals(Status.OK, clientResponse.getOMResponse().getStatus()); + } + + @Test + public void testValidateAndUpdateCacheWithNullToken() throws Exception { + /* Let token of ozoneManager.getDelegationToken() is Null. */ + when(ozoneManager.getDelegationToken(tester)).thenReturn(null); + + OMClientResponse clientResponse = setValidateAndUpdateCache(); + + boolean hasResponse = modifiedRequest.getUpdateGetDelegationTokenRequest() + .getGetDelegationTokenResponse().hasResponse(); + Assert.assertFalse(hasResponse); + + Optional responseRenewTime = Optional.fromNullable( + omMetadataManager.getDelegationTokenTable().get(identifier)); + Assert.assertEquals(Optional.absent(), responseRenewTime); + + Assert.assertEquals(Status.OK, clientResponse.getOMResponse().getStatus()); + } + + @Test + public void testValidateAndUpdateCacheWithException() throws Exception { + /* Create a token that causes InvalidProtocolBufferException by + * OzoneTokenIdentifier#readProtoBuf(). */ + Token exceptToken = new Token<>(); + when(ozoneManager.getDelegationToken(tester)).thenReturn(exceptToken); + + OMClientResponse clientResponse = setValidateAndUpdateCache(); + + boolean hasResponse = modifiedRequest.getUpdateGetDelegationTokenRequest() + .getGetDelegationTokenResponse().hasResponse(); + Assert.assertTrue(hasResponse); + + Assert.assertNotEquals(Status.OK, + clientResponse.getOMResponse().getStatus()); + } +} diff --git a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/security/package-info.java b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/security/package-info.java new file mode 100644 index 000000000000..4a72a86c81fa --- /dev/null +++ b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/request/security/package-info.java @@ -0,0 +1,23 @@ +/* + * 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 contains test classes for delegation token requests. + */ +package org.apache.hadoop.ozone.om.request.security; \ No newline at end of file diff --git a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/response/security/TestOMDelegationTokenResponse.java b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/response/security/TestOMDelegationTokenResponse.java new file mode 100644 index 000000000000..816e696ea0c1 --- /dev/null +++ b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/response/security/TestOMDelegationTokenResponse.java @@ -0,0 +1,51 @@ +/* + * 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.om.response.security; + +import org.apache.hadoop.hdds.conf.ConfigurationSource; +import org.apache.hadoop.hdds.conf.OzoneConfiguration; +import org.apache.hadoop.hdds.utils.db.BatchOperation; +import org.apache.hadoop.ozone.om.OMConfigKeys; +import org.apache.hadoop.ozone.om.OMMetadataManager; +import org.apache.hadoop.ozone.om.OmMetadataManagerImpl; +import org.junit.Before; +import org.junit.Rule; +import org.junit.rules.TemporaryFolder; +import java.io.IOException; + +/** Base test class for delegation token response. */ +@SuppressWarnings("visibilitymodifier") +public class TestOMDelegationTokenResponse { + + @Rule + public TemporaryFolder folder = new TemporaryFolder(); + + protected ConfigurationSource conf; + protected OMMetadataManager omMetadataManager; + protected BatchOperation batchOperation; + + @Before + public void setup() throws IOException { + conf = new OzoneConfiguration(); + ((OzoneConfiguration) conf).set(OMConfigKeys.OZONE_OM_DB_DIRS, + folder.newFolder().getAbsolutePath()); + omMetadataManager = new OmMetadataManagerImpl((OzoneConfiguration) conf); + batchOperation = omMetadataManager.getStore().initBatchOperation(); + } +} diff --git a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/response/security/TestOMGetDelegationTokenResponse.java b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/response/security/TestOMGetDelegationTokenResponse.java new file mode 100644 index 000000000000..df90d7ec8931 --- /dev/null +++ b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/response/security/TestOMGetDelegationTokenResponse.java @@ -0,0 +1,95 @@ +/* + * 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.om.response.security; + +import org.apache.hadoop.io.Text; +import org.apache.hadoop.ozone.om.request.security.OMGetDelegationTokenRequest; +import org.apache.hadoop.ozone.security.OzoneTokenIdentifier; +import org.apache.hadoop.security.proto.SecurityProtos.GetDelegationTokenRequestProto; +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.UpdateGetDelegationTokenRequest; +import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.Type; +import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.Status; +import java.io.IOException; +import java.util.UUID; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +/** The class tests OMGetDelegationTokenResponse. */ +public class TestOMGetDelegationTokenResponse extends + TestOMDelegationTokenResponse { + + private OzoneTokenIdentifier identifier; + private UpdateGetDelegationTokenRequest updateGetDelegationTokenRequest; + + @Before + public void setupGetDelegationToken() { + Text tester = new Text("tester"); + identifier = new OzoneTokenIdentifier(tester, tester, tester); + identifier.setOmCertSerialId("certID"); + + GetDelegationTokenRequestProto getDelegationTokenRequestProto = + GetDelegationTokenRequestProto.newBuilder() + .setRenewer(identifier.getRenewer().toString()) + .build(); + + OMRequest omRequest = OMRequest.newBuilder() + .setClientId(UUID.randomUUID().toString()) + .setCmdType(Type.GetDelegationToken) + .setGetDelegationTokenRequest(getDelegationTokenRequestProto) + .build(); + + updateGetDelegationTokenRequest = + new OMGetDelegationTokenRequest(omRequest) + .getOmRequest() + .getUpdateGetDelegationTokenRequest(); + } + + @Test + public void testAddToDBBatch() throws IOException { + OMResponse omResponse = OMResponse.newBuilder() + .setCmdType(Type.GetDelegationToken) + .setStatus(Status.OK) + .setSuccess(true) + .setGetDelegationTokenResponse( + updateGetDelegationTokenRequest + .getGetDelegationTokenResponse()) + .build(); + + long renewTime = 1000L; + OMGetDelegationTokenResponse getDelegationTokenResponse = + new OMGetDelegationTokenResponse(identifier, renewTime, omResponse); + + getDelegationTokenResponse.addToDBBatch(omMetadataManager, batchOperation); + omMetadataManager.getStore().commitBatchOperation(batchOperation); + + long rowNumInTable = 1; + long rowNumInTokenTable = omMetadataManager + .countRowsInTable(omMetadataManager.getDelegationTokenTable()); + Assert.assertEquals(rowNumInTable, rowNumInTokenTable); + + long renewTimeInTable = omMetadataManager.getDelegationTokenTable() + .get(identifier); + Assert.assertEquals(renewTime, renewTimeInTable); + } +} diff --git a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/response/security/package-info.java b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/response/security/package-info.java new file mode 100644 index 000000000000..1c197c6f4dc9 --- /dev/null +++ b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/response/security/package-info.java @@ -0,0 +1,21 @@ +/** + * 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 contains test classes for delegation token responses. + */ +package org.apache.hadoop.ozone.om.response.security;