blob: dcdd41db33d68e0a1d5c0a5ab48380a463fa8e50 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.metron.rest.service.impl;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import java.nio.charset.StandardCharsets;
import org.adrianwalker.multilinestring.Multiline;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.api.DeleteBuilder;
import org.apache.curator.framework.api.GetChildrenBuilder;
import org.apache.curator.framework.api.GetDataBuilder;
import org.apache.curator.framework.api.SetDataBuilder;
import org.apache.metron.common.configuration.ConfigurationType;
import org.apache.metron.common.configuration.IndexingConfigurations;
import org.apache.metron.common.configuration.ParserConfigurations;
import org.apache.metron.common.utils.JSONUtils;
import org.apache.metron.common.zookeeper.ConfigurationsCache;
import org.apache.metron.rest.RestException;
import org.apache.metron.rest.service.SensorIndexingConfigService;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.data.Stat;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Collections;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@SuppressWarnings("ALL")
public class SensorIndexingConfigServiceImplTest {
@Rule
public final ExpectedException exception = ExpectedException.none();
ObjectMapper objectMapper;
CuratorFramework curatorFramework;
SensorIndexingConfigService sensorIndexingConfigService;
ConfigurationsCache cache;
/**
{
"hdfs" : {
"index": "bro",
"batchSize": 5,
"enabled" : true
}
}
*/
@Multiline
public static String broJson;
@Before
public void setUp() throws Exception {
objectMapper = mock(ObjectMapper.class);
curatorFramework = mock(CuratorFramework.class);
cache = mock(ConfigurationsCache.class);
sensorIndexingConfigService = new SensorIndexingConfigServiceImpl(objectMapper, curatorFramework, cache);
}
@Test
public void deleteShouldProperlyCatchNoNodeExceptionAndReturnFalse() throws Exception {
DeleteBuilder builder = mock(DeleteBuilder.class);
when(curatorFramework.delete()).thenReturn(builder);
when(builder.forPath(ConfigurationType.INDEXING.getZookeeperRoot() + "/bro")).thenThrow(KeeperException.NoNodeException.class);
assertFalse(sensorIndexingConfigService.delete("bro"));
}
@Test
public void deleteShouldProperlyCatchNonNoNodeExceptionAndThrowRestException() throws Exception {
exception.expect(RestException.class);
DeleteBuilder builder = mock(DeleteBuilder.class);
when(curatorFramework.delete()).thenReturn(builder);
when(builder.forPath(ConfigurationType.INDEXING.getZookeeperRoot() + "/bro")).thenThrow(Exception.class);
assertFalse(sensorIndexingConfigService.delete("bro"));
}
@Test
public void deleteShouldReturnTrueWhenClientSuccessfullyCallsDelete() throws Exception {
DeleteBuilder builder = mock(DeleteBuilder.class);
when(curatorFramework.delete()).thenReturn(builder);
when(builder.forPath(ConfigurationType.INDEXING.getZookeeperRoot() + "/bro")).thenReturn(null);
assertTrue(sensorIndexingConfigService.delete("bro"));
verify(curatorFramework).delete();
}
@Test
public void findOneShouldProperlyReturnSensorEnrichmentConfig() throws Exception {
final Map<String, Object> sensorIndexingConfig = getTestSensorIndexingConfig();
IndexingConfigurations configs = new IndexingConfigurations(){
@Override
public Map<String, Object> getConfigurations() {
return ImmutableMap.of(IndexingConfigurations.getKey("bro"), sensorIndexingConfig);
}
};
when(cache.get( eq(IndexingConfigurations.class)))
.thenReturn(configs);
//We only have bro, so we should expect it to be returned
assertEquals(getTestSensorIndexingConfig(), sensorIndexingConfigService.findOne("bro"));
//and blah should be a miss.
assertNull(sensorIndexingConfigService.findOne("blah"));
}
@Test
public void getAllIndicesWithOnlyParsers() throws RestException {
ParserConfigurations parserConfiguration = mock(ParserConfigurations.class);
when(parserConfiguration.getTypes()).thenReturn(ImmutableList.of("bro", "snort"));
IndexingConfigurations indexingConfiguration = mock(IndexingConfigurations.class);
when(indexingConfiguration.getTypes()).thenReturn(Collections.emptyList());
when(indexingConfiguration.getIndex(eq("bro"), eq("elasticsearch"))).thenReturn(null);
when(indexingConfiguration.getIndex(eq("snort"), eq("elasticsearch"))).thenReturn(null);
when(indexingConfiguration.isEnabled(eq("snort"), eq("elasticsearch"))).thenReturn(true);
when(indexingConfiguration.isEnabled(eq("bro"), eq("elasticsearch"))).thenReturn(true);
when(cache.get(eq(ParserConfigurations.class))).thenReturn(parserConfiguration);
when(cache.get(eq(IndexingConfigurations.class))).thenReturn(indexingConfiguration);
List<String> indices = new ArrayList<String>();
Iterables.addAll(indices, sensorIndexingConfigService.getAllIndices("elasticsearch"));
Assert.assertEquals(2, indices.size());
Assert.assertTrue(indices.contains("bro"));
Assert.assertTrue(indices.contains("snort"));
}
@Test
public void getAllIndicesWithOnlyIndexing() throws RestException {
ParserConfigurations parserConfiguration = mock(ParserConfigurations.class);
when(parserConfiguration.getTypes()).thenReturn(Collections.emptyList());
IndexingConfigurations indexingConfiguration = mock(IndexingConfigurations.class);
// rename bro, include snort by default configs, and disable yaf
when(indexingConfiguration.getTypes()).thenReturn(ImmutableList.of("bro", "snort", "yaf"));
when(indexingConfiguration.getIndex(eq("bro"), eq("elasticsearch"))).thenReturn("renamed_bro");
when(indexingConfiguration.getIndex(eq("snort"), eq("elasticsearch"))).thenReturn(null);
when(indexingConfiguration.isEnabled(eq("snort"), eq("elasticsearch"))).thenReturn(true);
when(indexingConfiguration.isEnabled(eq("bro"), eq("elasticsearch"))).thenReturn(true);
when(indexingConfiguration.isEnabled(eq("yaf"), eq("elasticsearch"))).thenReturn(false);
when(cache.get(eq(ParserConfigurations.class))).thenReturn(parserConfiguration);
when(cache.get(eq(IndexingConfigurations.class))).thenReturn(indexingConfiguration);
List<String> indices = new ArrayList<String>();
Iterables.addAll(indices, sensorIndexingConfigService.getAllIndices("elasticsearch"));
Assert.assertEquals(2, indices.size());
Assert.assertTrue(indices.contains("renamed_bro"));
Assert.assertTrue(indices.contains("snort"));
}
@Test
public void getAllIndicesWithParsersAndIndexConfigs() throws RestException {
ParserConfigurations parserConfiguration = mock(ParserConfigurations.class);
when(parserConfiguration.getTypes()).thenReturn(ImmutableList.of("bro", "yaf"));
IndexingConfigurations indexingConfiguration = mock(IndexingConfigurations.class);
when(indexingConfiguration.getTypes()).thenReturn(ImmutableList.of("bro", "snort", "squid"));
when(indexingConfiguration.getIndex(eq("bro"), eq("elasticsearch"))).thenReturn("renamed_bro");
when(indexingConfiguration.getIndex(eq("snort"), eq("elasticsearch"))).thenReturn("snort");
when(indexingConfiguration.getIndex(eq("yaf"), eq("elasticsearch"))).thenReturn(null);
when(indexingConfiguration.isEnabled(eq("snort"), eq("elasticsearch"))).thenReturn(true);
when(indexingConfiguration.isEnabled(eq("bro"), eq("elasticsearch"))).thenReturn(true);
when(indexingConfiguration.isEnabled(eq("yaf"), eq("elasticsearch"))).thenReturn(true);
when(indexingConfiguration.isEnabled(eq("squid"), eq("elasticsearch"))).thenReturn(false);
when(cache.get(eq(ParserConfigurations.class))).thenReturn(parserConfiguration);
when(cache.get(eq(IndexingConfigurations.class))).thenReturn(indexingConfiguration);
List<String> indices = new ArrayList<String>();
Iterables.addAll(indices, sensorIndexingConfigService.getAllIndices("elasticsearch"));
Assert.assertEquals(3, indices.size());
Assert.assertTrue(indices.contains("renamed_bro"));
Assert.assertTrue(indices.contains("snort"));
Assert.assertTrue(indices.contains("yaf"));
}
@Test
public void getAllIndicesWithNoConfigs() throws RestException {
ParserConfigurations parserConfiguration = mock(ParserConfigurations.class);
when(parserConfiguration.getTypes()).thenReturn(Collections.emptyList());
IndexingConfigurations indexingConfiguration = mock(IndexingConfigurations.class);
when(indexingConfiguration.getTypes()).thenReturn(Collections.emptyList());
when(cache.get(eq(ParserConfigurations.class))).thenReturn(parserConfiguration);
when(cache.get(eq(IndexingConfigurations.class))).thenReturn(indexingConfiguration);
List<String> indices = new ArrayList<String>();
Iterables.addAll(indices, sensorIndexingConfigService.getAllIndices("elasticsearch"));
Assert.assertEquals(0, indices.size());
}
@Test
public void getAllTypesShouldProperlyReturnTypes() throws Exception {
IndexingConfigurations configs = new IndexingConfigurations(){
@Override
public Map<String, Object> getConfigurations() {
return ImmutableMap.of(IndexingConfigurations.getKey("bro"), new HashMap<>()
,IndexingConfigurations.getKey("squid"), new HashMap<>()
);
}
};
when(cache.get(eq(IndexingConfigurations.class)))
.thenReturn(configs);
assertEquals(new ArrayList() {{
add("bro");
add("squid");
}}, sensorIndexingConfigService.getAllTypes());
}
@Test
public void getAllShouldProperlyReturnIndexingConfigs() throws Exception {
final Map<String, Object> sensorIndexingConfig = getTestSensorIndexingConfig();
IndexingConfigurations configs = new IndexingConfigurations(){
@Override
public Map<String, Object> getConfigurations() {
return ImmutableMap.of(IndexingConfigurations.getKey("bro"), sensorIndexingConfig );
}
};
when(cache.get(eq(IndexingConfigurations.class)))
.thenReturn(configs);
assertEquals(new HashMap() {{ put("bro", sensorIndexingConfig);}}, sensorIndexingConfigService.getAll());
}
@Test
public void saveShouldWrapExceptionInRestException() throws Exception {
exception.expect(RestException.class);
SetDataBuilder setDataBuilder = mock(SetDataBuilder.class);
when(setDataBuilder.forPath(ConfigurationType.INDEXING.getZookeeperRoot() + "/bro", broJson.getBytes(
StandardCharsets.UTF_8))).thenThrow(Exception.class);
when(curatorFramework.setData()).thenReturn(setDataBuilder);
sensorIndexingConfigService.save("bro", new HashMap<>());
}
@Test
public void saveShouldReturnSameConfigThatIsPassedOnSuccessfulSave() throws Exception {
final Map<String, Object> sensorIndexingConfig = getTestSensorIndexingConfig();
when(objectMapper.writeValueAsString(sensorIndexingConfig)).thenReturn(broJson);
SetDataBuilder setDataBuilder = mock(SetDataBuilder.class);
when(setDataBuilder.forPath(ConfigurationType.INDEXING.getZookeeperRoot() + "/bro", broJson.getBytes(StandardCharsets.UTF_8))).thenReturn(new Stat());
when(curatorFramework.setData()).thenReturn(setDataBuilder);
assertEquals(sensorIndexingConfig, sensorIndexingConfigService.save("bro", sensorIndexingConfig));
verify(setDataBuilder).forPath(eq(ConfigurationType.INDEXING.getZookeeperRoot() + "/bro"), eq(broJson.getBytes(StandardCharsets.UTF_8)));
}
private Map<String, Object> getTestSensorIndexingConfig() {
Map<String, Object> sensorIndexingConfig = new HashMap<>();
sensorIndexingConfig.put("hdfs", new HashMap(){{
put("index", "bro");
put("batchSize", 5);
put("enabled", true);
}});
return sensorIndexingConfig;
}
}