/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hadoop.gateway.services.topology;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.monitor.FileAlterationMonitor;
import org.apache.commons.io.monitor.FileAlterationObserver;
import org.apache.hadoop.gateway.config.GatewayConfig;
import org.apache.hadoop.gateway.services.topology.impl.DefaultTopologyService;
import org.apache.hadoop.gateway.topology.*;
import org.apache.hadoop.test.TestUtils;
import org.easymock.EasyMock;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.*;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.core.IsNull.notNullValue;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
public class DefaultTopologyServiceTest {
@Before
public void setUp() throws Exception {
}
@After
public void tearDown() throws Exception {
}
private File createDir() throws IOException {
return TestUtils.createTempDir(this.getClass().getSimpleName() + "-");
}
private File createFile(File parent, String name, String resource, long timestamp) throws IOException {
File file = new File(parent, name);
if (!file.exists()) {
FileUtils.touch(file);
}
InputStream input = ClassLoader.getSystemResourceAsStream(resource);
OutputStream output = FileUtils.openOutputStream(file);
IOUtils.copy(input, output);
//KNOX-685: output.flush();
input.close();
output.close();
file.setLastModified(timestamp);
assertTrue("Failed to create test file " + file.getAbsolutePath(), file.exists());
assertTrue("Failed to populate test file " + file.getAbsolutePath(), file.length() > 0);
return file;
}
@Test
public void testGetTopologies() throws Exception {
File dir = createDir();
long time = dir.lastModified();
try {
createFile(dir, "one.xml", "org/apache/hadoop/gateway/topology/file/topology-one.xml", time);
TestTopologyListener topoListener = new TestTopologyListener();
FileAlterationMonitor monitor = new FileAlterationMonitor(Long.MAX_VALUE);
TopologyService provider = new DefaultTopologyService();
Map<String, String> c = new HashMap<String, String>();
GatewayConfig config = EasyMock.createNiceMock(GatewayConfig.class);
EasyMock.expect(config.getGatewayTopologyDir()).andReturn(dir.toString()).anyTimes();
EasyMock.replay(config);
provider.init(config, c);
provider.addTopologyChangeListener(topoListener);
provider.reloadTopologies();
Collection<Topology> topologies = provider.getTopologies();
assertThat(topologies, notNullValue());
assertThat(topologies.size(), is(1));
Topology topology = topologies.iterator().next();
assertThat(topology.getName(), is("one"));
assertThat(topology.getTimestamp(), is(time));
assertThat(topoListener.events.size(), is(1));
topoListener.events.clear();
// Add a file to the directory.
File two = createFile(dir, "two.xml", "org/apache/hadoop/gateway/topology/file/topology-two.xml", 1L);
provider.reloadTopologies();
topologies = provider.getTopologies();
assertThat(topologies.size(), is(2));
Set<String> names = new HashSet<String>(Arrays.asList("one", "two"));
Iterator<Topology> iterator = topologies.iterator();
topology = iterator.next();
assertThat(names, hasItem(topology.getName()));
names.remove(topology.getName());
topology = iterator.next();
assertThat(names, hasItem(topology.getName()));
names.remove(topology.getName());
assertThat(names.size(), is(0));
assertThat(topoListener.events.size(), is(1));
List<TopologyEvent> events = topoListener.events.get(0);
assertThat(events.size(), is(1));
TopologyEvent event = events.get(0);
assertThat(event.getType(), is(TopologyEvent.Type.CREATED));
assertThat(event.getTopology(), notNullValue());
// Update a file in the directory.
two = createFile(dir, "two.xml", "org/apache/hadoop/gateway/topology/file/topology-three.xml", 2L);
provider.reloadTopologies();
topologies = provider.getTopologies();
assertThat(topologies.size(), is(2));
names = new HashSet<String>(Arrays.asList("one", "two"));
iterator = topologies.iterator();
topology = iterator.next();
assertThat(names, hasItem(topology.getName()));
names.remove(topology.getName());
topology = iterator.next();
assertThat(names, hasItem(topology.getName()));
names.remove(topology.getName());
assertThat(names.size(), is(0));
// Remove a file from the directory.
two.delete();
provider.reloadTopologies();
topologies = provider.getTopologies();
assertThat(topologies.size(), is(1));
topology = topologies.iterator().next();
assertThat(topology.getName(), is("one"));
assertThat(topology.getTimestamp(), is(time));
} finally {
FileUtils.deleteQuietly(dir);
}
}
private void kickMonitor(FileAlterationMonitor monitor) {
for (FileAlterationObserver observer : monitor.getObservers()) {
observer.checkAndNotify();
}
}
@Test
public void testProviderParamsOrderIsPreserved() {
Provider provider = new Provider();
String names[] = {"ldapRealm=",
"ldapContextFactory",
"ldapRealm.contextFactory",
"ldapGroupRealm",
"ldapGroupRealm.contextFactory",
"ldapGroupRealm.contextFactory.systemAuthenticationMechanism"
};
Param param = null;
for (String name : names) {
param = new Param();
param.setName(name);
param.setValue(name);
provider.addParam(param);
}
Map<String, String> params = provider.getParams();
Set<String> keySet = params.keySet();
Iterator<String> iter = keySet.iterator();
int i = 0;
while (iter.hasNext()) {
assertTrue(iter.next().equals(names[i++]));
}
}
private class TestTopologyListener implements TopologyListener {
public ArrayList<List<TopologyEvent>> events = new ArrayList<List<TopologyEvent>>();
@Override
public void handleTopologyEvent(List<TopologyEvent> events) {
this.events.add(events);
}
}
}