This is an automated email from the ASF dual-hosted git repository. wuzhiguo pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/bigtop-manager.git
The following commit(s) were added to refs/heads/main by this push: new 68b888d1 BIGTOP-4392: Add unit test for command stage classes in server module (#192) 68b888d1 is described below commit 68b888d1541686b7f58c1f243dccbef06519c1d4 Author: xianrenzw <139131974+xianre...@users.noreply.github.com> AuthorDate: Tue Mar 25 17:10:11 2025 +0800 BIGTOP-4392: Add unit test for command stage classes in server module (#192) --- .../command/stage/AbstractComponentStage.java | 2 +- .../server/command/stage/AbstractStage.java | 5 - .../command/stage/AbstractComponentStageTest.java | 91 ++++ .../command/stage/ComponentAddStageTest.java | 76 +++ .../command/stage/ComponentCheckStageTest.java | 76 +++ .../command/stage/ComponentConfigureStageTest.java | 76 +++ .../command/stage/ComponentInitStageTest.java | 76 +++ .../command/stage/ComponentPrepareStageTest.java | 76 +++ .../server/command/stage/ComponentStageTest.java | 159 ------ .../command/stage/ComponentStartStageTest.java | 76 +++ .../command/stage/ComponentStopStageTest.java | 76 +++ .../server/command/stage/HostCheckStageTest.java | 82 +--- .../server/command/stage/SetupJdkStageTest.java | 82 +--- .../server/command/stage/StageContextTest.java | 189 ++++++++ .../services/kafka/configuration/kafka-broker.xml | 537 +++++++++++++++++++++ .../services/kafka/configuration/kafka-env.xml | 71 +++ .../services/kafka/configuration/kafka-log4j.xml | 143 ++++++ .../services/kafka/configuration/kafka.conf.xml | 54 +++ .../bigtop/3.3.0/services/kafka/metainfo.xml | 63 +++ .../stacks/bigtop/3.3.0/services/kafka/order.json | 8 + .../services/zookeeper/configuration/zoo.cfg.xml | 128 +++++ .../zookeeper/configuration/zookeeper-env.xml | 58 +++ .../bigtop/3.3.0/services/zookeeper/metainfo.xml | 64 +++ .../bigtop/3.3.0/services/zookeeper/order.json | 5 + 24 files changed, 1980 insertions(+), 293 deletions(-) diff --git a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/stage/AbstractComponentStage.java b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/stage/AbstractComponentStage.java index 8d35b8d8..ce610b8b 100644 --- a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/stage/AbstractComponentStage.java +++ b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/stage/AbstractComponentStage.java @@ -85,7 +85,7 @@ public abstract class AbstractComponentStage extends AbstractStage { return taskContext; } - private Map<String, List<String>> getClusterHosts() { + protected Map<String, List<String>> getClusterHosts() { Map<String, List<String>> clusterHosts = new HashMap<>(); for (ClusterPO clusterPO : clusterDao.findAll()) { List<String> hosts = new ArrayList<>(); diff --git a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/stage/AbstractStage.java b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/stage/AbstractStage.java index 15b821cd..47f99871 100644 --- a/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/stage/AbstractStage.java +++ b/bigtop-manager-server/src/main/java/org/apache/bigtop/manager/server/command/stage/AbstractStage.java @@ -161,9 +161,4 @@ public abstract class AbstractStage implements Stage { return stagePO; } - - protected void setStageContextAndTasksForTest(StageContext stageContext, List<Task> tasks) { - this.stageContext = stageContext; - this.tasks = tasks; - } } diff --git a/bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/command/stage/AbstractComponentStageTest.java b/bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/command/stage/AbstractComponentStageTest.java new file mode 100644 index 00000000..c921a054 --- /dev/null +++ b/bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/command/stage/AbstractComponentStageTest.java @@ -0,0 +1,91 @@ +/* + * 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 + * + * https://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.bigtop.manager.server.command.stage; + +import org.apache.bigtop.manager.common.utils.Environments; +import org.apache.bigtop.manager.dao.po.ClusterPO; +import org.apache.bigtop.manager.server.command.task.TaskContext; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.test.util.ReflectionTestUtils; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doCallRealMethod; +import static org.mockito.Mockito.mockStatic; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +public class AbstractComponentStageTest { + + @Mock + private AbstractComponentStage stage; + + @Test + @SuppressWarnings("unchecked") + public void testCreateTaskContext() { + StageContext stageContext = new StageContext(); + stageContext.setServiceName("zookeeper"); + stageContext.setComponentName("zookeeper_server"); + + ClusterPO clusterPO = new ClusterPO(); + clusterPO.setId(1L); + clusterPO.setName("test"); + clusterPO.setRootDir("/opt"); + clusterPO.setUserGroup("test"); + + ReflectionTestUtils.setField(stage, "stageContext", stageContext); + ReflectionTestUtils.setField(stage, "clusterPO", clusterPO); + + MockedStatic<Environments> mocked = mockStatic(Environments.class); + when(Environments.isDevMode()).thenReturn(true); + + Map<String, List<String>> componentHosts = new HashMap<>(); + componentHosts.put("test", List.of("host1")); + + when(stage.getClusterHosts()).thenReturn(componentHosts); + doCallRealMethod().when(stage).createTaskContext(any()); + TaskContext taskContext = stage.createTaskContext("host1"); + + assertEquals(1L, taskContext.getClusterId()); + assertEquals("test", taskContext.getClusterName()); + assertEquals("zookeeper", taskContext.getServiceName()); + assertEquals("zookeeper_server", taskContext.getComponentName()); + assertEquals("ZooKeeper Server", taskContext.getComponentDisplayName()); + assertEquals("zookeeper", taskContext.getServiceUser()); + assertEquals("test", taskContext.getUserGroup()); + assertEquals("/opt", taskContext.getRootDir()); + + Map<String, Object> properties = taskContext.getProperties(); + Map<String, List<String>> clusterHosts = (Map<String, List<String>>) properties.get("clusterHosts"); + assertEquals(1, taskContext.getProperties().size()); + assertEquals(1, clusterHosts.size()); + assertEquals("host1", clusterHosts.get("test").get(0)); + + mocked.close(); + } +} diff --git a/bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/command/stage/ComponentAddStageTest.java b/bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/command/stage/ComponentAddStageTest.java new file mode 100644 index 00000000..e2b213e5 --- /dev/null +++ b/bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/command/stage/ComponentAddStageTest.java @@ -0,0 +1,76 @@ +/* + * 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 + * + * https://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.bigtop.manager.server.command.stage; + +import org.apache.bigtop.manager.common.utils.Environments; +import org.apache.bigtop.manager.server.command.task.ComponentAddTask; +import org.apache.bigtop.manager.server.command.task.Task; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.MockedConstruction; +import org.mockito.MockedStatic; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.test.util.ReflectionTestUtils; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doCallRealMethod; +import static org.mockito.Mockito.mockConstruction; +import static org.mockito.Mockito.mockStatic; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +public class ComponentAddStageTest { + + @Mock + private ComponentAddStage stage; + + @Test + public void testCreateTask() { + MockedConstruction<?> mocked = mockConstruction(ComponentAddTask.class); + + doCallRealMethod().when(stage).createTask(any()); + Task task = stage.createTask("host1"); + + assertEquals(1, mocked.constructed().size()); + assertInstanceOf(ComponentAddTask.class, task); + + mocked.close(); + } + + @Test + public void testGetName() { + StageContext stageContext = new StageContext(); + stageContext.setServiceName("zookeeper"); + stageContext.setComponentName("zookeeper_server"); + + ReflectionTestUtils.setField(stage, "stageContext", stageContext); + + MockedStatic<Environments> mocked = mockStatic(Environments.class); + when(Environments.isDevMode()).thenReturn(true); + + doCallRealMethod().when(stage).getName(); + assertEquals("Add ZooKeeper Server", stage.getName()); + + mocked.close(); + } +} diff --git a/bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/command/stage/ComponentCheckStageTest.java b/bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/command/stage/ComponentCheckStageTest.java new file mode 100644 index 00000000..2db9eda9 --- /dev/null +++ b/bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/command/stage/ComponentCheckStageTest.java @@ -0,0 +1,76 @@ +/* + * 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 + * + * https://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.bigtop.manager.server.command.stage; + +import org.apache.bigtop.manager.common.utils.Environments; +import org.apache.bigtop.manager.server.command.task.ComponentCheckTask; +import org.apache.bigtop.manager.server.command.task.Task; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.MockedConstruction; +import org.mockito.MockedStatic; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.test.util.ReflectionTestUtils; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doCallRealMethod; +import static org.mockito.Mockito.mockConstruction; +import static org.mockito.Mockito.mockStatic; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +public class ComponentCheckStageTest { + + @Mock + private ComponentCheckStage stage; + + @Test + public void testCreateTask() { + MockedConstruction<?> mocked = mockConstruction(ComponentCheckTask.class); + + doCallRealMethod().when(stage).createTask(any()); + Task task = stage.createTask("host1"); + + assertEquals(1, mocked.constructed().size()); + assertInstanceOf(ComponentCheckTask.class, task); + + mocked.close(); + } + + @Test + public void testGetName() { + StageContext stageContext = new StageContext(); + stageContext.setServiceName("zookeeper"); + stageContext.setComponentName("zookeeper_server"); + + ReflectionTestUtils.setField(stage, "stageContext", stageContext); + + MockedStatic<Environments> mocked = mockStatic(Environments.class); + when(Environments.isDevMode()).thenReturn(true); + + doCallRealMethod().when(stage).getName(); + assertEquals("Check ZooKeeper Server", stage.getName()); + + mocked.close(); + } +} diff --git a/bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/command/stage/ComponentConfigureStageTest.java b/bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/command/stage/ComponentConfigureStageTest.java new file mode 100644 index 00000000..0967eb0a --- /dev/null +++ b/bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/command/stage/ComponentConfigureStageTest.java @@ -0,0 +1,76 @@ +/* + * 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 + * + * https://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.bigtop.manager.server.command.stage; + +import org.apache.bigtop.manager.common.utils.Environments; +import org.apache.bigtop.manager.server.command.task.ComponentConfigureTask; +import org.apache.bigtop.manager.server.command.task.Task; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.MockedConstruction; +import org.mockito.MockedStatic; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.test.util.ReflectionTestUtils; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doCallRealMethod; +import static org.mockito.Mockito.mockConstruction; +import static org.mockito.Mockito.mockStatic; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +public class ComponentConfigureStageTest { + + @Mock + private ComponentConfigureStage stage; + + @Test + public void testCreateTask() { + MockedConstruction<?> mocked = mockConstruction(ComponentConfigureTask.class); + + doCallRealMethod().when(stage).createTask(any()); + Task task = stage.createTask("host1"); + + assertEquals(1, mocked.constructed().size()); + assertInstanceOf(ComponentConfigureTask.class, task); + + mocked.close(); + } + + @Test + public void testGetName() { + StageContext stageContext = new StageContext(); + stageContext.setServiceName("zookeeper"); + stageContext.setComponentName("zookeeper_server"); + + ReflectionTestUtils.setField(stage, "stageContext", stageContext); + + MockedStatic<Environments> mocked = mockStatic(Environments.class); + when(Environments.isDevMode()).thenReturn(true); + + doCallRealMethod().when(stage).getName(); + assertEquals("Configure ZooKeeper Server", stage.getName()); + + mocked.close(); + } +} diff --git a/bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/command/stage/ComponentInitStageTest.java b/bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/command/stage/ComponentInitStageTest.java new file mode 100644 index 00000000..9457b703 --- /dev/null +++ b/bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/command/stage/ComponentInitStageTest.java @@ -0,0 +1,76 @@ +/* + * 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 + * + * https://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.bigtop.manager.server.command.stage; + +import org.apache.bigtop.manager.common.utils.Environments; +import org.apache.bigtop.manager.server.command.task.ComponentInitTask; +import org.apache.bigtop.manager.server.command.task.Task; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.MockedConstruction; +import org.mockito.MockedStatic; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.test.util.ReflectionTestUtils; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doCallRealMethod; +import static org.mockito.Mockito.mockConstruction; +import static org.mockito.Mockito.mockStatic; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +public class ComponentInitStageTest { + + @Mock + private ComponentInitStage stage; + + @Test + public void testCreateTask() { + MockedConstruction<?> mocked = mockConstruction(ComponentInitTask.class); + + doCallRealMethod().when(stage).createTask(any()); + Task task = stage.createTask("host1"); + + assertEquals(1, mocked.constructed().size()); + assertInstanceOf(ComponentInitTask.class, task); + + mocked.close(); + } + + @Test + public void testGetName() { + StageContext stageContext = new StageContext(); + stageContext.setServiceName("zookeeper"); + stageContext.setComponentName("zookeeper_server"); + + ReflectionTestUtils.setField(stage, "stageContext", stageContext); + + MockedStatic<Environments> mocked = mockStatic(Environments.class); + when(Environments.isDevMode()).thenReturn(true); + + doCallRealMethod().when(stage).getName(); + assertEquals("Init ZooKeeper Server", stage.getName()); + + mocked.close(); + } +} diff --git a/bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/command/stage/ComponentPrepareStageTest.java b/bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/command/stage/ComponentPrepareStageTest.java new file mode 100644 index 00000000..20339b66 --- /dev/null +++ b/bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/command/stage/ComponentPrepareStageTest.java @@ -0,0 +1,76 @@ +/* + * 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 + * + * https://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.bigtop.manager.server.command.stage; + +import org.apache.bigtop.manager.common.utils.Environments; +import org.apache.bigtop.manager.server.command.task.ComponentPrepareTask; +import org.apache.bigtop.manager.server.command.task.Task; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.MockedConstruction; +import org.mockito.MockedStatic; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.test.util.ReflectionTestUtils; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doCallRealMethod; +import static org.mockito.Mockito.mockConstruction; +import static org.mockito.Mockito.mockStatic; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +public class ComponentPrepareStageTest { + + @Mock + private ComponentPrepareStage stage; + + @Test + public void testCreateTask() { + MockedConstruction<?> mocked = mockConstruction(ComponentPrepareTask.class); + + doCallRealMethod().when(stage).createTask(any()); + Task task = stage.createTask("host1"); + + assertEquals(1, mocked.constructed().size()); + assertInstanceOf(ComponentPrepareTask.class, task); + + mocked.close(); + } + + @Test + public void testGetName() { + StageContext stageContext = new StageContext(); + stageContext.setServiceName("zookeeper"); + stageContext.setComponentName("zookeeper_server"); + + ReflectionTestUtils.setField(stage, "stageContext", stageContext); + + MockedStatic<Environments> mocked = mockStatic(Environments.class); + when(Environments.isDevMode()).thenReturn(true); + + doCallRealMethod().when(stage).getName(); + assertEquals("Prepare ZooKeeper Server", stage.getName()); + + mocked.close(); + } +} diff --git a/bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/command/stage/ComponentStageTest.java b/bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/command/stage/ComponentStageTest.java deleted file mode 100644 index c8a19bed..00000000 --- a/bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/command/stage/ComponentStageTest.java +++ /dev/null @@ -1,159 +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 - * - * https://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.bigtop.manager.server.command.stage; - -import org.apache.bigtop.manager.dao.po.StagePO; -import org.apache.bigtop.manager.dao.repository.ClusterDao; -import org.apache.bigtop.manager.dao.repository.HostDao; -import org.apache.bigtop.manager.dao.repository.StageDao; -import org.apache.bigtop.manager.server.command.task.Task; -import org.apache.bigtop.manager.server.holder.SpringContextHolder; - -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.Mock; -import org.mockito.MockedStatic; -import org.mockito.Spy; -import org.mockito.junit.jupiter.MockitoExtension; - -import java.util.List; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.doCallRealMethod; -import static org.mockito.Mockito.lenient; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.mockStatic; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -@ExtendWith(MockitoExtension.class) -public class ComponentStageTest { - - private MockedStatic<SpringContextHolder> springContextHolderMockedStatic; - - @Mock - private StageDao stageDao; - - @Mock - private HostDao hostDao; - - @Mock - private ClusterDao clusterDao; - - @Spy - private StageContext stageContext; - - @Mock - private List<Task> tasks; - - @Spy - private StagePO stagePO; - - private ComponentAddStage componentStage; - - @BeforeEach - public void setUp() { - springContextHolderMockedStatic = mockStatic(SpringContextHolder.class); - when(SpringContextHolder.getBean(StageDao.class)).thenReturn(stageDao); - when(SpringContextHolder.getBean(HostDao.class)).thenReturn(hostDao); - when(SpringContextHolder.getBean(ClusterDao.class)).thenReturn(clusterDao); - - componentStage = mock(ComponentAddStage.class); - - stageContext.setComponentName("TestComponentName"); - stageContext.setServiceName("TestServiceName"); - stageContext.setClusterId(123L); - - doCallRealMethod().when(componentStage).setStageContextAndTasksForTest(any(), any()); - componentStage.setStageContextAndTasksForTest(stageContext, tasks); - - doCallRealMethod().when(componentStage).injectBeans(); - componentStage.injectBeans(); - - doCallRealMethod().when(componentStage).loadStagePO(any()); - lenient().when(componentStage.getStagePO()).thenCallRealMethod(); - componentStage.loadStagePO(stagePO); - } - - @AfterEach - public void tearDown() { - springContextHolderMockedStatic.close(); - } - - @Test - public void testInjectBeans() { - springContextHolderMockedStatic.verify(() -> SpringContextHolder.getBean(any(Class.class)), times(3)); - } - - @Test - public void testBeforeCreateTasks() { - doCallRealMethod().when(componentStage).beforeCreateTasks(); - componentStage.beforeCreateTasks(); - verify(clusterDao, times(1)).findById(123L); - } - - @Test - public void tesGetServiceName() { - doCallRealMethod().when(componentStage).getServiceName(); - assertEquals("TestServiceName", componentStage.getServiceName()); - } - - @Test - public void tesGetComponentName() { - doCallRealMethod().when(componentStage).getComponentName(); - assertEquals("TestComponentName", componentStage.getComponentName()); - } - - @Test - public void testBeforeRun() { - doCallRealMethod().when(componentStage).beforeRun(); - componentStage.beforeRun(); - verify(stageDao, times(1)).partialUpdateById(any()); - } - - @Test - public void testOnSuccess() { - doCallRealMethod().when(componentStage).onSuccess(); - componentStage.onSuccess(); - verify(stageDao, times(1)).partialUpdateById(any()); - } - - @Test - public void testOnFailure() { - doCallRealMethod().when(componentStage).onFailure(); - componentStage.onFailure(); - verify(stageDao, times(1)).partialUpdateById(any()); - } - - @Test - public void testGetStageContext() { - doCallRealMethod().when(componentStage).getStageContext(); - assertEquals(stageContext, componentStage.getStageContext()); - } - - @Test - public void testGetTasks() { - doCallRealMethod().when(componentStage).getTasks(); - assertEquals(tasks, componentStage.getTasks()); - } -} diff --git a/bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/command/stage/ComponentStartStageTest.java b/bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/command/stage/ComponentStartStageTest.java new file mode 100644 index 00000000..d625e8e8 --- /dev/null +++ b/bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/command/stage/ComponentStartStageTest.java @@ -0,0 +1,76 @@ +/* + * 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 + * + * https://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.bigtop.manager.server.command.stage; + +import org.apache.bigtop.manager.common.utils.Environments; +import org.apache.bigtop.manager.server.command.task.ComponentStartTask; +import org.apache.bigtop.manager.server.command.task.Task; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.MockedConstruction; +import org.mockito.MockedStatic; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.test.util.ReflectionTestUtils; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doCallRealMethod; +import static org.mockito.Mockito.mockConstruction; +import static org.mockito.Mockito.mockStatic; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +public class ComponentStartStageTest { + + @Mock + private ComponentStartStage stage; + + @Test + public void testCreateTask() { + MockedConstruction<?> mocked = mockConstruction(ComponentStartTask.class); + + doCallRealMethod().when(stage).createTask(any()); + Task task = stage.createTask("host1"); + + assertEquals(1, mocked.constructed().size()); + assertInstanceOf(ComponentStartTask.class, task); + + mocked.close(); + } + + @Test + public void testGetName() { + StageContext stageContext = new StageContext(); + stageContext.setServiceName("zookeeper"); + stageContext.setComponentName("zookeeper_server"); + + ReflectionTestUtils.setField(stage, "stageContext", stageContext); + + MockedStatic<Environments> mocked = mockStatic(Environments.class); + when(Environments.isDevMode()).thenReturn(true); + + doCallRealMethod().when(stage).getName(); + assertEquals("Start ZooKeeper Server", stage.getName()); + + mocked.close(); + } +} diff --git a/bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/command/stage/ComponentStopStageTest.java b/bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/command/stage/ComponentStopStageTest.java new file mode 100644 index 00000000..de6e0b54 --- /dev/null +++ b/bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/command/stage/ComponentStopStageTest.java @@ -0,0 +1,76 @@ +/* + * 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 + * + * https://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.bigtop.manager.server.command.stage; + +import org.apache.bigtop.manager.common.utils.Environments; +import org.apache.bigtop.manager.server.command.task.ComponentStopTask; +import org.apache.bigtop.manager.server.command.task.Task; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.MockedConstruction; +import org.mockito.MockedStatic; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.test.util.ReflectionTestUtils; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doCallRealMethod; +import static org.mockito.Mockito.mockConstruction; +import static org.mockito.Mockito.mockStatic; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +public class ComponentStopStageTest { + + @Mock + private ComponentStopStage stage; + + @Test + public void testCreateTask() { + MockedConstruction<?> mocked = mockConstruction(ComponentStopTask.class); + + doCallRealMethod().when(stage).createTask(any()); + Task task = stage.createTask("host1"); + + assertEquals(1, mocked.constructed().size()); + assertInstanceOf(ComponentStopTask.class, task); + + mocked.close(); + } + + @Test + public void testGetName() { + StageContext stageContext = new StageContext(); + stageContext.setServiceName("zookeeper"); + stageContext.setComponentName("zookeeper_server"); + + ReflectionTestUtils.setField(stage, "stageContext", stageContext); + + MockedStatic<Environments> mocked = mockStatic(Environments.class); + when(Environments.isDevMode()).thenReturn(true); + + doCallRealMethod().when(stage).getName(); + assertEquals("Stop ZooKeeper Server", stage.getName()); + + mocked.close(); + } +} diff --git a/bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/command/stage/HostCheckStageTest.java b/bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/command/stage/HostCheckStageTest.java index 317ccd82..285d47ed 100644 --- a/bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/command/stage/HostCheckStageTest.java +++ b/bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/command/stage/HostCheckStageTest.java @@ -18,93 +18,47 @@ */ package org.apache.bigtop.manager.server.command.stage; -import org.apache.bigtop.manager.dao.po.StagePO; -import org.apache.bigtop.manager.dao.repository.HostDao; -import org.apache.bigtop.manager.dao.repository.StageDao; +import org.apache.bigtop.manager.server.command.task.HostCheckTask; import org.apache.bigtop.manager.server.command.task.Task; -import org.apache.bigtop.manager.server.holder.SpringContextHolder; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; -import org.mockito.MockedStatic; -import org.mockito.Spy; +import org.mockito.MockedConstruction; import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.test.util.ReflectionTestUtils; -import java.util.List; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doCallRealMethod; -import static org.mockito.Mockito.lenient; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.mockStatic; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.when; +import static org.mockito.Mockito.mockConstruction; @ExtendWith(MockitoExtension.class) public class HostCheckStageTest { - private MockedStatic<SpringContextHolder> springContextHolderMockedStatic; - @Mock - private StageDao stageDao; - - @Mock - private HostDao hostDao; - - @Spy - private StageContext stageContext; - - @Mock - private List<Task> tasks; - - @Spy - private StagePO stagePO; - - private HostCheckStage hostCheckStage; + private HostCheckStage stage; - @BeforeEach - public void setUp() { - springContextHolderMockedStatic = mockStatic(SpringContextHolder.class); - when(SpringContextHolder.getBean(StageDao.class)).thenReturn(stageDao); - when(SpringContextHolder.getBean(HostDao.class)).thenReturn(hostDao); - - hostCheckStage = mock(HostCheckStage.class); + @Test + public void testCreateTask() { + StageContext stageContext = new StageContext(); + ReflectionTestUtils.setField(stage, "stageContext", stageContext); - doCallRealMethod().when(hostCheckStage).setStageContextAndTasksForTest(any(), any()); - hostCheckStage.setStageContextAndTasksForTest(stageContext, tasks); + MockedConstruction<?> mocked = mockConstruction(HostCheckTask.class); - doCallRealMethod().when(hostCheckStage).injectBeans(); - hostCheckStage.injectBeans(); + doCallRealMethod().when(stage).createTask(any()); + Task task = stage.createTask("host1"); - doCallRealMethod().when(hostCheckStage).loadStagePO(any()); - lenient().when(hostCheckStage.getStagePO()).thenCallRealMethod(); - hostCheckStage.loadStagePO(stagePO); - } - - @AfterEach - public void tearDown() { - springContextHolderMockedStatic.close(); - } + assertEquals(1, mocked.constructed().size()); + assertInstanceOf(HostCheckTask.class, task); - @Test - public void testInjectBeans() { - springContextHolderMockedStatic.verify(() -> SpringContextHolder.getBean(any(Class.class)), times(2)); - } - - @Test - public void testBeforeCreateTasks() { - doCallRealMethod().when(hostCheckStage).beforeCreateTasks(); - assertDoesNotThrow(() -> hostCheckStage.beforeCreateTasks()); + mocked.close(); } @Test public void tesGetName() { - doCallRealMethod().when(hostCheckStage).getName(); - assertEquals("Check hosts", hostCheckStage.getName()); + doCallRealMethod().when(stage).getName(); + assertEquals("Check hosts", stage.getName()); } } diff --git a/bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/command/stage/SetupJdkStageTest.java b/bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/command/stage/SetupJdkStageTest.java index 0c18be92..3f11cf8f 100644 --- a/bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/command/stage/SetupJdkStageTest.java +++ b/bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/command/stage/SetupJdkStageTest.java @@ -18,93 +18,47 @@ */ package org.apache.bigtop.manager.server.command.stage; -import org.apache.bigtop.manager.dao.po.StagePO; -import org.apache.bigtop.manager.dao.repository.HostDao; -import org.apache.bigtop.manager.dao.repository.StageDao; +import org.apache.bigtop.manager.server.command.task.SetupJdkTask; import org.apache.bigtop.manager.server.command.task.Task; -import org.apache.bigtop.manager.server.holder.SpringContextHolder; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; -import org.mockito.MockedStatic; -import org.mockito.Spy; +import org.mockito.MockedConstruction; import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.test.util.ReflectionTestUtils; -import java.util.List; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doCallRealMethod; -import static org.mockito.Mockito.lenient; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.mockStatic; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.when; +import static org.mockito.Mockito.mockConstruction; @ExtendWith(MockitoExtension.class) public class SetupJdkStageTest { - private MockedStatic<SpringContextHolder> springContextHolderMockedStatic; - @Mock - private StageDao stageDao; - - @Mock - private HostDao hostDao; - - @Spy - private StageContext stageContext; - - @Mock - private List<Task> tasks; - - @Spy - private StagePO stagePO; - - private SetupJdkStage setupJdkStage; + private SetupJdkStage stage; - @BeforeEach - public void setUp() { - springContextHolderMockedStatic = mockStatic(SpringContextHolder.class); - when(SpringContextHolder.getBean(StageDao.class)).thenReturn(stageDao); - when(SpringContextHolder.getBean(HostDao.class)).thenReturn(hostDao); - - setupJdkStage = mock(SetupJdkStage.class); + @Test + public void testCreateTask() { + StageContext stageContext = new StageContext(); + ReflectionTestUtils.setField(stage, "stageContext", stageContext); - doCallRealMethod().when(setupJdkStage).setStageContextAndTasksForTest(any(), any()); - setupJdkStage.setStageContextAndTasksForTest(stageContext, tasks); + MockedConstruction<?> mocked = mockConstruction(SetupJdkTask.class); - doCallRealMethod().when(setupJdkStage).injectBeans(); - setupJdkStage.injectBeans(); + doCallRealMethod().when(stage).createTask(any()); + Task task = stage.createTask("host1"); - doCallRealMethod().when(setupJdkStage).loadStagePO(any()); - lenient().when(setupJdkStage.getStagePO()).thenCallRealMethod(); - setupJdkStage.loadStagePO(stagePO); - } - - @AfterEach - public void tearDown() { - springContextHolderMockedStatic.close(); - } + assertEquals(1, mocked.constructed().size()); + assertInstanceOf(SetupJdkTask.class, task); - @Test - public void testInjectBeans() { - springContextHolderMockedStatic.verify(() -> SpringContextHolder.getBean(any(Class.class)), times(2)); - } - - @Test - public void testBeforeCreateTasks() { - doCallRealMethod().when(setupJdkStage).beforeCreateTasks(); - assertDoesNotThrow(() -> setupJdkStage.beforeCreateTasks()); + mocked.close(); } @Test public void tesGetName() { - doCallRealMethod().when(setupJdkStage).getName(); - assertEquals("Setup JDK", setupJdkStage.getName()); + doCallRealMethod().when(stage).getName(); + assertEquals("Setup JDK", stage.getName()); } } diff --git a/bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/command/stage/StageContextTest.java b/bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/command/stage/StageContextTest.java new file mode 100644 index 00000000..5745f138 --- /dev/null +++ b/bigtop-manager-server/src/test/java/org/apache/bigtop/manager/server/command/stage/StageContextTest.java @@ -0,0 +1,189 @@ +/* + * 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 + * + * https://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.bigtop.manager.server.command.stage; + +import org.apache.bigtop.manager.dao.po.ClusterPO; +import org.apache.bigtop.manager.dao.repository.ClusterDao; +import org.apache.bigtop.manager.server.enums.CommandLevel; +import org.apache.bigtop.manager.server.holder.SpringContextHolder; +import org.apache.bigtop.manager.server.model.dto.CommandDTO; +import org.apache.bigtop.manager.server.model.dto.HostDTO; +import org.apache.bigtop.manager.server.model.dto.command.ClusterCommandDTO; +import org.apache.bigtop.manager.server.model.dto.command.HostCommandDTO; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.MockedStatic; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.mockito.Mockito.mockStatic; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +class StageContextTest { + + @Mock + private ClusterDao clusterDao; + + private MockedStatic<SpringContextHolder> springContextHolderMockedStatic; + + @BeforeEach + void setUp() { + springContextHolderMockedStatic = mockStatic(SpringContextHolder.class); + when(SpringContextHolder.getBean(ClusterDao.class)).thenReturn(clusterDao); + } + + @AfterEach + void tearDown() { + springContextHolderMockedStatic.close(); + } + + @Test + void testWithClusterIdAndClusterCommand() { + // Mock database cluster info + ClusterPO mockCluster = new ClusterPO(); + mockCluster.setId(1L); + mockCluster.setName("test-cluster"); + mockCluster.setUserGroup("test-user-group"); + mockCluster.setRootDir("/data/bigtop"); + when(clusterDao.findById(1L)).thenReturn(mockCluster); + + // Create test HostDTOs + HostDTO host1 = new HostDTO(); + host1.setHostnames(List.of("host1.example.com")); + HostDTO host2 = new HostDTO(); + host2.setHostnames(List.of("host2.example.com")); + + // Build CLUSTER-level command + ClusterCommandDTO clusterCommand = new ClusterCommandDTO(); + clusterCommand.setHosts(List.of(host1, host2)); + clusterCommand.setName("should-not-use-this-name"); + clusterCommand.setUserGroup("should-not-use-this-group"); + clusterCommand.setRootDir("/should/not/use/this"); + + CommandDTO commandDTO = new CommandDTO(); + commandDTO.setClusterId(1L); + commandDTO.setCommandLevel(CommandLevel.CLUSTER); + commandDTO.setClusterCommand(clusterCommand); + + // Execute conversion + StageContext context = StageContext.fromCommandDTO(commandDTO); + + // Verify cluster info comes from database + assertEquals(1L, context.getClusterId()); + assertEquals("test-cluster", context.getClusterName()); + assertEquals("test-user-group", context.getUserGroup()); + assertEquals("/data/bigtop", context.getRootDir()); + + // Verify hostnames not set (skip processing when clusterId exists) + assertNull(context.getHostnames()); + + // Ensure redundant command info is not used + assertEquals("test-cluster", context.getClusterName()); + } + + @Test + void testClusterCommandWithoutClusterId() { + // Create test HostDTOs + HostDTO host1 = new HostDTO(); + host1.setHostnames(List.of("hostA.example.com")); + HostDTO host2 = new HostDTO(); + host2.setHostnames(List.of("hostB.example.com")); + + // Build CLUSTER-level command (no clusterId) + ClusterCommandDTO clusterCommand = new ClusterCommandDTO(); + clusterCommand.setHosts(List.of(host1, host2)); + clusterCommand.setName("new-cluster"); + clusterCommand.setUserGroup("new-group"); + clusterCommand.setRootDir("/new/root"); + + CommandDTO commandDTO = new CommandDTO(); + commandDTO.setClusterId(null); + commandDTO.setCommandLevel(CommandLevel.CLUSTER); + commandDTO.setClusterCommand(clusterCommand); + + // Execute conversion + StageContext context = StageContext.fromCommandDTO(commandDTO); + + // Verify info comes from command payload + assertNull(context.getClusterId()); + assertEquals(List.of("hostA.example.com", "hostB.example.com"), context.getHostnames()); + assertEquals("new-cluster", context.getClusterName()); + assertEquals("new-group", context.getUserGroup()); + assertEquals("/new/root", context.getRootDir()); + } + + @Test + void testHostCommand() { + // Create HostCommandDTO test objects + HostCommandDTO host1 = new HostCommandDTO(); + host1.setHostnames(List.of("host-01.example.com", "host-01-alias.example.com")); + HostCommandDTO host2 = new HostCommandDTO(); + host2.setHostnames(List.of("host-02.example.com")); + + CommandDTO commandDTO = new CommandDTO(); + commandDTO.setCommandLevel(CommandLevel.HOST); + commandDTO.setHostCommands(List.of(host1, host2)); + + // Execute conversion + StageContext context = StageContext.fromCommandDTO(commandDTO); + + // Verify merged hostnames + assertEquals( + List.of("host-01.example.com", "host-01-alias.example.com", "host-02.example.com"), + context.getHostnames()); + + // Verify other fields not set + assertNull(context.getClusterId()); + assertNull(context.getClusterName()); + } + + @Test + void testServiceCommand() { + // Build SERVICE-level command + CommandDTO commandDTO = new CommandDTO(); + commandDTO.setCommandLevel(CommandLevel.SERVICE); + + StageContext context = StageContext.fromCommandDTO(commandDTO); + + // Verify no other fields set + assertNull(context.getClusterId()); + assertNull(context.getHostnames()); + } + + @Test + void testComponentCommand() { + // Build component level command + CommandDTO commandDTO = new CommandDTO(); + commandDTO.setCommandLevel(CommandLevel.COMPONENT); + + StageContext context = StageContext.fromCommandDTO(commandDTO); + + // Verify no other fields set + assertNull(context.getClusterId()); + assertNull(context.getHostnames()); + } +} diff --git a/bigtop-manager-server/src/test/resources/stacks/bigtop/3.3.0/services/kafka/configuration/kafka-broker.xml b/bigtop-manager-server/src/test/resources/stacks/bigtop/3.3.0/services/kafka/configuration/kafka-broker.xml new file mode 100644 index 00000000..2e915dc9 --- /dev/null +++ b/bigtop-manager-server/src/test/resources/stacks/bigtop/3.3.0/services/kafka/configuration/kafka-broker.xml @@ -0,0 +1,537 @@ +<?xml version="1.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 + ~ + ~ https://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. +--> + +<configuration> + <property> + <name>log.dirs</name> + <display-name>Log directories</display-name> + <value>/kafka-logs</value> + <description> + A comma-separated list of one or more directories in which Kafka data is stored. + Each new partition that is created will be placed in the directory which currently has the fewest + partitions. + </description> + </property> + <property> + <name>zookeeper.connect</name> + <value><![CDATA[<#if zk_server_list?? ><#list zk_server_list as host>${host}:2181<#sep>,</#sep></#list><#else>localhost:2181</#if>]]></value> + <description> + Zookeeper also allows you to add a "chroot" path which will make all kafka data for this cluster appear + under a particular path. + This is a way to setup multiple Kafka clusters or other applications on the same zookeeper cluster. + To do this give a connection string in the form hostname1:port1,hostname2:port2,hostname3:port3/chroot/path + which would put all this cluster's data under the path /chroot/path. Note that consumers must use the same + connection string. + </description> + </property> + <property> + <name>listeners</name> + <value><![CDATA[PLAINTEXT://<#if host?? >${host}:9092<#else>localhost:9092</#if>]]></value> + <description> + host and port where kafka broker will be accepting connections. localhost will be substituted with hostname. + </description> + </property> + <property> + <name>advertised.listeners</name> + <value><![CDATA[PLAINTEXT://<#if host?? >${host}:9092<#else>localhost:9092</#if>]]></value> + <description> + Listeners to publish to ZooKeeper for clients to use, if different than the listeners config property. + </description> + </property> + <property> + <name>message.max.bytes</name> + <value>1000000</value> + <description> + The maximum size of a message that the server can receive. + It is important that this property be in sync with the maximum fetch size your consumers use or + else an unruly producer will be able to publish messages too large for consumers to consume. + </description> + </property> + <property> + <name>num.network.threads</name> + <value>3</value> + <description> + The number of network threads that the server uses for handling network requests. + You probably don't need to change this. + </description> + </property> + <property> + <name>num.io.threads</name> + <value>8</value> + <description> + The number of I/O threads that the server uses for executing requests. You should have at least as many + threads as you have disks. + </description> + </property> + <property> + <name>queued.max.requests</name> + <value>500</value> + <description> + The number of requests that can be queued up for processing by the I/O threads before the network threads + stop reading in new requests. + </description> + </property> + <property> + <name>socket.send.buffer.bytes</name> + <value>102400</value> + <description>The SO_SNDBUFF buffer the server prefers for socket connections.</description> + </property> + <property> + <name>socket.receive.buffer.bytes</name> + <value>102400</value> + <description>The SO_RCVBUFF buffer the server prefers for socket connections.</description> + </property> + <property> + <name>socket.request.max.bytes</name> + <value>104857600</value> + <description> + The maximum request size the server will allow. This prevents the server from running out of memory and + should be smaller than the Java heap size. + </description> + </property> + <property> + <name>num.partitions</name> + <value>1</value> + <description>The default number of partitions per topic.</description> + </property> + <property> + <name>log.segment.bytes</name> + <value>1073741824</value> + <description> + The maximum request size the server will allow. + This prevents the server from running out of memory and should be smaller than the Java heap size. + </description> + </property> + <property> + <name>log.roll.hours</name> + <value>168</value> + <description> + This setting will force Kafka to roll a new log segment even if the log.segment.bytes size has not been + reached. + </description> + </property> + <property> + <name>log.retention.bytes</name> + <value>-1</value> + <description> + The amount of data to retain in the log for each topic-partitions. Note that this is the limit per-partition + so multiply by the number of partitions to get the total data retained for the topic. + Also note that if both log.retention.hours and log.retention.bytes are both set we delete a segment when + either limit is exceeded. + </description> + </property> + <property> + <name>log.retention.hours</name> + <value>168</value> + <description> + The number of hours to keep a log segment before it is deleted, i.e. the default data retention window for + all topics. + Note that if both log.retention.hours and log.retention.bytes are both set we delete a segment when either + limit is exceeded. + </description> + </property> + <property> + <name>log.cleanup.interval.mins</name> + <value>10</value> + <description> + The frequency in minutes that the log cleaner checks whether any log segment is eligible for deletion to + meet the retention policies. + </description> + </property> + <property> + <name>log.retention.check.interval.ms</name> + <value>600000</value> + <description> + The frequency in milliseconds that the log cleaner checks whether any log segment is eligible for deletion + to meet the retention policies. + </description> + </property> + <property> + <name>log.index.size.max.bytes</name> + <value>10485760</value> + <description> + The maximum size in bytes we allow for the offset index for each log segment. + Note that we will always pre-allocate a sparse file with this much space and shrink it down when the log + rolls. + If the index fills up we will roll a new log segment even if we haven't reached the log.segment.bytes limit. + </description> + </property> + <property> + <name>log.index.interval.bytes</name> + <value>4096</value> + <description> + The byte interval at which we add an entry to the offset index. + When executing a fetch request the server must do a linear scan for up to this many bytes to find the + correct position in the log to begin and end the fetch. + So setting this value to be larger will mean larger index files (and a bit more memory usage) but less + scanning. + However the server will never add more than one index entry per log append (even if more than + log.index.interval worth of messages are appended). + In general you probably don't need to mess with this value. + </description> + </property> + <property> + <name>auto.create.topics.enable</name> + <value>true</value> + <description> + Enable auto creation of topic on the server. + If this is set to true then attempts to produce, consume, or fetch metadata for a non-existent topic will + automatically create it with the default replication factor and number of partitions. + </description> + </property> + <property> + <name>controller.socket.timeout.ms</name> + <value>30000</value> + <description> + The socket timeout for commands from the partition management controller to the replicas. + </description> + </property> + <property> + <name>controller.message.queue.size</name> + <value>10</value> + <description>The buffer size for controller-to-broker-channels</description> + </property> + <property> + <name>default.replication.factor</name> + <value>1</value> + <description>The default replication factor for automatically created topics.</description> + </property> + <property> + <name>replica.lag.time.max.ms</name> + <value>10000</value> + <description> + If a follower hasn't sent any fetch requests for this window of time, the leader will remove the follower + from ISR (in-sync replicas) and treat it as dead. + </description> + </property> + <property> + <name>replica.lag.max.messages</name> + <value>4000</value> + <description> + If a replica falls more than this many messages behind the leader, the leader will remove the follower from + ISR and treat it as dead. + </description> + </property> + <property> + <name>replica.socket.timeout.ms</name> + <value>30000</value> + <description>The socket timeout for network requests to the leader for replicating data.</description> + </property> + <property> + <name>replica.socket.receive.buffer.bytes</name> + <value>65536</value> + <description>The socket receive buffer for network requests to the leader for replicating data.</description> + </property> + <property> + <name>replica.fetch.max.bytes</name> + <value>1048576</value> + <description> + The number of byes of messages to attempt to fetch for each partition in the fetch requests the replicas + send to the leader. + </description> + </property> + <property> + <name>replica.fetch.wait.max.ms</name> + <value>500</value> + <description> + The maximum amount of time to wait time for data to arrive on the leader in the fetch requests sent by the + replicas to the leader. + </description> + </property> + <property> + <name>replica.fetch.min.bytes</name> + <value>1</value> + <description> + Minimum bytes expected for each fetch response for the fetch requests from the replica to the leader. + If not enough bytes, wait up to replica.fetch.wait.max.ms for this many bytes to arrive. + </description> + </property> + <property> + <name>num.replica.fetchers</name> + <value>1</value> + <description> + Number of threads used to replicate messages from leaders. + Increasing this value can increase the degree of I/O parallelism in the follower broker. + </description> + </property> + <property> + <name>replica.high.watermark.checkpoint.interval.ms</name> + <value>5000</value> + <description> + The frequency with which each replica saves its high watermark to disk to handle recovery. + </description> + </property> + <property> + <name>fetch.purgatory.purge.interval.requests</name> + <value>10000</value> + <description>The purge interval (in number of requests) of the fetch request purgatory.</description> + </property> + <property> + <name>producer.purgatory.purge.interval.requests</name> + <value>10000</value> + <description>The purge interval (in number of requests) of the producer request purgatory.</description> + </property> + <property> + <name>zookeeper.session.timeout.ms</name> + <value>30000</value> + <description> + Zookeeper session timeout. + If the server fails to heartbeat to zookeeper within this period of time it is considered dead. + If you set this too low the server may be falsely considered dead; if you set it too high it may take too + long to recognize a truly dead server. + </description> + </property> + <property> + <name>zookeeper.connection.timeout.ms</name> + <value>25000</value> + <description> + The maximum amount of time that the client waits to establish a connection to zookeeper. + </description> + </property> + <property> + <name>zookeeper.sync.time.ms</name> + <value>2000</value> + <description>How far a ZK follower can be behind a ZK leader.</description> + </property> + <property> + <name>controlled.shutdown.max.retries</name> + <value>3</value> + <description> + Number of retries to complete the controlled shutdown successfully before executing an unclean shutdown. + </description> + </property> + <property> + <name>controlled.shutdown.retry.backoff.ms</name> + <value>5000</value> + <description>Backoff time between shutdown retries.</description> + </property> + <property> + <name>controlled.shutdown.enable</name> + <value>true</value> + <description> + Enable controlled shutdown of the broker. + If enabled, the broker will move all leaders on it to some other brokers before shutting itself down. + This reduces the unavailability window during shutdown. + </description> + </property> + <property> + <name>auto.leader.rebalance.enable</name> + <value>true</value> + <description> + Enables auto leader balancing. + A background thread checks and triggers leader balance if required at regular intervals. + </description> + </property> + <property> + <name>num.recovery.threads.per.data.dir</name> + <value>1</value> + <description> + The number of threads per data directory to be used for log recovery at startup and flushing at shutdown + </description> + </property> + <property> + <name>min.insync.replicas</name> + <value>1</value> + <description> + define the minimum number of replicas in ISR needed to satisfy a produce request with required.acks=-1 (or + all) + </description> + </property> + <property> + <name>leader.imbalance.per.broker.percentage</name> + <value>10</value> + <description> + The ratio of leader imbalance allowed per broker. + The controller would trigger a leader balance if it goes above this value per broker. + The value is specified in percentage. + </description> + </property> + <property> + <name>leader.imbalance.check.interval.seconds</name> + <value>300</value> + <description> + The frequency with which the partition re-balance check is triggered by the controller + </description> + </property> + <property> + <name>offset.metadata.max.bytes</name> + <value>4096</value> + <description>The maximum size for a metadata entry associated with an offset commit</description> + </property> + <property> + <name>offsets.load.buffer.size</name> + <value>5242880</value> + <description> + Batch size for reading from the offsets segments when loading offsets into the cache. + </description> + </property> + <property> + <name>offsets.topic.replication.factor</name> + <value>3</value> + <description> + The replication factor for the offsets topic (set higher to ensure availability). + To ensure that the effective replication factor of the offsets topic is the configured + value, the number of alive brokers has to be at least the replication factor at the time of the first + request for the offsets topic. + If not, either the offsets topic creation will fail or it will get a replication factor of min(alive + brokers, configured replication factor). + </description> + </property> + <property> + <name>offsets.topic.num.partitions</name> + <value>50</value> + <description> + The number of partitions for the offset commit topic (should not change after deployment) + </description> + </property> + <property> + <name>offsets.topic.segment.bytes</name> + <value>104857600</value> + <description> + The offsets topic segment bytes should be kept relatively small in order to facilitate faster log compaction + and cache loads + </description> + </property> + <property> + <name>offsets.topic.compression.codec</name> + <value>0</value> + <description> + Compression codec for the offsets topic - compression may be used to achieve \"atomic\" commits. + Default is NoCompression. + For Gzip add value 1 , SnappyCompression add value 2, LZ4CompressionCodec 3. + </description> + </property> + <property> + <name>offsets.retention.minutes</name> + <value>86400000</value> + <description>Log retention window in minutes for offsets topic</description> + </property> + <property> + <name>offsets.retention.check.interval.ms</name> + <value>600000</value> + <description>Frequency at which to check for stale offsets</description> + </property> + <property> + <name>offsets.commit.timeout.ms</name> + <value>5000</value> + <description> + Offset commit will be delayed until all replicas for the offsets topic receive the commit or this timeout is + reached. This is similar to the producer request timeout. + </description> + </property> + <property> + <name>offsets.commit.required.acks</name> + <value>-1</value> + <description> + The required acks before the commit can be accepted. + In general, the default (-1) should not be overridden + </description> + </property> + <property> + <name>delete.topic.enable</name> + <value>true</value> + <description> + Enables delete topic. + Delete topic through the admin tool will have no effect if this config is turned off + </description> + </property> + <property> + <name>compression.type</name> + <value>producer</value> + <description> + Specify the final compression type for a given topic. + This configuration accepts the standard compression codecs ('gzip', 'snappy', lz4). + It additionally accepts 'uncompressed' which is equivalent to no compression; and 'producer' which means + retain the original compression codec set by the producer. + </description> + </property> + <property> + <name>external.kafka.metrics.exclude.prefix</name> + <value>kafka.network.RequestMetrics,kafka.server.DelayedOperationPurgatory,kafka.server.BrokerTopicMetrics.BytesRejectedPerSec</value> + <description>Exclude metrics starting with these prefixes from being collected.</description> + </property> + <property> + <name>external.kafka.metrics.include.prefix</name> + <value>kafka.network.RequestMetrics.ResponseQueueTimeMs.request.OffsetCommit.98percentile,kafka.network.RequestMetrics.ResponseQueueTimeMs.request.Offsets.95percentile,kafka.network.RequestMetrics.ResponseSendTimeMs.request.Fetch.95percentile,kafka.network.RequestMetrics.RequestsPerSec.request</value> + <description> + These metrics would be included even if the exclude prefix omits them. + </description> + </property> + <property> + <name>sasl.enabled.mechanisms</name> + <value>GSSAPI</value> + <description> + The list of SASL mechanisms enabled in the Kafka server. + The list may contain any mechanism for which a security provider is available. + Only GSSAPI is enabled by default. + </description> + </property> + <property> + <name>security.inter.broker.protocol</name> + <value>PLAINTEXT</value> + <description> + Security protocol used to communicate between brokers. + Valid values are: PLAINTEXT, SSL, SASL_PLAINTEXT, SASL_SSL. + It is an error to set this and inter.broker.listener.name properties at the same time. + </description> + </property> + <property> + <name>sasl.mechanism.inter.broker.protocol</name> + <value>GSSAPI</value> + <description>SASL mechanism used for inter-broker communication. Default is GSSAPI.</description> + </property> + <property> + <name>ssl.client.auth</name> + <value>none</value> + <description>Configures kafka broker to request client authentication.</description> + </property> + <property> + <name>ssl.key.password</name> + <value/> + <description>The password of private key in the key store file.</description> + </property> + <property> + <name>ssl.keystore.location</name> + <value/> + <description>The location of key store file.</description> + </property> + <property> + <name>ssl.keystore.password</name> + <value/> + <description>The store password for key store file.</description> + </property> + <property> + <name>ssl.truststore.location</name> + <value/> + <description>The location of trust store file.</description> + </property> + <property> + <name>ssl.truststore.password</name> + <value/> + <description> + The password for trust store file. + If a password is not set access to the truststore is still available, but integrity checking is disabled + </description> + </property> + <property> + <name>producer.metrics.enable</name> + <value>false</value> + </property> +</configuration> \ No newline at end of file diff --git a/bigtop-manager-server/src/test/resources/stacks/bigtop/3.3.0/services/kafka/configuration/kafka-env.xml b/bigtop-manager-server/src/test/resources/stacks/bigtop/3.3.0/services/kafka/configuration/kafka-env.xml new file mode 100644 index 00000000..e51666ce --- /dev/null +++ b/bigtop-manager-server/src/test/resources/stacks/bigtop/3.3.0/services/kafka/configuration/kafka-env.xml @@ -0,0 +1,71 @@ +<?xml version="1.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. +--> + +<configuration> + <property> + <name>kafka_log_dir</name> + <display-name>Kafka Log directory</display-name> + <value>/var/log/kafka</value> + <description /> + </property> + <property> + <name>kafka_pid_dir</name> + <value>/var/run/kafka</value> + <display-name>Kafka PID dir</display-name> + <description /> + </property> + <property> + <name>kafka_user_nofile_limit</name> + <value>128000</value> + <description>Max open files limit setting for kafka user.</description> + </property> + <property> + <name>kafka_user_nproc_limit</name> + <value>65536</value> + <description>Max number of processes limit setting for kafka user.</description> + </property> + + <property> + <name>content</name> + <display-name>kafka-env template</display-name> + <description>This is the freemarker template for kafka-env.sh file</description> + <value><![CDATA[ +#!/bin/bash + +# Set KAFKA specific environment variables here. + +# The java implementation to use. +export JAVA_HOME=${java_home!} +<#noparse>export PATH=$PATH:${JAVA_HOME}/bin</#noparse> +export PID_DIR=${kafka_pid_dir!} +export LOG_DIR=${kafka_log_dir!} +<#if security_enabled > +export KAFKA_OPTS="-Djavax.security.auth.useSubjectCredsOnly=false {{kafka_kerberos_params}}" +<#else> +export KAFKA_OPTS={{kafka_kerberos_params}} +</#if> +export CLASSPATH=$CLASSPATH:${kafka_conf_dir} +]]> + </value> + <attrs> + <type>longtext</type> + </attrs> + </property> +</configuration> \ No newline at end of file diff --git a/bigtop-manager-server/src/test/resources/stacks/bigtop/3.3.0/services/kafka/configuration/kafka-log4j.xml b/bigtop-manager-server/src/test/resources/stacks/bigtop/3.3.0/services/kafka/configuration/kafka-log4j.xml new file mode 100644 index 00000000..f6f76a09 --- /dev/null +++ b/bigtop-manager-server/src/test/resources/stacks/bigtop/3.3.0/services/kafka/configuration/kafka-log4j.xml @@ -0,0 +1,143 @@ +<?xml version="1.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 + ~ + ~ https://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. +--> + +<configuration> + <property> + <name>kafkaLogMaxFileSize</name> + <value>256</value> + <description>The maximum size of backup file before the log is rotated</description> + <display-name>Kafka Log: backup file size</display-name> + </property> + <property> + <name>kafkaLogMaxBackupIndex</name> + <value>20</value> + <description>The number of backup files</description> + <display-name>Kafka Log: # of backup files</display-name> + </property> + <property> + <name>controllerLogMaxFileSize</name> + <value>256</value> + <description>The maximum size of backup file before the log is rotated</description> + <display-name>Kafka Controller Log: backup file size</display-name> + </property> + <property> + <name>controllerLogMaxBackupIndex</name> + <value>20</value> + <description>The number of backup files</description> + <display-name>Kafka Controller Log: # of backup files</display-name> + </property> + <property> + <name>content</name> + <display-name>kafka-log4j template</display-name> + <description>Custom log4j.properties</description> + <value><![CDATA[ +# +# +# 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. +# +# +# +kafka.logs.dir=logs + +log4j.rootLogger=INFO, stdout + +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=[%d{ISO8601}] %p %m (%c)%n + +log4j.appender.kafkaAppender=org.apache.log4j.DailyRollingFileAppender +log4j.appender.kafkaAppender.DatePattern='.'yyyy-MM-dd-HH +<#noparse>log4j.appender.kafkaAppender.File=${kafka.logs.dir}/server.log</#noparse> +log4j.appender.kafkaAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.kafkaAppender.layout.ConversionPattern=[%d{ISO8601}] %p %m (%c)%n +log4j.appender.kafkaAppender.MaxFileSize = ${kafkaLogMaxFileSize}MB +log4j.appender.kafkaAppender.MaxBackupIndex = ${kafkaLogMaxBackupIndex} + +log4j.appender.stateChangeAppender=org.apache.log4j.DailyRollingFileAppender +log4j.appender.stateChangeAppender.DatePattern='.'yyyy-MM-dd-HH +<#noparse>log4j.appender.stateChangeAppender.File=${kafka.logs.dir}/state-change.log</#noparse> +log4j.appender.stateChangeAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.stateChangeAppender.layout.ConversionPattern=[%d{ISO8601}] %p %m (%c)%n + +log4j.appender.requestAppender=org.apache.log4j.DailyRollingFileAppender +log4j.appender.requestAppender.DatePattern='.'yyyy-MM-dd-HH +<#noparse>log4j.appender.requestAppender.File=${kafka.logs.dir}/kafka-request.log</#noparse> +log4j.appender.requestAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.requestAppender.layout.ConversionPattern=[%d{ISO8601}] %p %m (%c)%n + +log4j.appender.cleanerAppender=org.apache.log4j.DailyRollingFileAppender +log4j.appender.cleanerAppender.DatePattern='.'yyyy-MM-dd-HH +<#noparse>log4j.appender.cleanerAppender.File=${kafka.logs.dir}/log-cleaner.log</#noparse> +log4j.appender.cleanerAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.cleanerAppender.layout.ConversionPattern=[%d{ISO8601}] %p %m (%c)%n + +log4j.appender.controllerAppender=org.apache.log4j.DailyRollingFileAppender +log4j.appender.controllerAppender.DatePattern='.'yyyy-MM-dd-HH +<#noparse>log4j.appender.controllerAppender.File=${kafka.logs.dir}/controller.log</#noparse> +log4j.appender.controllerAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.controllerAppender.layout.ConversionPattern=[%d{ISO8601}] %p %m (%c)%n +log4j.appender.controllerAppender.MaxFileSize = ${controllerLogMaxFileSize}MB +log4j.appender.controllerAppender.MaxBackupIndex = ${controllerLogMaxBackupIndex} +# Turn on all our debugging info +#log4j.logger.kafka.producer.async.DefaultEventHandler=DEBUG, kafkaAppender +#log4j.logger.kafka.client.ClientUtils=DEBUG, kafkaAppender +#log4j.logger.kafka.perf=DEBUG, kafkaAppender +<#noparse>#log4j.logger.kafka.perf.ProducerPerformance$ProducerThread=DEBUG, kafkaAppender</#noparse> +#log4j.logger.org.I0Itec.zkclient.ZkClient=DEBUG +log4j.logger.kafka=INFO, kafkaAppender +<#noparse>log4j.logger.kafka.network.RequestChannel$=WARN, requestAppender</#noparse> +<#noparse>log4j.additivity.kafka.network.RequestChannel$=false</#noparse> + +#log4j.logger.kafka.network.Processor=TRACE, requestAppender +#log4j.logger.kafka.server.KafkaApis=TRACE, requestAppender +#log4j.additivity.kafka.server.KafkaApis=false +log4j.logger.kafka.request.logger=WARN, requestAppender +log4j.additivity.kafka.request.logger=false + +log4j.logger.kafka.controller=TRACE, controllerAppender +log4j.additivity.kafka.controller=false + +log4j.logger.kafka.log.LogCleaner=INFO, cleanerAppender +log4j.additivity.kafka.log.LogCleaner=false + +log4j.logger.state.change.logger=TRACE, stateChangeAppender +log4j.additivity.state.change.logger=false +]]> + </value> + <attrs> + <type>longtext</type> + </attrs> + </property> +</configuration> \ No newline at end of file diff --git a/bigtop-manager-server/src/test/resources/stacks/bigtop/3.3.0/services/kafka/configuration/kafka.conf.xml b/bigtop-manager-server/src/test/resources/stacks/bigtop/3.3.0/services/kafka/configuration/kafka.conf.xml new file mode 100644 index 00000000..48076cd6 --- /dev/null +++ b/bigtop-manager-server/src/test/resources/stacks/bigtop/3.3.0/services/kafka/configuration/kafka.conf.xml @@ -0,0 +1,54 @@ +<?xml version="1.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. +--> + +<configuration> + <property> + <name>content</name> + <display-name>kafka.conf template</display-name> + <description>This is the freemarker template for kafka-env.sh file</description> + <value><![CDATA[ +# +# 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. +# + +${kafka_user} - nofile ${kafka_user_nofile_limit} +${kafka_group} - nproc ${kafka_user_nproc_limit} + +]]> + </value> + <attrs> + <type>longtext</type> + </attrs> + </property> +</configuration> \ No newline at end of file diff --git a/bigtop-manager-server/src/test/resources/stacks/bigtop/3.3.0/services/kafka/metainfo.xml b/bigtop-manager-server/src/test/resources/stacks/bigtop/3.3.0/services/kafka/metainfo.xml new file mode 100644 index 00000000..562bd378 --- /dev/null +++ b/bigtop-manager-server/src/test/resources/stacks/bigtop/3.3.0/services/kafka/metainfo.xml @@ -0,0 +1,63 @@ +<?xml version="1.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 + ~ + ~ https://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. +--> + +<metainfo> + <service> + <name>kafka</name> + <display-name>Kafka</display-name> + <desc> + Apache Kafka is an open-source distributed event streaming platform used by thousands of companies for + high-performance data pipelines, streaming analytics, data integration, and mission-critical + applications. + </desc> + <version>2.8.2-1</version> + <user>kafka</user> + <license>Apache-2.0</license> + + <components> + <component> + <name>kafka_broker</name> + <display-name>Kafka Broker</display-name> + <category>server</category> + <cardinality>1+</cardinality> + </component> + </components> + + <package-specifics> + <package-specific> + <architectures> + <arch>x86_64</arch> + <arch>aarch64</arch> + </architectures> + <packages> + <package> + <name>kafka-2.8.2-1.tgz</name> + <checksum>SHA-256:30a2d69ef081813624273d8a406c9b803c5868df998484e27207f85ea217870f</checksum> + </package> + </packages> + </package-specific> + </package-specifics> + + <required-services> + <service>zookeeper</service> + </required-services> + + </service> +</metainfo> diff --git a/bigtop-manager-server/src/test/resources/stacks/bigtop/3.3.0/services/kafka/order.json b/bigtop-manager-server/src/test/resources/stacks/bigtop/3.3.0/services/kafka/order.json new file mode 100644 index 00000000..2f55e86d --- /dev/null +++ b/bigtop-manager-server/src/test/resources/stacks/bigtop/3.3.0/services/kafka/order.json @@ -0,0 +1,8 @@ +{ + "KAFKA_BROKER-START": [ + "ZOOKEEPER_SERVER-START" + ], + "KAFKA_BROKER-RESTART": [ + "ZOOKEEPER_SERVER-RESTART" + ] +} \ No newline at end of file diff --git a/bigtop-manager-server/src/test/resources/stacks/bigtop/3.3.0/services/zookeeper/configuration/zoo.cfg.xml b/bigtop-manager-server/src/test/resources/stacks/bigtop/3.3.0/services/zookeeper/configuration/zoo.cfg.xml new file mode 100644 index 00000000..bd09086c --- /dev/null +++ b/bigtop-manager-server/src/test/resources/stacks/bigtop/3.3.0/services/zookeeper/configuration/zoo.cfg.xml @@ -0,0 +1,128 @@ +<?xml version="1.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. +--> + +<configuration> + <property> + <name>tickTime</name> + <value>3000</value> + <display-name>Length of single Tick</display-name> + <description> + The length of a single tick in milliseconds, which is the basic time unit used by ZooKeeper + </description> + </property> + <property> + <name>initLimit</name> + <value>10</value> + <display-name>Ticks to allow for sync at Init</display-name> + <description>Ticks to allow for sync at Init.</description> + </property> + <property> + <name>syncLimit</name> + <value>5</value> + <display-name>Ticks to allow for sync at Runtime</display-name> + <description>Ticks to allow for sync at Runtime.</description> + </property> + <property> + <name>clientPort</name> + <value>2181</value> + <display-name>Port for running ZK Server</display-name> + <description>Port for running ZK Server.</description> + </property> + <property> + <name>dataDir</name> + <value>/hadoop/zookeeper</value> + <display-name>ZooKeeper directory</display-name> + <description>Data directory for ZooKeeper.</description> + </property> + <property> + <name>autopurge.snapRetainCount</name> + <value>30</value> + <description> + ZooKeeper purge feature retains the autopurge. + snapRetainCount most recent snapshots and the corresponding transaction logs in the dataDir and dataLogDir + respectively and deletes the rest. + </description> + </property> + <property> + <name>autopurge.purgeInterval</name> + <value>24</value> + <description> + The time interval in hours for which the purge task has to be triggered. + Set to a positive integer (1 and above) to enable the auto purging. + </description> + </property> + <property> + <name>4lw.commands.whitelist</name> + <value>ruok</value> + <description> + A list of comma separated Four Letter Words commands that user wants to use. + A valid Four Letter Words command must be put in this list else ZooKeeper server will not enable the + command. + By default the whitelist only contains "srvr" command which zkServer.sh uses. + The rest of four letter word commands are disabled by default. + </description> + </property> + <property> + <name>admin.enableServer</name> + <value>true</value> + <description>Set to "false" to disable the AdminServer. By default the AdminServer is enabled.</description> + </property> + <property> + <name>admin.serverPort</name> + <value>9393</value> + <description>The port the embedded Jetty server listens on. Defaults to 8080.</description> + </property> + <property> + <name>content</name> + <description>The port the embedded Jetty server listens on. Defaults to 8080.</description> + <value><![CDATA[ +<#compress> +<#list model as key,value> + <#if value??> + <#if value?string == 'true'> + ${key}=true + <#elseif value?string == 'false'> + ${key}=false + <#else> + ${key}=${value} + </#if> + </#if> +</#list> +</#compress> + +<#noparse> +<#if zk_server_str?? > +${zk_server_str} +</#if> + +<#if security_enabled?? && security_enabled > +authProvider.1=org.apache.zookeeper.server.auth.SASLAuthenticationProvider +jaasLoginRenew=3600000 +kerberos.removeHostFromPrincipal=true +kerberos.removeRealmFromPrincipal=true +</#if> +</#noparse> +]]> + </value> + <attrs> + <type>longtext</type> + </attrs> + </property> +</configuration> diff --git a/bigtop-manager-server/src/test/resources/stacks/bigtop/3.3.0/services/zookeeper/configuration/zookeeper-env.xml b/bigtop-manager-server/src/test/resources/stacks/bigtop/3.3.0/services/zookeeper/configuration/zookeeper-env.xml new file mode 100644 index 00000000..a947ff69 --- /dev/null +++ b/bigtop-manager-server/src/test/resources/stacks/bigtop/3.3.0/services/zookeeper/configuration/zookeeper-env.xml @@ -0,0 +1,58 @@ +<?xml version="1.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. +--> + +<configuration> + <property> + <name>zookeeper_log_dir</name> + <value>/var/log/zookeeper</value> + <display-name>ZooKeeper Log Dir</display-name> + <description>ZooKeeper Log Dir</description> + </property> + <property> + <name>zookeeper_pid_dir</name> + <value>/var/run/zookeeper</value> + <display-name>ZooKeeper PID Dir</display-name> + <description>ZooKeeper Pid Dir</description> + </property> + <!-- zookeeper-env.sh --> + <property> + <name>content</name> + <display-name>zookeeper-env template</display-name> + <description>This is the freemarker template for zookeeper-env.sh file</description> + <value><![CDATA[ +export JAVA_HOME=${java_home!} +export ZOOKEEPER_HOME=${zookeeper_home!} +export ZOO_LOG_DIR=${zookeeper_log_dir!} +export ZOOPIDFILE=${zookeeper_pid_file!} +export SERVER_JVMFLAGS=${SERVER_JVMFLAGS!} +<#noparse>export JAVA=${JAVA_HOME}/bin/java</#noparse> +export CLASSPATH=$CLASSPATH:/usr/share/zookeeper/* + +<#if securityEnabled?? && securityEnabled > +export SERVER_JVMFLAGS="$SERVER_JVMFLAGS -Djava.security.auth.login.config=${zk_server_jaas_file!}" +export CLIENT_JVMFLAGS="$CLIENT_JVMFLAGS -Djava.security.auth.login.config=${zk_client_jaas_file!} -Dzookeeper.sasl.client.username=${zk_principal_user!}" +</#if> +]]> + </value> + <attrs> + <type>longtext</type> + </attrs> + </property> +</configuration> diff --git a/bigtop-manager-server/src/test/resources/stacks/bigtop/3.3.0/services/zookeeper/metainfo.xml b/bigtop-manager-server/src/test/resources/stacks/bigtop/3.3.0/services/zookeeper/metainfo.xml new file mode 100644 index 00000000..913b576c --- /dev/null +++ b/bigtop-manager-server/src/test/resources/stacks/bigtop/3.3.0/services/zookeeper/metainfo.xml @@ -0,0 +1,64 @@ +<?xml version="1.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 + ~ + ~ https://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. +--> + +<metainfo> + <service> + <name>zookeeper</name> + <display-name>ZooKeeper</display-name> + <desc> + Apache ZooKeeper is an effort to develop and maintain an open-source server which enables highly + reliable distributed coordination. + </desc> + <version>3.7.2-1</version> + <user>zookeeper</user> + <license>Apache-2.0</license> + + <components> + <component> + <name>zookeeper_server</name> + <display-name>ZooKeeper Server</display-name> + <category>server</category> + <cardinality>1+</cardinality> + </component> + + <component> + <name>zookeeper_client</name> + <display-name>ZooKeeper Client</display-name> + <category>client</category> + <cardinality>1+</cardinality> + </component> + </components> + + <package-specifics> + <package-specific> + <architectures> + <arch>x86_64</arch> + <arch>aarch64</arch> + </architectures> + <packages> + <package> + <name>zookeeper-3.7.2-1.tar.gz</name> + <checksum>SHA-256:83e07f914eb3477c77245f4dc44031b82ea6ef1be3691687f469ddc4b8c720bb</checksum> + </package> + </packages> + </package-specific> + </package-specifics> + </service> +</metainfo> \ No newline at end of file diff --git a/bigtop-manager-server/src/test/resources/stacks/bigtop/3.3.0/services/zookeeper/order.json b/bigtop-manager-server/src/test/resources/stacks/bigtop/3.3.0/services/zookeeper/order.json new file mode 100644 index 00000000..0da47175 --- /dev/null +++ b/bigtop-manager-server/src/test/resources/stacks/bigtop/3.3.0/services/zookeeper/order.json @@ -0,0 +1,5 @@ +{ + "ZOOKEEPER_SERVER-STOP": [ + "KAFKA_BROKER-STOP" + ] +} \ No newline at end of file