/* * Copyright 2016-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.glowroot.central.repo; import java.util.List; import java.util.UUID; import com.datastax.driver.core.Cluster; import com.datastax.driver.core.KeyspaceMetadata; import com.datastax.driver.core.Session; import com.google.common.collect.ImmutableList; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; import org.glowroot.central.util.ClusterManager; import org.glowroot.central.util.Sessions; import org.glowroot.common.config.CentralStorageConfig; import org.glowroot.common.config.CentralWebConfig; import org.glowroot.common.config.ImmutableCentralStorageConfig; import org.glowroot.common.config.ImmutableCentralWebConfig; import org.glowroot.common.config.ImmutableLdapConfig; import org.glowroot.common.config.ImmutableRoleConfig; import org.glowroot.common.config.ImmutableSmtpConfig; import org.glowroot.common.config.ImmutableUserConfig; import org.glowroot.common.config.LdapConfig; import org.glowroot.common.config.RoleConfig; import org.glowroot.common.config.SmtpConfig; import org.glowroot.common.config.UserConfig; import org.glowroot.common.repo.ConfigRepository; import org.glowroot.common.util.Versions; import org.glowroot.wire.api.model.AgentConfigOuterClass.AgentConfig; import org.glowroot.wire.api.model.AgentConfigOuterClass.AgentConfig.AdvancedConfig; import org.glowroot.wire.api.model.AgentConfigOuterClass.AgentConfig.AlertConfig; import org.glowroot.wire.api.model.AgentConfigOuterClass.AgentConfig.AlertConfig.AlertKind; import org.glowroot.wire.api.model.AgentConfigOuterClass.AgentConfig.GaugeConfig; import org.glowroot.wire.api.model.AgentConfigOuterClass.AgentConfig.InstrumentationConfig; import org.glowroot.wire.api.model.AgentConfigOuterClass.AgentConfig.InstrumentationConfig.CaptureKind; import org.glowroot.wire.api.model.AgentConfigOuterClass.AgentConfig.InstrumentationConfig.MethodModifier; import org.glowroot.wire.api.model.AgentConfigOuterClass.AgentConfig.MBeanAttribute; import org.glowroot.wire.api.model.AgentConfigOuterClass.AgentConfig.TransactionConfig; import org.glowroot.wire.api.model.AgentConfigOuterClass.AgentConfig.UiConfig; import org.glowroot.wire.api.model.AgentConfigOuterClass.AgentConfig.UserRecordingConfig; import org.glowroot.wire.api.model.Proto.OptionalDouble; import org.glowroot.wire.api.model.Proto.OptionalInt32; import static org.assertj.core.api.Assertions.assertThat; public class ConfigRepositoryIT { private static Cluster cluster; private static Session session; private static ClusterManager clusterManager; private static ConfigRepository configRepository; private static ConfigDao configDao; @BeforeClass public static void setUp() throws Exception { SharedSetupRunListener.startCassandra(); cluster = Clusters.newCluster(); session = cluster.newSession(); Sessions.createKeyspaceIfNotExists(session, "glowroot_unit_tests"); session.execute("use glowroot_unit_tests"); KeyspaceMetadata keyspace = cluster.getMetadata().getKeyspace("glowroot_unit_tests"); session.execute("drop table if exists agent"); session.execute("drop table if exists agent_rollup"); session.execute("drop table if exists user"); session.execute("drop table if exists role"); session.execute("drop table if exists central_config"); clusterManager = ClusterManager.create(); configDao = new ConfigDao(session, clusterManager); AgentDao agentDao = new AgentDao(session, clusterManager); CentralConfigDao centralConfigDao = new CentralConfigDao(session, clusterManager); UserDao userDao = new UserDao(session, keyspace, clusterManager); RoleDao roleDao = new RoleDao(session, keyspace, clusterManager); configRepository = new ConfigRepositoryImpl(agentDao, configDao, centralConfigDao, userDao, roleDao, ""); } @AfterClass public static void tearDown() throws Exception { clusterManager.close(); // remove bad data so other tests don't have issue session.execute("drop table agent_rollup"); session.execute("drop table config"); session.execute("drop table user"); session.execute("drop table role"); session.execute("drop table central_config"); session.close(); cluster.close(); SharedSetupRunListener.stopCassandra(); } @Test public void shouldReadConfigForNonExistentAgentId() throws Exception { String agentId = UUID.randomUUID().toString(); assertThat(configRepository.getGaugeConfigs(agentId)).isEmpty(); boolean exception = false; try { configRepository.getGaugeConfig(agentId, "dummy"); } catch (IllegalStateException e) { exception = true; } assertThat(exception).isTrue(); assertThat(configRepository.getAlertConfigs(agentId)).isEmpty(); exception = false; try { configRepository.getAlertConfig(agentId, "dummy"); } catch (IllegalStateException e) { exception = true; } assertThat(exception).isTrue(); assertThat(configRepository.getPluginConfigs(agentId)).isEmpty(); exception = false; try { configRepository.getPluginConfig(agentId, "dummy"); } catch (IllegalStateException e) { exception = true; } assertThat(exception).isTrue(); assertThat(configRepository.getInstrumentationConfigs(agentId)).isEmpty(); exception = false; try { configRepository.getInstrumentationConfig(agentId, "dummy"); } catch (IllegalStateException e) { exception = true; } assertThat(exception).isTrue(); } @Test public void shouldUpdateTransactionConfig() throws Exception { // given String agentId = UUID.randomUUID().toString(); configDao.store(agentId, null, AgentConfig.getDefaultInstance()); TransactionConfig config = configRepository.getTransactionConfig(agentId); TransactionConfig updatedConfig = TransactionConfig.newBuilder() .setSlowThresholdMillis(OptionalInt32.newBuilder().setValue(1234)) .setProfilingIntervalMillis(OptionalInt32.newBuilder().setValue(2345)) .setCaptureThreadStats(true) .build(); // when configRepository.updateTransactionConfig(agentId, updatedConfig, Versions.getVersion(config)); config = configRepository.getTransactionConfig(agentId); // then assertThat(config).isEqualTo(updatedConfig); } @Test public void shouldUpdateUiConfig() throws Exception { // given String agentId = UUID.randomUUID().toString(); configDao.store(agentId, null, AgentConfig.getDefaultInstance()); UiConfig config = configRepository.getUiConfig(agentId); UiConfig updatedConfig = UiConfig.newBuilder() .setDefaultDisplayedTransactionType("xyz") .addDefaultDisplayedPercentile(99.0) .addDefaultDisplayedPercentile(99.9) .addDefaultDisplayedPercentile(99.99) .build(); // when configRepository.updateUiConfig(agentId, updatedConfig, Versions.getVersion(config)); config = configRepository.getUiConfig(agentId); // then assertThat(config).isEqualTo(updatedConfig); } @Test public void shouldUpdateUserRecordingConfig() throws Exception { // given String agentId = UUID.randomUUID().toString(); configDao.store(agentId, null, AgentConfig.getDefaultInstance()); UserRecordingConfig config = configRepository.getUserRecordingConfig(agentId); UserRecordingConfig updatedConfig = UserRecordingConfig.newBuilder() .addUser("x") .addUser("y") .addUser("z") .setProfilingIntervalMillis(OptionalInt32.newBuilder().setValue(1234)) .build(); // when configRepository.updateUserRecordingConfig(agentId, updatedConfig, Versions.getVersion(config)); config = configRepository.getUserRecordingConfig(agentId); // then assertThat(config).isEqualTo(updatedConfig); } @Test public void shouldUpdateAdvancedConfig() throws Exception { // given String agentId = UUID.randomUUID().toString(); configDao.store(agentId, null, AgentConfig.getDefaultInstance()); AdvancedConfig config = configRepository.getAdvancedConfig(agentId); AdvancedConfig updatedConfig = AdvancedConfig.newBuilder() .setWeavingTimer(true) .setImmediatePartialStoreThresholdSeconds(OptionalInt32.newBuilder().setValue(1)) .setMaxAggregateTransactionsPerType(OptionalInt32.newBuilder().setValue(2)) .setMaxAggregateQueriesPerType(OptionalInt32.newBuilder().setValue(3)) .setMaxAggregateServiceCallsPerType(OptionalInt32.newBuilder().setValue(4)) .setMaxTraceEntriesPerTransaction(OptionalInt32.newBuilder().setValue(5)) .setMaxStackTraceSamplesPerTransaction(OptionalInt32.newBuilder().setValue(6)) .setMbeanGaugeNotFoundDelaySeconds(OptionalInt32.newBuilder().setValue(7)) .build(); // when configRepository.updateAdvancedConfig(agentId, updatedConfig, Versions.getVersion(config)); config = configRepository.getAdvancedConfig(agentId); // then assertThat(config).isEqualTo(updatedConfig); } @Test public void shouldCrudGaugeConfig() throws Exception { // given String agentId = UUID.randomUUID().toString(); configDao.store(agentId, null, AgentConfig.getDefaultInstance()); GaugeConfig gaugeConfig = GaugeConfig.newBuilder() .setMbeanObjectName("x") .addMbeanAttribute(MBeanAttribute.newBuilder() .setName("y") .setCounter(true)) .build(); // when configRepository.insertGaugeConfig(agentId, gaugeConfig); List<GaugeConfig> gaugeConfigs = configRepository.getGaugeConfigs(agentId); // then assertThat(gaugeConfigs).hasSize(1); assertThat(gaugeConfigs.get(0)).isEqualTo(gaugeConfig); // and further // given GaugeConfig updatedGaugeConfig = GaugeConfig.newBuilder() .setMbeanObjectName("x2") .addMbeanAttribute(MBeanAttribute.newBuilder() .setName("y2")) .build(); // when configRepository.updateGaugeConfig(agentId, updatedGaugeConfig, Versions.getVersion(gaugeConfig)); gaugeConfigs = configRepository.getGaugeConfigs(agentId); // then assertThat(gaugeConfigs).hasSize(1); assertThat(gaugeConfigs.get(0)).isEqualTo(updatedGaugeConfig); // and further // when configRepository.deleteGaugeConfig(agentId, Versions.getVersion(updatedGaugeConfig)); gaugeConfigs = configRepository.getGaugeConfigs(agentId); // then assertThat(gaugeConfigs).isEmpty(); } @Test public void shouldCrudAlertConfig() throws Exception { // given String agentId = UUID.randomUUID().toString(); configDao.store(agentId, null, AgentConfig.getDefaultInstance()); AlertConfig alertConfig = AlertConfig.newBuilder() .setKind(AlertKind.GAUGE) .setGaugeName("abc") .setGaugeThreshold(OptionalDouble.newBuilder().setValue(111)) .setTimePeriodSeconds(60) .addEmailAddress("noone@example.org") .build(); // when configRepository.insertAlertConfig(agentId, alertConfig); List<AlertConfig> alertConfigs = configRepository.getAlertConfigs(agentId); // then assertThat(alertConfigs).hasSize(1); assertThat(alertConfigs.get(0)).isEqualTo(alertConfig); // and further // given AlertConfig updatedAlertConfig = alertConfig.toBuilder() .setGaugeName("abc2") .setGaugeThreshold(OptionalDouble.newBuilder().setValue(222)) .setTimePeriodSeconds(62) .addEmailAddress("noone2@example.org") .build(); // when configRepository.updateAlertConfig(agentId, updatedAlertConfig, Versions.getVersion(alertConfig)); alertConfigs = configRepository.getAlertConfigs(agentId); // then assertThat(alertConfigs).hasSize(1); assertThat(alertConfigs.get(0)).isEqualTo(updatedAlertConfig); // and further // when configRepository.deleteAlertConfig(agentId, Versions.getVersion(updatedAlertConfig)); alertConfigs = configRepository.getAlertConfigs(agentId); // then assertThat(alertConfigs).isEmpty(); } @Test public void shouldCrudInstrumentationConfig() throws Exception { // given String agentId = UUID.randomUUID().toString(); configDao.store(agentId, null, AgentConfig.getDefaultInstance()); InstrumentationConfig instrumentationConfig = InstrumentationConfig.newBuilder() .setClassName("a") .setMethodName("b") .setMethodReturnType("c") .addMethodModifier(MethodModifier.PUBLIC) .setCaptureKind(CaptureKind.TRACE_ENTRY) .setTimerName("d") .setTraceEntryMessageTemplate("e") .setTraceEntryStackThresholdMillis(OptionalInt32.newBuilder().setValue(1)) .setTransactionType("f") .setTransactionNameTemplate("g") .setTransactionSlowThresholdMillis(OptionalInt32.newBuilder().setValue(2)) .build(); // when configRepository.insertInstrumentationConfig(agentId, instrumentationConfig); List<InstrumentationConfig> instrumentationConfigs = configRepository.getInstrumentationConfigs(agentId); // then assertThat(instrumentationConfigs).hasSize(1); assertThat(instrumentationConfigs.get(0)).isEqualTo(instrumentationConfig); // and further // given InstrumentationConfig updatedInstrumentationConfig = InstrumentationConfig.newBuilder() .setClassName("a2") .setMethodName("b2") .setMethodReturnType("c2") .addMethodModifier(MethodModifier.PUBLIC) .setCaptureKind(CaptureKind.TRACE_ENTRY) .setTimerName("d2") .setTraceEntryMessageTemplate("e2") .setTraceEntryStackThresholdMillis(OptionalInt32.newBuilder().setValue(12)) .setTransactionType("f2") .setTransactionNameTemplate("g2") .setTransactionSlowThresholdMillis(OptionalInt32.newBuilder().setValue(22)) .build(); // when configRepository.updateInstrumentationConfig(agentId, updatedInstrumentationConfig, Versions.getVersion(instrumentationConfig)); instrumentationConfigs = configRepository.getInstrumentationConfigs(agentId); // then assertThat(instrumentationConfigs).hasSize(1); assertThat(instrumentationConfigs.get(0)).isEqualTo(updatedInstrumentationConfig); // and further // when configRepository.deleteInstrumentationConfigs(agentId, ImmutableList.of(Versions.getVersion(updatedInstrumentationConfig))); instrumentationConfigs = configRepository.getInstrumentationConfigs(agentId); // then assertThat(instrumentationConfigs).isEmpty(); } @Test public void shouldCrudUserConfig() throws Exception { // given UserConfig userConfig = ImmutableUserConfig.builder() .username("auser") .addRoles("brole") .build(); // when configRepository.insertUserConfig(userConfig); List<UserConfig> userConfigs = configRepository.getUserConfigs(); // then assertThat(userConfigs).hasSize(2); assertThat(userConfigs.get(1)).isEqualTo(userConfig); // and further // given String username = "auser"; // when UserConfig readUserConfig = configRepository.getUserConfig(username); // then assertThat(readUserConfig).isNotNull(); // and further // given UserConfig updatedUserConfig = ImmutableUserConfig.builder() .username("auser") .addRoles("brole2") .build(); // when configRepository.updateUserConfig(updatedUserConfig, userConfig.version()); userConfigs = configRepository.getUserConfigs(); // then assertThat(userConfigs).hasSize(2); assertThat(userConfigs.get(1)).isEqualTo(updatedUserConfig); // and further // when configRepository.deleteUserConfig(updatedUserConfig.username()); userConfigs = configRepository.getUserConfigs(); // then assertThat(userConfigs).hasSize(1); assertThat(userConfigs.get(0).username()).isEqualTo("anonymous"); } @Test public void shouldCrudRoleConfig() throws Exception { // given RoleConfig roleConfig = ImmutableRoleConfig.builder() .central(true) .name("brole") .addPermissions("p1") .addPermissions("p2") .build(); // when configRepository.insertRoleConfig(roleConfig); List<RoleConfig> roleConfigs = configRepository.getRoleConfigs(); // then assertThat(roleConfigs).hasSize(2); assertThat(roleConfigs.get(1)).isEqualTo(roleConfig); // and further // given RoleConfig updatedRoleConfig = ImmutableRoleConfig.builder() .central(true) .name("brole") .addPermissions("p5") .addPermissions("p6") .addPermissions("p7") .build(); // when configRepository.updateRoleConfig(updatedRoleConfig, roleConfig.version()); roleConfigs = configRepository.getRoleConfigs(); // then assertThat(roleConfigs).hasSize(2); assertThat(roleConfigs.get(1)).isEqualTo(updatedRoleConfig); // and further // when configRepository.deleteRoleConfig(updatedRoleConfig.name()); roleConfigs = configRepository.getRoleConfigs(); // then assertThat(roleConfigs).hasSize(1); assertThat(roleConfigs.get(0).name()).isEqualTo("Administrator"); } @Test public void shouldUpdateWebConfig() throws Exception { // given CentralWebConfig config = configRepository.getCentralWebConfig(); CentralWebConfig updatedConfig = ImmutableCentralWebConfig.builder() .sessionTimeoutMinutes(31) .sessionCookieName("GLOWROOT_SESSION_ID2") .build(); // when configRepository.updateCentralWebConfig(updatedConfig, config.version()); config = configRepository.getCentralWebConfig(); // then assertThat(config).isEqualTo(updatedConfig); } @Test public void shouldUpdateCentralStorageConfig() throws Exception { // given CentralStorageConfig config = configRepository.getCentralStorageConfig(); CentralStorageConfig updatedConfig = ImmutableCentralStorageConfig.builder() .addRollupExpirationHours(1) .addRollupExpirationHours(2) .addRollupExpirationHours(3) .addRollupExpirationHours(4) .traceExpirationHours(100) .fullQueryTextExpirationHours(100) .build(); // when configRepository.updateCentralStorageConfig(updatedConfig, config.version()); config = configRepository.getCentralStorageConfig(); // then assertThat(config).isEqualTo(updatedConfig); } @Test public void shouldUpdateSmtpConfig() throws Exception { // given SmtpConfig config = configRepository.getSmtpConfig(); SmtpConfig updatedConfig = ImmutableSmtpConfig.builder() .host("a") .port(555) .ssl(true) .username("b") .password("c") .putAdditionalProperties("f", "g") .putAdditionalProperties("h", "i") .fromEmailAddress("d") .fromDisplayName("e") .build(); // when configRepository.updateSmtpConfig(updatedConfig, config.version()); config = configRepository.getSmtpConfig(); // then assertThat(config).isEqualTo(updatedConfig); } @Test public void shouldUpdateLdapConfig() throws Exception { // given LdapConfig config = configRepository.getLdapConfig(); LdapConfig updatedConfig = ImmutableLdapConfig.builder() .host("a") .port(1234) .username("b") .password("c") .userBaseDn("d") .userSearchFilter("e") .groupBaseDn("f") .groupSearchFilter("g") .build(); // when configRepository.updateLdapConfig(updatedConfig, config.version()); config = configRepository.getLdapConfig(); // then assertThat(config).isEqualTo(updatedConfig); } }