Repository: atlas Updated Branches: refs/heads/ATLAS-2251 c2b9846dd -> 5f40541b5
ATLAS-2251: restoring deleted InMemory and Noop EntityAuditRepository Project: http://git-wip-us.apache.org/repos/asf/atlas/repo Commit: http://git-wip-us.apache.org/repos/asf/atlas/commit/5f40541b Tree: http://git-wip-us.apache.org/repos/asf/atlas/tree/5f40541b Diff: http://git-wip-us.apache.org/repos/asf/atlas/diff/5f40541b Branch: refs/heads/ATLAS-2251 Commit: 5f40541b5345c94804b19d4a085e30e73c8ee83e Parents: c2b9846 Author: Madhan Neethiraj <mad...@apache.org> Authored: Thu Nov 9 19:41:51 2017 -0800 Committer: Madhan Neethiraj <mad...@apache.org> Committed: Thu Nov 9 19:41:51 2017 -0800 ---------------------------------------------------------------------- .../test/java/org/apache/atlas/TestUtilsV2.java | 4 + .../audit/InMemoryEntityAuditRepository.java | 84 +++++++++++++++ .../audit/NoopEntityAuditRepository.java | 63 +++++++++++ .../audit/AuditRepositoryTestBase.java | 107 +++++++++++++++++++ .../audit/InMemoryAuditRepositoryTest.java | 28 +++++ 5 files changed, 286 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/atlas/blob/5f40541b/intg/src/test/java/org/apache/atlas/TestUtilsV2.java ---------------------------------------------------------------------- diff --git a/intg/src/test/java/org/apache/atlas/TestUtilsV2.java b/intg/src/test/java/org/apache/atlas/TestUtilsV2.java index 5564955..bbccf77 100755 --- a/intg/src/test/java/org/apache/atlas/TestUtilsV2.java +++ b/intg/src/test/java/org/apache/atlas/TestUtilsV2.java @@ -836,6 +836,10 @@ public final class TestUtilsV2 { return RandomStringUtils.randomAlphanumeric(10); } + public static final String randomString(int count) { + return RandomStringUtils.randomAlphanumeric(count); + } + public static AtlasEntity createDBEntity() { String dbName = RandomStringUtils.randomAlphanumeric(10); return createDBEntity(dbName); http://git-wip-us.apache.org/repos/asf/atlas/blob/5f40541b/repository/src/main/java/org/apache/atlas/repository/audit/InMemoryEntityAuditRepository.java ---------------------------------------------------------------------- diff --git a/repository/src/main/java/org/apache/atlas/repository/audit/InMemoryEntityAuditRepository.java b/repository/src/main/java/org/apache/atlas/repository/audit/InMemoryEntityAuditRepository.java new file mode 100644 index 0000000..22d2a81 --- /dev/null +++ b/repository/src/main/java/org/apache/atlas/repository/audit/InMemoryEntityAuditRepository.java @@ -0,0 +1,84 @@ +/** + * 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.atlas.EntityAuditEvent; +import org.apache.atlas.annotation.ConditionalOnAtlasProperty; +import org.springframework.stereotype.Component; + +import javax.inject.Singleton; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.SortedMap; +import java.util.TreeMap; + +/** + * Entity audit repository where audit events are stored in-memory. Used only for integration tests + */ +@Singleton +@Component +@ConditionalOnAtlasProperty(property = "atlas.EntityAuditRepository.impl") +public class InMemoryEntityAuditRepository implements EntityAuditRepository { + private TreeMap<String, EntityAuditEvent> auditEvents = new TreeMap<>(); + + @Override + public void putEvents(EntityAuditEvent... events) throws AtlasException { + putEvents(Arrays.asList(events)); + } + + @Override + public synchronized void putEvents(List<EntityAuditEvent> events) throws AtlasException { + for (EntityAuditEvent event : events) { + String rowKey = event.getEntityId() + (Long.MAX_VALUE - event.getTimestamp()); + event.setEventKey(rowKey); + auditEvents.put(rowKey, event); + } + } + + //synchronized to avoid concurrent modification exception that occurs if events are added + //while we are iterating through the map + @Override + public synchronized List<EntityAuditEvent> listEvents(String entityId, String startKey, short maxResults) + throws AtlasException { + List<EntityAuditEvent> events = new ArrayList<>(); + String myStartKey = startKey; + if (myStartKey == null) { + myStartKey = entityId; + } + SortedMap<String, EntityAuditEvent> subMap = auditEvents.tailMap(myStartKey); + for (EntityAuditEvent event : subMap.values()) { + if (events.size() < maxResults && event.getEntityId().equals(entityId)) { + events.add(event); + } + } + return events; + } + + @Override + public long repositoryMaxSize() throws AtlasException { + return -1; + } + + @Override + public List<String> getAuditExcludeAttributes(String entityType) throws AtlasException { + return null; + } +} http://git-wip-us.apache.org/repos/asf/atlas/blob/5f40541b/repository/src/main/java/org/apache/atlas/repository/audit/NoopEntityAuditRepository.java ---------------------------------------------------------------------- diff --git a/repository/src/main/java/org/apache/atlas/repository/audit/NoopEntityAuditRepository.java b/repository/src/main/java/org/apache/atlas/repository/audit/NoopEntityAuditRepository.java new file mode 100644 index 0000000..c382601 --- /dev/null +++ b/repository/src/main/java/org/apache/atlas/repository/audit/NoopEntityAuditRepository.java @@ -0,0 +1,63 @@ +/** + * 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.atlas.EntityAuditEvent; +import org.apache.atlas.annotation.ConditionalOnAtlasProperty; +import org.springframework.stereotype.Component; + +import javax.inject.Singleton; +import java.util.Collections; +import java.util.List; + +/** + * Implementation that completely disables the audit repository. + */ +@Singleton +@Component +@ConditionalOnAtlasProperty(property = "atlas.EntityAuditRepository.impl") +public class NoopEntityAuditRepository implements EntityAuditRepository { + + @Override + public void putEvents(EntityAuditEvent... events) throws AtlasException { + //do nothing + } + + @Override + public synchronized void putEvents(List<EntityAuditEvent> events) throws AtlasException { + //do nothing + } + + @Override + public List<EntityAuditEvent> listEvents(String entityId, String startKey, short maxResults) + throws AtlasException { + return Collections.emptyList(); + } + + @Override + public long repositoryMaxSize() throws AtlasException { + return -1; + } + + @Override + public List<String> getAuditExcludeAttributes(String entityType) throws AtlasException { + return null; + } +} http://git-wip-us.apache.org/repos/asf/atlas/blob/5f40541b/repository/src/test/java/org/apache/atlas/repository/audit/AuditRepositoryTestBase.java ---------------------------------------------------------------------- diff --git a/repository/src/test/java/org/apache/atlas/repository/audit/AuditRepositoryTestBase.java b/repository/src/test/java/org/apache/atlas/repository/audit/AuditRepositoryTestBase.java new file mode 100644 index 0000000..47fd9cf --- /dev/null +++ b/repository/src/test/java/org/apache/atlas/repository/audit/AuditRepositoryTestBase.java @@ -0,0 +1,107 @@ +/** + * 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.EntityAuditEvent; +import org.apache.atlas.TestUtilsV2; +import org.apache.atlas.v1.model.instance.Referenceable; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; + +import java.util.ArrayList; +import java.util.List; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotNull; + +public class AuditRepositoryTestBase { + protected EntityAuditRepository eventRepository; + + private String rand() { + return TestUtilsV2.randomString(10); + } + + @BeforeTest + public void setUp() throws Exception{ + eventRepository = new InMemoryEntityAuditRepository(); + } + + @Test + public void testAddEvents() throws Exception { + EntityAuditEvent event = new EntityAuditEvent(rand(), System.currentTimeMillis(), "u1", + EntityAuditEvent.EntityAuditAction.ENTITY_CREATE, "d1", new Referenceable(rand())); + + eventRepository.putEvents(event); + + List<EntityAuditEvent> events = eventRepository.listEvents(event.getEntityId(), null, (short) 10); + + assertEquals(events.size(), 1); + assertEventEquals(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.currentTimeMillis(); + Referenceable entity = new Referenceable(rand()); + List<EntityAuditEvent> expectedEvents = new ArrayList<>(3); + + for (int i = 0; i < 3; i++) { + //Add events for both ids + EntityAuditEvent event = new EntityAuditEvent(id2, ts - i, "user" + i, EntityAuditEvent.EntityAuditAction.ENTITY_UPDATE, "details" + i, entity); + + eventRepository.putEvents(event); + expectedEvents.add(event); + eventRepository.putEvents(new EntityAuditEvent(id1, ts - i, "user" + i, EntityAuditEvent.EntityAuditAction.TAG_DELETE, "details" + i, entity)); + eventRepository.putEvents(new EntityAuditEvent(id3, ts - i, "user" + i, EntityAuditEvent.EntityAuditAction.TAG_ADD, "details" + i, entity)); + } + + //Use ts for which there is no event - ts + 2 + List<EntityAuditEvent> events = eventRepository.listEvents(id2, null, (short) 3); + assertEquals(events.size(), 3); + assertEventEquals(events.get(0), expectedEvents.get(0)); + assertEventEquals(events.get(1), expectedEvents.get(1)); + assertEventEquals(events.get(2), expectedEvents.get(2)); + + //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(2).getEventKey(), (short) 3); + assertEquals(events.size(), 1); + assertEventEquals(events.get(0), expectedEvents.get(2)); + } + + @Test + public void testInvalidEntityId() throws Exception { + List<EntityAuditEvent> events = eventRepository.listEvents(rand(), null, (short) 3); + + assertEquals(events.size(), 0); + } + + protected void assertEventEquals(EntityAuditEvent actual, EntityAuditEvent expected) { + if (expected != null) { + assertNotNull(actual); + } + + assertEquals(actual.getEntityId(), expected.getEntityId()); + assertEquals(actual.getAction(), expected.getAction()); + assertEquals(actual.getTimestamp(), expected.getTimestamp()); + assertEquals(actual.getDetails(), expected.getDetails()); + } +} http://git-wip-us.apache.org/repos/asf/atlas/blob/5f40541b/repository/src/test/java/org/apache/atlas/repository/audit/InMemoryAuditRepositoryTest.java ---------------------------------------------------------------------- diff --git a/repository/src/test/java/org/apache/atlas/repository/audit/InMemoryAuditRepositoryTest.java b/repository/src/test/java/org/apache/atlas/repository/audit/InMemoryAuditRepositoryTest.java new file mode 100644 index 0000000..3bdfcf9 --- /dev/null +++ b/repository/src/test/java/org/apache/atlas/repository/audit/InMemoryAuditRepositoryTest.java @@ -0,0 +1,28 @@ +/** + * 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.testng.annotations.BeforeClass; + +public class InMemoryAuditRepositoryTest extends AuditRepositoryTestBase { + @BeforeClass + public void setup() { + eventRepository = new InMemoryEntityAuditRepository(); + } +}