Skip to content

Commit

Permalink
Merge pull request #141 from bazaarvoice/emo-6145
Browse files Browse the repository at this point in the history
Create a Global Stash Snapshot.
  • Loading branch information
sujithvaddi authored May 14, 2018
2 parents 7867801 + 4f2c048 commit 4c7f93b
Show file tree
Hide file tree
Showing 65 changed files with 2,119 additions and 232 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ public enum EmoServiceMode {
Aspect.blackList,
Aspect.throttle,
Aspect.report,
Aspect.compaction_control,
Aspect.compaction_control_web,
Aspect.job,
Aspect.security,
Aspect.full_consistency,
Expand All @@ -69,6 +71,7 @@ public enum EmoServiceMode {
Aspect.blobStore_module,
Aspect.blackList,
Aspect.throttle,
Aspect.compaction_control,
Aspect.security,
Aspect.leader_control, // needed for HintsPollerManager
Aspect.blob_zookeeper_full_consistency,
Expand All @@ -92,9 +95,11 @@ public enum EmoServiceMode {
Aspect.cache,
Aspect.leader_control,
Aspect.dataCenter,
Aspect.dataCenter_announce,
Aspect.dataStore_module,
Aspect.blobStore_module, // needed for permission resolver
Aspect.scanner,
Aspect.compaction_control,
Aspect.security,
Aspect.full_consistency
),
Expand Down Expand Up @@ -165,6 +170,8 @@ public enum Aspect {
blackList,
throttle,
report,
compaction_control,
compaction_control_web,
job,
full_consistency, // This wires in the fct global zookeeper location
security,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,12 @@
import com.bazaarvoice.emodb.sor.DataStoreZooKeeper;
import com.bazaarvoice.emodb.sor.api.Audit;
import com.bazaarvoice.emodb.sor.api.AuditBuilder;
import com.bazaarvoice.emodb.sor.api.CompactionControlSource;
import com.bazaarvoice.emodb.sor.api.DataStore;
import com.bazaarvoice.emodb.sor.api.TableOptions;
import com.bazaarvoice.emodb.sor.api.TableOptionsBuilder;
import com.bazaarvoice.emodb.sor.compactioncontrol.CompControlApiKey;
import com.bazaarvoice.emodb.sor.compactioncontrol.LocalCompactionControl;
import com.bazaarvoice.emodb.sor.core.SystemDataStore;
import com.bazaarvoice.emodb.sor.db.cql.CqlForMultiGets;
import com.bazaarvoice.emodb.sor.db.cql.CqlForScans;
Expand Down Expand Up @@ -168,6 +171,9 @@ protected void configure() {

bind(Clock.class).toInstance(Clock.systemDefaultZone());

bind(String.class).annotatedWith(CompControlApiKey.class).toInstance("CompControlApiKey");
bind(CompactionControlSource.class).annotatedWith(LocalCompactionControl.class).toInstance(mock(CompactionControlSource.class));

EmoServiceMode serviceMode = EmoServiceMode.STANDARD_ALL;
install(new SelfHostAndPortModule());
install(new DataCenterModule(serviceMode));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@
import com.bazaarvoice.emodb.sor.DataStoreConfiguration;
import com.bazaarvoice.emodb.sor.DataStoreModule;
import com.bazaarvoice.emodb.sor.DataStoreZooKeeper;
import com.bazaarvoice.emodb.sor.api.CompactionControlSource;
import com.bazaarvoice.emodb.sor.api.DataStore;
import com.bazaarvoice.emodb.sor.compactioncontrol.CompControlApiKey;
import com.bazaarvoice.emodb.sor.compactioncontrol.LocalCompactionControl;
import com.bazaarvoice.emodb.sor.condition.Condition;
import com.bazaarvoice.emodb.sor.condition.Conditions;
import com.bazaarvoice.emodb.sor.core.SystemDataStore;
Expand Down Expand Up @@ -166,6 +169,9 @@ protected void configure() {

bind(Clock.class).toInstance(Clock.systemDefaultZone());

bind(String.class).annotatedWith(CompControlApiKey.class).toInstance("CompControlApiKey");
bind(CompactionControlSource.class).annotatedWith(LocalCompactionControl.class).toInstance(mock(CompactionControlSource.class));

EmoServiceMode serviceMode = EmoServiceMode.STANDARD_ALL;
install(new SelfHostAndPortModule());
install(new DataCenterModule(serviceMode));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,16 @@
import com.bazaarvoice.emodb.sor.api.AuditBuilder;
import com.bazaarvoice.emodb.sor.api.Change;
import com.bazaarvoice.emodb.sor.api.Compaction;
import com.bazaarvoice.emodb.sor.api.CompactionControlSource;
import com.bazaarvoice.emodb.sor.api.DataStore;
import com.bazaarvoice.emodb.sor.api.Intrinsic;
import com.bazaarvoice.emodb.sor.api.ReadConsistency;
import com.bazaarvoice.emodb.sor.api.Table;
import com.bazaarvoice.emodb.sor.api.TableOptionsBuilder;
import com.bazaarvoice.emodb.sor.api.Update;
import com.bazaarvoice.emodb.sor.api.WriteConsistency;
import com.bazaarvoice.emodb.sor.compactioncontrol.CompControlApiKey;
import com.bazaarvoice.emodb.sor.compactioncontrol.LocalCompactionControl;
import com.bazaarvoice.emodb.sor.core.SystemDataStore;
import com.bazaarvoice.emodb.sor.db.cql.CqlForMultiGets;
import com.bazaarvoice.emodb.sor.db.cql.CqlForScans;
Expand Down Expand Up @@ -167,6 +170,9 @@ protected void configure() {

bind(Clock.class).toInstance(Clock.systemDefaultZone());

bind(String.class).annotatedWith(CompControlApiKey.class).toInstance("CompControlApiKey");
bind(CompactionControlSource.class).annotatedWith(LocalCompactionControl.class).toInstance(mock(CompactionControlSource.class));

EmoServiceMode serviceMode = EmoServiceMode.STANDARD_ALL;
install(new SelfHostAndPortModule());
install(new DataCenterModule(serviceMode));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
package test.integration.sor;

import com.bazaarvoice.emodb.auth.apikey.ApiKey;
import com.bazaarvoice.emodb.auth.apikey.ApiKeyModification;
import com.bazaarvoice.emodb.auth.identity.InMemoryAuthIdentityManager;
import com.bazaarvoice.emodb.auth.permissions.InMemoryPermissionManager;
import com.bazaarvoice.emodb.auth.role.InMemoryRoleManager;
import com.bazaarvoice.emodb.auth.role.RoleManager;
import com.bazaarvoice.emodb.blob.api.BlobStore;
import com.bazaarvoice.emodb.client.EmoClientException;
import com.bazaarvoice.emodb.common.jersey.dropwizard.JerseyEmoClient;
import com.bazaarvoice.emodb.sor.api.CompactionControlSource;
import com.bazaarvoice.emodb.sor.api.DataStore;
import com.bazaarvoice.emodb.sor.client.CompactionControlClient;
import com.bazaarvoice.emodb.sor.core.DataStoreAsync;
import com.bazaarvoice.emodb.test.ResourceTest;
import com.bazaarvoice.emodb.web.auth.DefaultRoles;
import com.bazaarvoice.emodb.web.auth.EmoPermissionResolver;
import com.bazaarvoice.emodb.web.resources.sor.DataStoreResource1;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.sun.jersey.api.client.ClientResponse;
import io.dropwizard.testing.junit.ResourceTestRule;
import org.junit.After;
import org.junit.Rule;
import org.junit.Test;

import java.net.URI;
import java.util.List;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.testng.Assert.fail;

public class CompactionControlJerseyTest extends ResourceTest {
private static final String APIKEY_COMPACTION_CONTROL = "compaction-control-key";
private static final String APIKEY_UNAUTHORIZED = "unauthorized-key";

private DataStore _dataStoreServer = mock(DataStore.class);
private CompactionControlSource _compactionControlSourceServer = mock(CompactionControlSource.class);

@Rule
public ResourceTestRule _resourceTestRule = setupReplicationResourceTestRule(ImmutableList.<Object>of(new DataStoreResource1(_dataStoreServer, mock(DataStoreAsync.class),
_compactionControlSourceServer)));

protected static ResourceTestRule setupReplicationResourceTestRule(List<Object> resourceList) {
InMemoryAuthIdentityManager<ApiKey> authIdentityManager = new InMemoryAuthIdentityManager<>();
authIdentityManager.createIdentity(APIKEY_COMPACTION_CONTROL, new ApiKeyModification().addRoles("sor-compcontrol-role"));
authIdentityManager.createIdentity(APIKEY_UNAUTHORIZED, new ApiKeyModification().addRoles("sor-read-only-role"));

EmoPermissionResolver permissionResolver = new EmoPermissionResolver(mock(DataStore.class), mock(BlobStore.class));
InMemoryPermissionManager permissionManager = new InMemoryPermissionManager(permissionResolver);
RoleManager roleManager = new InMemoryRoleManager(permissionManager);
createRole(roleManager, null, "sor-compcontrol-role", DefaultRoles.compaction_control.getPermissions());
createRole(roleManager, null, "sor-read-only-role", ImmutableSet.of("sor|read|*"));

return setupResourceTestRule(resourceList, authIdentityManager, permissionManager);
}

@After
public void tearDownMocksAndClearState() {
verifyNoMoreInteractions(_dataStoreServer);
reset(_dataStoreServer);
verifyNoMoreInteractions(_compactionControlSourceServer);
reset(_compactionControlSourceServer);
}

private CompactionControlSource compactionControlClient() {
return compactionControlClient(APIKEY_COMPACTION_CONTROL);
}

private CompactionControlSource compactionControlClient(String apiKey) {
return new CompactionControlClient(URI.create("/sor/1"), new JerseyEmoClient(_resourceTestRule.client()), apiKey);
}

@Test
public void testUpdateStashTime() {
compactionControlClient().updateStashTime("1", 123L, ImmutableList.of("placement-name"), 123L, "datacenter");

verify(_compactionControlSourceServer).updateStashTime("1", 123L, ImmutableList.of("placement-name"), 123L, "datacenter");
verifyNoMoreInteractions(_compactionControlSourceServer);
}

@Test
public void testdeleteStashTime() {
compactionControlClient().deleteStashTime("1", "datacenter");

verify(_compactionControlSourceServer).deleteStashTime("1", "datacenter");
verifyNoMoreInteractions(_compactionControlSourceServer);
}

@Test
public void testGetStashTime() {
try {
compactionControlClient().getStashTime("1", "datacenter");
} catch (EmoClientException e) {
// we can expect this as there can be a 404 response.
}
verify(_compactionControlSourceServer).getStashTime("1", "datacenter");
verifyNoMoreInteractions(_compactionControlSourceServer);
}

@Test
public void testAllStashTimes() {
compactionControlClient().getAllStashTimes();

verify(_compactionControlSourceServer).getAllStashTimes();
verifyNoMoreInteractions(_compactionControlSourceServer);
}

@Test
public void testAllStashTimesForPlacement() {
compactionControlClient().getStashTimesForPlacement("placement");

verify(_compactionControlSourceServer).getStashTimesForPlacement("placement");
verifyNoMoreInteractions(_compactionControlSourceServer);
}


/**
* Test delete w/an invalid API key.
*/
@Test
public void testdeleteStashTimeUnauthenticated() {
try {
compactionControlClient(APIKEY_UNAUTHORIZED).deleteStashTime("1", "datacenter");
fail();
} catch (EmoClientException e) {
if (e.getResponse().getStatus() != ClientResponse.Status.FORBIDDEN.getStatusCode()) {
throw e;
}
}
verifyNoMoreInteractions(_compactionControlSourceServer);
}

/**
* Test delete w/a valid API key but not one that has permission to delete.
*/
@Test
public void testDeleteForbidden() {
try {
compactionControlClient("completely-unknown-key").deleteStashTime("1", "datacenter");
fail();
} catch (EmoClientException e) {
if (e.getResponse().getStatus() != ClientResponse.Status.FORBIDDEN.getStatusCode()) {
throw e;
}
}
verifyNoMoreInteractions(_compactionControlSourceServer);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import com.bazaarvoice.emodb.sor.client.DataStoreAuthenticator;
import com.bazaarvoice.emodb.sor.client.DataStoreClient;
import com.bazaarvoice.emodb.sor.client.DataStoreStreaming;
import com.bazaarvoice.emodb.sor.compactioncontrol.InMemoryCompactionControlSource;
import com.bazaarvoice.emodb.sor.core.DataStoreAsync;
import com.bazaarvoice.emodb.sor.delta.Deltas;
import com.bazaarvoice.emodb.test.ResourceTest;
Expand Down Expand Up @@ -143,7 +144,7 @@ private ResourceTestRule setupDataStoreResourceTestRule() {
createRole(roleManager, null, "standard", DefaultRoles.standard.getPermissions());
createRole(roleManager, null, "update-with-events", ImmutableSet.of("sor|update|*"));

return setupResourceTestRule(Collections.<Object>singletonList(new DataStoreResource1(_server, mock(DataStoreAsync.class))), authIdentityManager, permissionManager);
return setupResourceTestRule(Collections.<Object>singletonList(new DataStoreResource1(_server, mock(DataStoreAsync.class), new InMemoryCompactionControlSource())), authIdentityManager, permissionManager);
}

@After
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import com.bazaarvoice.emodb.sor.api.DataStore;
import com.bazaarvoice.emodb.sor.client.DataStoreAuthenticator;
import com.bazaarvoice.emodb.sor.client.DataStoreClient;
import com.bazaarvoice.emodb.sor.compactioncontrol.InMemoryCompactionControlSource;
import com.bazaarvoice.emodb.sor.core.DefaultDataStoreAsync;
import com.bazaarvoice.emodb.test.ResourceTest;
import com.bazaarvoice.emodb.web.auth.EmoPermissionResolver;
Expand Down Expand Up @@ -109,7 +110,7 @@ private ResourceTestRule setupDataStoreResourceTestRule() {
createRole(roleManager, null, "all-sor-role", ImmutableSet.of("sor|*|*"));

return setupResourceTestRule(
Collections.<Object>singletonList(new DataStoreResource1(_dataStore, new DefaultDataStoreAsync(_dataStore, mock(JobService.class), mock(JobHandlerRegistry.class)))),
Collections.<Object>singletonList(new DataStoreResource1(_dataStore, new DefaultDataStoreAsync(_dataStore, mock(JobService.class), mock(JobHandlerRegistry.class)), new InMemoryCompactionControlSource())),
Collections.<Object>singletonList(new ConcurrentRequestsThrottlingFilter(_deferringRegulatorSupplier)),
authIdentityManager, permissionManager);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ auth:
# IN A PRODUCTION ENVIRONMENT DO NOT INCLUDE THE UNENCRYPTED KEYS IN THIS FILE!
adminApiKey: "zl+p3AU4/EgT8OtR0ZmLrkL70j0SklugAzd+xxYR1Dz/rioe5aXo4yay7sKi7PSKD59h7/HumH7442nGhlR2rw" # local_admin
replicationApiKey: "iuOPUIfI0lyxRrNZ9j9Aa68m1yrALBbVMw8kdqb6FVhSwMgOXVsuUblLr9nL73D4xpMVEZZHZr50pCBy1gbjDg" # local_replication
compControlApiKey: "local_admin" # compaction-control
anonymousRoles:
- anonymous

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ auth:
# IN A PRODUCTION ENVIRONMENT DO NOT INCLUDE THE UNENCRYPTED KEYS IN THIS FILE!
adminApiKey: "zl+p3AU4/EgT8OtR0ZmLrkL70j0SklugAzd+xxYR1Dz/rioe5aXo4yay7sKi7PSKD59h7/HumH7442nGhlR2rw" # local_admin
replicationApiKey: "iuOPUIfI0lyxRrNZ9j9Aa68m1yrALBbVMw8kdqb6FVhSwMgOXVsuUblLr9nL73D4xpMVEZZHZr50pCBy1gbjDg" # local_replication
compControlApiKey: "local_admin" #compaction-control
anonymousRoles:
- anonymous

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,10 +159,10 @@ auth:
# IN A PRODUCTION ENVIRONMENT DO NOT INCLUDE THE UNENCRYPTED KEYS IN THIS FILE!
adminApiKey: "zl+p3AU4/EgT8OtR0ZmLrkL70j0SklugAzd+xxYR1Dz/rioe5aXo4yay7sKi7PSKD59h7/HumH7442nGhlR2rw" # local_admin
replicationApiKey: "iuOPUIfI0lyxRrNZ9j9Aa68m1yrALBbVMw8kdqb6FVhSwMgOXVsuUblLr9nL73D4xpMVEZZHZr50pCBy1gbjDg" # local_replication
compControlApiKey: "local_admin" # compaction-control
anonymousRoles:
- anonymous


scanner:
scanStatusTable: "__system_scan_upload"
scannerApiKey: "local_admin"
Expand Down
1 change: 1 addition & 0 deletions sdk/src/main/resources/emodb-default-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ auth:
# IN A PRODUCTION ENVIRONMENT DO NOT INCLUDE THE UNENCRYPTED KEYS IN THIS FILE!
adminApiKey: "zl+p3AU4/EgT8OtR0ZmLrkL70j0SklugAzd+xxYR1Dz/rioe5aXo4yay7sKi7PSKD59h7/HumH7442nGhlR2rw" # local_admin
replicationApiKey: "iuOPUIfI0lyxRrNZ9j9Aa68m1yrALBbVMw8kdqb6FVhSwMgOXVsuUblLr9nL73D4xpMVEZZHZr50pCBy1gbjDg" # local_replication
compControlApiKey: "local_admin" # compaction-control
anonymousRoles:
- anonymous

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.bazaarvoice.emodb.sor.api;

import java.util.List;
import java.util.Map;

/**
* Defines the interface for storing and retrieving the stash start run timestamps.
* <p/>
* It's used in stash process (to update the start timestamps) and in compaction (to delay the deletion of deltas).
*/
public interface CompactionControlSource {

void updateStashTime(String id, long timestamp, List<String> placements, long expiredTimestamp, String dataCenter);

void deleteStashTime(String id, String dataCenter);

StashRunTimeInfo getStashTime(String id, String dataCenter);

Map<String, StashRunTimeInfo> getAllStashTimes();

Map<String, StashRunTimeInfo> getStashTimesForPlacement(String placement);
}
Loading

0 comments on commit 4c7f93b

Please sign in to comment.