Repository: incubator-atlas Updated Branches: refs/heads/master ad7604fcf -> ad0d764dd
ATLAS-539 Store for entity audit events (shwethags) Project: http://git-wip-us.apache.org/repos/asf/incubator-atlas/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-atlas/commit/ad0d764d Tree: http://git-wip-us.apache.org/repos/asf/incubator-atlas/tree/ad0d764d Diff: http://git-wip-us.apache.org/repos/asf/incubator-atlas/diff/ad0d764d Branch: refs/heads/master Commit: ad0d764dde83e7159a862fef4ec9d97aa0766cbb Parents: ad7604f Author: Shwetha GS <[email protected]> Authored: Wed Mar 16 14:08:55 2016 +0530 Committer: Shwetha GS <[email protected]> Committed: Wed Mar 16 14:08:55 2016 +0530 ---------------------------------------------------------------------- .../java/org/apache/atlas/service/Service.java | 2 +- .../java/org/apache/atlas/service/Services.java | 6 +- pom.xml | 33 ++- release-log.txt | 1 + repository/pom.xml | 12 + .../repository/audit/EntityAuditRepository.java | 98 ++++++++ .../audit/HBaseBasedAuditRepository.java | 244 +++++++++++++++++++ .../audit/HBaseBasedAuditRepositoryTest.java | 129 ++++++++++ .../main/resources/atlas-application.properties | 2 + webapp/pom.xml | 6 +- webapp/src/main/resources/atlas-log4j.xml | 68 ------ .../web/service/SecureEmbeddedServerTest.java | 2 +- 12 files changed, 527 insertions(+), 76 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/ad0d764d/common/src/main/java/org/apache/atlas/service/Service.java ---------------------------------------------------------------------- diff --git a/common/src/main/java/org/apache/atlas/service/Service.java b/common/src/main/java/org/apache/atlas/service/Service.java index 64ce1d6..c87a240 100644 --- a/common/src/main/java/org/apache/atlas/service/Service.java +++ b/common/src/main/java/org/apache/atlas/service/Service.java @@ -26,5 +26,5 @@ public interface Service { void start() throws AtlasException; - void stop(); + void stop() throws AtlasException; } http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/ad0d764d/common/src/main/java/org/apache/atlas/service/Services.java ---------------------------------------------------------------------- diff --git a/common/src/main/java/org/apache/atlas/service/Services.java b/common/src/main/java/org/apache/atlas/service/Services.java index 10c7e5e..8b2e205 100644 --- a/common/src/main/java/org/apache/atlas/service/Services.java +++ b/common/src/main/java/org/apache/atlas/service/Services.java @@ -52,7 +52,11 @@ public class Services { public void stop() { for (Service service : services) { LOG.debug("Stopping service {}", service.getClass().getName()); - service.stop(); + try { + service.stop(); + } catch (Throwable e) { + LOG.warn("Error stopping service {}", service.getClass().getName(), e); + } } } } http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/ad0d764d/pom.xml ---------------------------------------------------------------------- diff --git a/pom.xml b/pom.xml index 36397ea..a018529 100755 --- a/pom.xml +++ b/pom.xml @@ -880,6 +880,30 @@ </dependency> <dependency> + <groupId>org.apache.hbase</groupId> + <artifactId>hbase-server</artifactId> + <version>${hbase.version}</version> + <classifier>tests</classifier> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.apache.hbase</groupId> + <artifactId>hbase-server</artifactId> + <version>${hbase.version}</version> + <exclusions> + <exclusion> + <groupId>org.mortbay.jetty</groupId> + <artifactId>*</artifactId> + </exclusion> + <exclusion> + <groupId>tomcat</groupId> + <artifactId>*</artifactId> + </exclusion> + </exclusions> + </dependency> + + <dependency> <groupId>com.thinkaurelius.titan</groupId> <artifactId>titan-es</artifactId> <version>${titan.version}</version> @@ -1447,14 +1471,14 @@ <systemProperties> <user.dir>${project.basedir}</user.dir> <atlas.data>${project.build.directory}/data</atlas.data> + <log4j.configuration>atlas-log4j.xml</log4j.configuration> </systemProperties> <skipTests>${skipTests}</skipTests> <forkMode>always</forkMode> <redirectTestOutputToFile>true</redirectTestOutputToFile> <argLine>-Djava.awt.headless=true -Dproject.version=${project.version} -Dhadoop.tmp.dir="${project.build.directory}/tmp-hadoop-${user.name}" - -Xmx1024m -XX:MaxPermSize=512m -Dlog4j.configuration=atlas-log4j.xml - -Djava.net.preferIPv4Stack=true + -Xmx1024m -XX:MaxPermSize=512m -Djava.net.preferIPv4Stack=true </argLine> <skip>${skipUTs}</skip> <excludes> @@ -1473,16 +1497,17 @@ <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-failsafe-plugin</artifactId> - <version>2.18.1</version> + <version>2.19.1</version> <configuration> <systemPropertyVariables> <projectBaseDir>${projectBaseDir}</projectBaseDir> <atlas.data>${project.build.directory}/data</atlas.data> + <log4j.configuration>atlas-log4j.xml</log4j.configuration> </systemPropertyVariables> <redirectTestOutputToFile>true</redirectTestOutputToFile> <argLine>-Djava.awt.headless=true -Dproject.version=${project.version} -Dhadoop.tmp.dir="${project.build.directory}/tmp-hadoop-${user.name}" - -Xmx1024m -XX:MaxPermSize=512m -Dlog4j.configuration=atlas-log4j.xml + -Xmx1024m -XX:MaxPermSize=512m </argLine> <skip>${skipITs}</skip> <parallel>none</parallel> http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/ad0d764d/release-log.txt ---------------------------------------------------------------------- diff --git a/release-log.txt b/release-log.txt index 9c73da2..86e5c5d 100644 --- a/release-log.txt +++ b/release-log.txt @@ -13,6 +13,7 @@ ATLAS-409 Atlas will not import avro tables with schema read from a file (dosset ATLAS-379 Create sqoop and falcon metadata addons (venkatnrangan,bvellanki,sowmyaramesh via shwethags) ALL CHANGES: +ATLAS-539 Store for entity audit events (shwethags) ATLAS-523 Support alter view (sumasai via shwethags) ATLAS-555 Tag creation from UI fails due to missing description attribute (guptaneeru via shwethags) ATLAS-522 Support Alter table commands (sumasai via shwethags) http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/ad0d764d/repository/pom.xml ---------------------------------------------------------------------- diff --git a/repository/pom.xml b/repository/pom.xml index ffa7d97..6502bba 100755 --- a/repository/pom.xml +++ b/repository/pom.xml @@ -138,6 +138,18 @@ <groupId>org.mockito</groupId> <artifactId>mockito-all</artifactId> </dependency> + + <dependency> + <groupId>org.apache.hbase</groupId> + <artifactId>hbase-server</artifactId> + <classifier>tests</classifier> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>org.apache.hbase</groupId> + <artifactId>hbase-server</artifactId> + </dependency> </dependencies> <build> http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/ad0d764d/repository/src/main/java/org/apache/atlas/repository/audit/EntityAuditRepository.java ---------------------------------------------------------------------- diff --git a/repository/src/main/java/org/apache/atlas/repository/audit/EntityAuditRepository.java b/repository/src/main/java/org/apache/atlas/repository/audit/EntityAuditRepository.java new file mode 100644 index 0000000..a5b4a59 --- /dev/null +++ b/repository/src/main/java/org/apache/atlas/repository/audit/EntityAuditRepository.java @@ -0,0 +1,98 @@ +/** + * 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 + * <p/> + * http://www.apache.org/licenses/LICENSE-2.0 + * <p/> + * 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.atlas.repository.audit; + +import org.apache.atlas.AtlasException; +import org.apache.commons.lang.StringUtils; + +import java.util.List; + +/** + * Interface for repository for storing entity audit events + */ +public interface EntityAuditRepository { + /** + * Structure of entity audit event + */ + class EntityAuditEvent { + String entityId; + Long timestamp; + String user; + String action; + String details; + + public EntityAuditEvent() { + } + + public EntityAuditEvent(String entityId, long ts, String user, String action, String details) { + this.entityId = entityId; + this.timestamp = ts; + this.user = user; + this.action = action; + this.details = details; + } + + @Override + public boolean equals(Object other) { + if (this == other) { + return true; + } + + if (!(other instanceof EntityAuditEvent)) { + return false; + } + + EntityAuditEvent otherEvent = (EntityAuditEvent) other; + return StringUtils.equals(entityId, otherEvent.entityId) && + (timestamp.longValue() == otherEvent.timestamp.longValue()) && + StringUtils.equals(user, otherEvent.user) && StringUtils.equals(action, otherEvent.action) && + StringUtils.equals(details, otherEvent.details); + } + + @Override + public int hashCode() { + return toString().hashCode(); + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("EntityId=").append(entityId).append(";Timestamp=").append(timestamp).append(";User=") + .append(user).append(";Action=").append(action).append(";Details=").append(details); + return builder.toString(); + } + } + + /** + * Add events to the event repository + * @param events events to be added + * @throws AtlasException + */ + void putEvents(EntityAuditEvent... events) throws AtlasException; + + /** + * List events for the given entity id in decreasing order of timestamp, from the given timestamp. Returns n results + * @param entityId entity id + * @param ts starting timestamp for events + * @param n number of events to be returned + * @return list of events + * @throws AtlasException + */ + List<EntityAuditRepository.EntityAuditEvent> listEvents(String entityId, Long ts, short n) throws AtlasException; +} http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/ad0d764d/repository/src/main/java/org/apache/atlas/repository/audit/HBaseBasedAuditRepository.java ---------------------------------------------------------------------- diff --git a/repository/src/main/java/org/apache/atlas/repository/audit/HBaseBasedAuditRepository.java b/repository/src/main/java/org/apache/atlas/repository/audit/HBaseBasedAuditRepository.java new file mode 100644 index 0000000..8b92792 --- /dev/null +++ b/repository/src/main/java/org/apache/atlas/repository/audit/HBaseBasedAuditRepository.java @@ -0,0 +1,244 @@ +/** + * 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 + * <p/> + * http://www.apache.org/licenses/LICENSE-2.0 + * <p/> + * 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.atlas.repository.audit; + +import org.apache.atlas.ApplicationProperties; +import org.apache.atlas.AtlasException; +import org.apache.atlas.service.Service; +import org.apache.commons.configuration.Configuration; +import org.apache.commons.lang.StringUtils; +import org.apache.hadoop.hbase.HBaseConfiguration; +import org.apache.hadoop.hbase.HColumnDescriptor; +import org.apache.hadoop.hbase.HTableDescriptor; +import org.apache.hadoop.hbase.TableName; +import org.apache.hadoop.hbase.client.Admin; +import org.apache.hadoop.hbase.client.Connection; +import org.apache.hadoop.hbase.client.ConnectionFactory; +import org.apache.hadoop.hbase.client.Put; +import org.apache.hadoop.hbase.client.Result; +import org.apache.hadoop.hbase.client.ResultScanner; +import org.apache.hadoop.hbase.client.Scan; +import org.apache.hadoop.hbase.client.Table; +import org.apache.hadoop.hbase.filter.PageFilter; +import org.apache.hadoop.hbase.util.Bytes; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.Closeable; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * HBase based repository for entity audit events + * Table -> 1, ATLAS_ENTITY_EVENTS + * Key -> entity id + timestamp + * Column Family -> 1,dt + * Columns -> action, user, detail + * versions -> 1 + * + * Note: The timestamp in the key is assumed to be timestamp in nano seconds. Since the key is entity id + timestamp, + * and only 1 version is kept, there can be just 1 audit event per entity id + timestamp. This is ok for one atlas server. + * But if there are more than one atlas servers, we should use server id in the key + */ +public class HBaseBasedAuditRepository implements Service, EntityAuditRepository { + private static final Logger LOG = LoggerFactory.getLogger(HBaseBasedAuditRepository.class); + + public static final String CONFIG_PREFIX = "atlas.audit"; + public static final String CONFIG_TABLE_NAME = CONFIG_PREFIX + ".hbase.tablename"; + public static final String DEFAULT_TABLE_NAME = "ATLAS_ENTITY_AUDIT_EVENTS"; + + private static final String FIELD_SEPARATOR = ":"; + + public static final byte[] COLUMN_FAMILY = Bytes.toBytes("dt"); + public static final byte[] COLUMN_ACTION = Bytes.toBytes("action"); + public static final byte[] COLUMN_DETAIL = Bytes.toBytes("detail"); + public static final byte[] COLUMN_USER = Bytes.toBytes("user"); + + private TableName tableName; + private Connection connection; + + /** + * Add events to the event repository + * @param events events to be added + * @throws AtlasException + */ + public void putEvents(EntityAuditRepository.EntityAuditEvent... events) throws AtlasException { + LOG.info("Putting {} events", events.length); + Table table = null; + try { + table = connection.getTable(tableName); + List<Put> puts = new ArrayList<>(events.length); + for (EntityAuditRepository.EntityAuditEvent event : events) { + LOG.debug("Adding entity audit event {}", event); + Put put = new Put(getKey(event.entityId, event.timestamp)); + addColumn(put, COLUMN_ACTION, event.action); + addColumn(put, COLUMN_USER, event.user); + addColumn(put, COLUMN_DETAIL, event.details); + puts.add(put); + } + table.put(puts); + } catch (IOException e) { + throw new AtlasException(e); + } finally { + close(table); + } + } + + private void addColumn(Put put, byte[] columnName, String columnValue) { + if (StringUtils.isNotEmpty(columnValue)) { + put.addColumn(COLUMN_FAMILY, columnName, Bytes.toBytes(columnValue)); + } + } + + private byte[] getKey(String id, Long ts) { + assert id != null : "entity id can't be null"; + assert ts != null : "timestamp can't be null"; + String keyStr = id + FIELD_SEPARATOR + ts; + return Bytes.toBytes(keyStr); + } + + /** + * List events for the given entity id in decreasing order of timestamp, from the given timestamp. Returns n results + * @param entityId entity id + * @param ts starting timestamp for events + * @param n number of events to be returned + * @return list of events + * @throws AtlasException + */ + public List<EntityAuditRepository.EntityAuditEvent> listEvents(String entityId, Long ts, short n) + throws AtlasException { + LOG.info("Listing events for entity id {}, starting timestamp {}, #records {}", entityId, ts, n); + Table table = null; + ResultScanner scanner = null; + try { + table = connection.getTable(tableName); + Scan scan = new Scan().setReversed(true).setFilter(new PageFilter(n)) + .setStartRow(getKey(entityId, ts)) + .setStopRow(Bytes.toBytes(entityId)) + .setCaching(n) + .setSmall(true); + scanner = table.getScanner(scan); + Result result; + List<EntityAuditRepository.EntityAuditEvent> events = new ArrayList<>(); + + //PageFilter doesn't ensure n results are returned. The filter is per region server. + //So, adding extra check on n here + while ((result = scanner.next()) != null && events.size() < n) { + String key = Bytes.toString(result.getRow()); + EntityAuditRepository.EntityAuditEvent event = fromKey(key); + event.user = getResultString(result, COLUMN_USER); + event.action = getResultString(result, COLUMN_ACTION); + event.details = getResultString(result, COLUMN_DETAIL); + events.add(event); + } + LOG.info("Got events for entity id {}, starting timestamp {}, #records {}", entityId, ts, events.size()); + return events; + } catch (IOException e) { + throw new AtlasException(e); + } finally { + close(scanner); + close(table); + } + } + + private String getResultString(Result result, byte[] columnName) { + return Bytes.toString(result.getValue(COLUMN_FAMILY, columnName)); + } + + private EntityAuditEvent fromKey(String key) { + EntityAuditEvent event = new EntityAuditEvent(); + if (StringUtils.isNotEmpty(key)) { + String[] parts = key.split(FIELD_SEPARATOR); + event.entityId = parts[0]; + event.timestamp = Long.valueOf(parts[1]); + } + return event; + } + + private void close(Closeable closeable) throws AtlasException { + if (closeable != null) { + try { + closeable.close(); + } catch (IOException e) { + throw new AtlasException(e); + } + } + } + + /** + * Converts atlas' application properties to hadoop conf + * @return + * @throws AtlasException + * @param atlasConf + */ + public org.apache.hadoop.conf.Configuration getHBaseConfiguration(Configuration atlasConf) throws AtlasException { + Configuration subsetAtlasConf = + ApplicationProperties.getSubsetConfiguration(atlasConf, CONFIG_PREFIX); + org.apache.hadoop.conf.Configuration hbaseConf = HBaseConfiguration.create(); + Iterator<String> keys = subsetAtlasConf.getKeys(); + while (keys.hasNext()) { + String key = keys.next(); + hbaseConf.set(key, subsetAtlasConf.getString(key)); + } + return hbaseConf; + } + + private void createTableIfNotExists() throws AtlasException { + try { + Admin admin = connection.getAdmin(); + LOG.info("Checking if table {} exists", tableName.getNameAsString()); + if (!admin.tableExists(tableName)) { + LOG.info("Creating table {}", tableName.getNameAsString()); + HTableDescriptor tableDescriptor = new HTableDescriptor(tableName); + HColumnDescriptor columnFamily = new HColumnDescriptor(COLUMN_FAMILY); + columnFamily.setMaxVersions(1); + tableDescriptor.addFamily(columnFamily); + admin.createTable(tableDescriptor); + } else { + LOG.info("Table {} exists", tableName.getNameAsString()); + } + } catch (IOException e) { + throw new AtlasException(e); + } + } + + @Override + public void start() throws AtlasException { + Configuration atlasConf = ApplicationProperties.get(); + + String tableNameStr = atlasConf.getString(CONFIG_TABLE_NAME, DEFAULT_TABLE_NAME); + tableName = TableName.valueOf(tableNameStr); + + try { + org.apache.hadoop.conf.Configuration hbaseConf = getHBaseConfiguration(atlasConf); + connection = ConnectionFactory.createConnection(hbaseConf); + } catch (IOException e) { + throw new AtlasException(e); + } + + createTableIfNotExists(); + } + + @Override + public void stop() throws AtlasException { + close(connection); + } +} http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/ad0d764d/repository/src/test/java/org/apache/atlas/repository/audit/HBaseBasedAuditRepositoryTest.java ---------------------------------------------------------------------- diff --git a/repository/src/test/java/org/apache/atlas/repository/audit/HBaseBasedAuditRepositoryTest.java b/repository/src/test/java/org/apache/atlas/repository/audit/HBaseBasedAuditRepositoryTest.java new file mode 100644 index 0000000..ac52f29 --- /dev/null +++ b/repository/src/test/java/org/apache/atlas/repository/audit/HBaseBasedAuditRepositoryTest.java @@ -0,0 +1,129 @@ +/** + * 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 + * <p/> + * http://www.apache.org/licenses/LICENSE-2.0 + * <p/> + * 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.atlas.repository.audit; + +import org.apache.atlas.ApplicationProperties; +import org.apache.atlas.AtlasException; +import org.apache.commons.configuration.Configuration; +import org.apache.commons.lang.RandomStringUtils; +import org.apache.hadoop.hbase.HBaseTestingUtility; +import org.apache.hadoop.hbase.LocalHBaseCluster; +import org.apache.hadoop.hbase.TableName; +import org.apache.hadoop.hbase.client.Admin; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +import java.util.ArrayList; +import java.util.List; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertTrue; + +public class HBaseBasedAuditRepositoryTest { + private HBaseTestingUtility testUtility; + private HBaseBasedAuditRepository eventRepository; + private LocalHBaseCluster hbaseCluster; + private TableName tableName; + + @BeforeClass + public void setup() throws Exception { + testUtility = HBaseTestingUtility.createLocalHTU(); + testUtility.startMiniZKCluster(); + testUtility.getConfiguration().set("zookeeper.session.timeout.ms", "1000"); + hbaseCluster = new LocalHBaseCluster(testUtility.getConfiguration()); + hbaseCluster.startup(); + + eventRepository = new HBaseBasedAuditRepository() { + @Override + public org.apache.hadoop.conf.Configuration getHBaseConfiguration(Configuration atlasConf) + throws AtlasException { + return testUtility.getConfiguration(); + } + }; + eventRepository.start(); + + Configuration properties = ApplicationProperties.get(); + String tableNameStr = properties.getString(HBaseBasedAuditRepository.CONFIG_TABLE_NAME, + HBaseBasedAuditRepository.DEFAULT_TABLE_NAME); + tableName = TableName.valueOf(tableNameStr); + } + + @AfterClass + public void teardown() throws Exception { + eventRepository.stop(); + testUtility.getConnection().close(); + hbaseCluster.shutdown(); + testUtility.shutdownMiniZKCluster(); + } + + private String rand() { + return RandomStringUtils.randomAlphanumeric(10); + } + + @Test + public void testTableCreated() throws Exception { + Admin admin = testUtility.getConnection().getAdmin(); + assertTrue(admin.tableExists(tableName)); + } + + @Test + public void testAddEvents() throws Exception { + EntityAuditRepository.EntityAuditEvent event = + new EntityAuditRepository.EntityAuditEvent(rand(), System.currentTimeMillis(), "u1", "a1", "d1"); + + eventRepository.putEvents(event); + + List<EntityAuditRepository.EntityAuditEvent> events = + eventRepository.listEvents(event.entityId, System.currentTimeMillis(), (short) 10); + assertEquals(events.size(), 1); + assertEquals(events.get(0), event); + } + + @Test + public void testListPagination() throws Exception { + String id1 = "id1" + rand(); + String id2 = "id2" + rand(); + String id3 = "id3" + rand(); + long ts = System.nanoTime(); + List<EntityAuditRepository.EntityAuditEvent> expectedEvents = new ArrayList<>(3); + for (int i = 0; i < 3; i++) { + //Add events for both ids + EntityAuditRepository.EntityAuditEvent event = + new EntityAuditRepository.EntityAuditEvent(id2, ts - i, "user" + i, "action" + i, "details" + i); + eventRepository.putEvents(event); + expectedEvents.add(event); + eventRepository.putEvents(new EntityAuditRepository.EntityAuditEvent(id1, ts - i, "user" + i, + "action" + i, "details" + i)); + eventRepository.putEvents(new EntityAuditRepository.EntityAuditEvent(id3, ts - i, "user" + i, + "action" + i, "details" + i)); + } + + //Use ts for which there is no event - ts + 2 + List<EntityAuditRepository.EntityAuditEvent> events = eventRepository.listEvents(id2, ts + 2, (short) 2); + assertEquals(events.size(), 2); + assertEquals(events.get(0), expectedEvents.get(0)); + assertEquals(events.get(1), expectedEvents.get(1)); + + //Use last event's timestamp for next list(). Should give only 1 event and shouldn't include events from other id + events = eventRepository.listEvents(id2, events.get(1).timestamp - 1, (short) 3); + assertEquals(events.size(), 1); + assertEquals(events.get(0), expectedEvents.get(2)); + } +} http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/ad0d764d/typesystem/src/main/resources/atlas-application.properties ---------------------------------------------------------------------- diff --git a/typesystem/src/main/resources/atlas-application.properties b/typesystem/src/main/resources/atlas-application.properties index bb6e171..239ac95 100644 --- a/typesystem/src/main/resources/atlas-application.properties +++ b/typesystem/src/main/resources/atlas-application.properties @@ -78,3 +78,5 @@ atlas.enableTLS=false atlas.server.https.port=31443 ######### Security Properties ######### + +hbase.security.authentication=simple http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/ad0d764d/webapp/pom.xml ---------------------------------------------------------------------- diff --git a/webapp/pom.xml b/webapp/pom.xml index 3a27a60..d00cf15 100755 --- a/webapp/pom.xml +++ b/webapp/pom.xml @@ -353,7 +353,11 @@ <systemProperties> <systemProperty> <name>log4j.configuration</name> - <value>atlas-log4j.xml</value> + <value>file://${project.build.directory}/../../distro/src/conf/atlas-log4j.xml</value> + </systemProperty> + <systemProperty> + <name>atlas.log.file</name> + <value>application.log</value> </systemProperty> <systemProperty> <name>atlas.log.dir</name> http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/ad0d764d/webapp/src/main/resources/atlas-log4j.xml ---------------------------------------------------------------------- diff --git a/webapp/src/main/resources/atlas-log4j.xml b/webapp/src/main/resources/atlas-log4j.xml deleted file mode 100755 index 768b4a3..0000000 --- a/webapp/src/main/resources/atlas-log4j.xml +++ /dev/null @@ -1,68 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<!-- - ~ 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. - --> - -<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> - -<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"> - <appender name="console" class="org.apache.log4j.ConsoleAppender"> - <param name="Target" value="System.out"/> - <layout class="org.apache.log4j.PatternLayout"> - <param name="ConversionPattern" value="%d %-5p - [%t:%x] ~ %m (%c{1}:%L)%n"/> - </layout> - </appender> - - <appender name="FILE" class="org.apache.log4j.DailyRollingFileAppender"> - <param name="File" value="${atlas.log.dir}/application.log"/> - <param name="Append" value="true"/> - <param name="Threshold" value="debug"/> - <layout class="org.apache.log4j.PatternLayout"> - <param name="ConversionPattern" value="%d %-5p - [%t:%x] ~ %m (%c{1}:%L)%n"/> - </layout> - </appender> - - <appender name="AUDIT" class="org.apache.log4j.DailyRollingFileAppender"> - <param name="File" value="${atlas.log.dir}/audit.log"/> - <param name="Append" value="true"/> - <param name="Threshold" value="debug"/> - <layout class="org.apache.log4j.PatternLayout"> - <param name="ConversionPattern" value="%d %x %m%n"/> - </layout> - </appender> - - <logger name="org.apache.atlas" additivity="false"> - <level value="debug"/> - <appender-ref ref="FILE"/> - </logger> - - <logger name="com.thinkaurelius.titan" additivity="false"> - <level value="info"/> - <appender-ref ref="FILE"/> - </logger> - - <logger name="AUDIT"> - <level value="info"/> - <appender-ref ref="AUDIT"/> - </logger> - - <root> - <priority value="warn"/> - <appender-ref ref="FILE"/> - </root> - -</log4j:configuration> http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/ad0d764d/webapp/src/test/java/org/apache/atlas/web/service/SecureEmbeddedServerTest.java ---------------------------------------------------------------------- diff --git a/webapp/src/test/java/org/apache/atlas/web/service/SecureEmbeddedServerTest.java b/webapp/src/test/java/org/apache/atlas/web/service/SecureEmbeddedServerTest.java index 7e75ed3..6b0a005 100644 --- a/webapp/src/test/java/org/apache/atlas/web/service/SecureEmbeddedServerTest.java +++ b/webapp/src/test/java/org/apache/atlas/web/service/SecureEmbeddedServerTest.java @@ -48,7 +48,7 @@ public class SecureEmbeddedServerTest extends SecureEmbeddedServerTestBase { }; secureEmbeddedServer.server.start(); - URL url = new URL("https://localhost:21443/"); + URL url = new URL("https://localhost:21443/api/atlas/admin/version"); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.connect();
