use of org.apache.druid.indexing.overlord.autoscaling.AutoScalingData in project druid by druid-io.
the class GceAutoScaler method terminateWithIds.
/**
* Terminates the instances in the list of IDs provided by the caller
*/
@Override
public AutoScalingData terminateWithIds(List<String> ids) {
log.info("Asked to terminate IDs: [%s]", String.join(",", ids));
if (ids.isEmpty()) {
return new AutoScalingData(new ArrayList<>());
}
try {
final String project = envConfig.getProjectId();
final String zone = envConfig.getZoneName();
final String managedInstanceGroupName = envConfig.getManagedInstanceGroupName();
List<String> before = getRunningInstances();
InstanceGroupManagersDeleteInstancesRequest requestBody = new InstanceGroupManagersDeleteInstancesRequest();
requestBody.setInstances(namesToInstances(ids));
Compute computeService = createComputeService();
Compute.InstanceGroupManagers.DeleteInstances request = computeService.instanceGroupManagers().deleteInstances(project, zone, managedInstanceGroupName, requestBody);
Operation response = request.execute();
Operation.Error err = waitForOperationEnd(computeService, response);
if (err == null || err.isEmpty()) {
List<String> after = null;
// certain amount of retries in checking)
for (int i = 0; i < RUNNING_INSTANCES_MAX_RETRIES; i++) {
after = getRunningInstances();
if (after.size() == (before.size() - ids.size())) {
break;
}
log.info("Machines not down yet, waiting");
Thread.sleep(POLL_INTERVAL_MS);
}
// keep only the ones no more present
before.removeAll(after);
return new AutoScalingData(before);
} else {
log.error("Unable to terminate instances: %s", err.toPrettyString());
}
} catch (Exception e) {
log.error(e, "Unable to terminate any instances.");
}
return new AutoScalingData(new ArrayList<>());
}
use of org.apache.druid.indexing.overlord.autoscaling.AutoScalingData in project druid by druid-io.
the class GceAutoScaler method provision.
/**
* When called resizes envConfig.getManagedInstanceGroupName() increasing it by creating
* envConfig.getNumInstances() new workers (unless the maximum is reached). Return the
* IDs of the workers created
*/
@Override
public AutoScalingData provision() {
final String project = envConfig.getProjectId();
final String zone = envConfig.getZoneName();
final int numInstances = envConfig.getNumInstances();
final String managedInstanceGroupName = envConfig.getManagedInstanceGroupName();
try {
List<String> before = getRunningInstances();
log.debug("Existing instances [%s]", String.join(",", before));
int toSize = Math.min(before.size() + numInstances, getMaxNumWorkers());
if (before.size() >= toSize) {
// nothing to scale
return new AutoScalingData(new ArrayList<>());
}
log.info("Asked to provision instances, will resize to %d", toSize);
Compute computeService = createComputeService();
Compute.InstanceGroupManagers.Resize request = computeService.instanceGroupManagers().resize(project, zone, managedInstanceGroupName, toSize);
Operation response = request.execute();
Operation.Error err = waitForOperationEnd(computeService, response);
if (err == null || err.isEmpty()) {
List<String> after = null;
// certain amount of retries in checking)
for (int i = 0; i < RUNNING_INSTANCES_MAX_RETRIES; i++) {
after = getRunningInstances();
if (after.size() == toSize) {
break;
}
log.info("Machines not up yet, waiting");
Thread.sleep(POLL_INTERVAL_MS);
}
// these should be the new ones
after.removeAll(before);
log.info("Added instances [%s]", String.join(",", after));
return new AutoScalingData(after);
} else {
log.error("Unable to provision instances: %s", err.toPrettyString());
}
} catch (Exception e) {
log.error(e, "Unable to provision any gce instances.");
}
return new AutoScalingData(new ArrayList<>());
}
use of org.apache.druid.indexing.overlord.autoscaling.AutoScalingData in project druid by druid-io.
the class GceAutoScalerTest method testTerminateWithIds.
@Test
public void testTerminateWithIds() throws IOException, GeneralSecurityException, GceServiceException {
GceAutoScaler autoScaler = EasyMock.createMockBuilder(GceAutoScaler.class).withConstructor(int.class, int.class, GceEnvironmentConfig.class).withArgs(2, 4, new GceEnvironmentConfig(1, "proj-x", "us-central-1", "druid-mig")).addMockedMethod("createComputeServiceImpl").createMock();
EasyMock.expect(autoScaler.createComputeServiceImpl()).andReturn(null);
EasyMock.expect(autoScaler.createComputeServiceImpl()).andReturn(mockCompute);
EasyMock.replay(autoScaler);
// set up getRunningInstances results
InstanceGroupManagersListManagedInstancesResponse beforeRunningInstance = createRunningInstances(Arrays.asList("http://xyz/foo", "http://xyz/bar", "http://xyz/baz"));
InstanceGroupManagersListManagedInstancesResponse afterRunningInstance = createRunningInstances(Arrays.asList("http://xyz/foo", "http://xyz/bar"));
// 1st call
EasyMock.expect(mockInstancesRequest.execute()).andReturn(beforeRunningInstance);
EasyMock.expect(mockInstancesRequest.setMaxResults(500L)).andReturn(mockInstancesRequest);
// 2nd call
EasyMock.expect(mockInstancesRequest.execute()).andReturn(afterRunningInstance);
EasyMock.expect(mockInstancesRequest.setMaxResults(500L)).andReturn(mockInstancesRequest);
EasyMock.replay(mockInstancesRequest);
EasyMock.expect(mockInstanceGroupManagers.listManagedInstances("proj-x", "us-central-1", "druid-mig")).andReturn(mockInstancesRequest).times(2);
// set up the delete operation
Operation mockResponse = new Operation();
mockResponse.setStatus("DONE");
mockResponse.setError(new Operation.Error());
EasyMock.expect(mockDeleteRequest.execute()).andReturn(mockResponse);
EasyMock.replay(mockDeleteRequest);
InstanceGroupManagersDeleteInstancesRequest requestBody = new InstanceGroupManagersDeleteInstancesRequest();
requestBody.setInstances(Collections.singletonList("zones/us-central-1/instances/baz"));
EasyMock.expect(mockInstanceGroupManagers.deleteInstances("proj-x", "us-central-1", "druid-mig", requestBody)).andReturn(mockDeleteRequest);
EasyMock.replay(mockInstanceGroupManagers);
// called twice in getRunningInstances...
EasyMock.expect(mockCompute.instanceGroupManagers()).andReturn(mockInstanceGroupManagers);
EasyMock.expect(mockCompute.instanceGroupManagers()).andReturn(mockInstanceGroupManagers);
// ...and once in terminateWithIds
EasyMock.expect(mockCompute.instanceGroupManagers()).andReturn(mockInstanceGroupManagers);
// and that's all folks!
EasyMock.replay(mockCompute);
AutoScalingData autoScalingData = autoScaler.terminateWithIds(Collections.singletonList("baz"));
Assert.assertEquals(1, autoScalingData.getNodeIds().size());
Assert.assertEquals("baz", autoScalingData.getNodeIds().get(0));
EasyMock.verify(mockCompute);
EasyMock.verify(mockInstanceGroupManagers);
EasyMock.verify(mockDeleteRequest);
EasyMock.verify(mockInstancesRequest);
}
use of org.apache.druid.indexing.overlord.autoscaling.AutoScalingData in project druid by druid-io.
the class GceAutoScalerTest method testTerminate.
@Test
public void testTerminate() throws IOException, GeneralSecurityException, GceServiceException {
GceAutoScaler autoScaler = EasyMock.createMockBuilder(GceAutoScaler.class).withConstructor(int.class, int.class, GceEnvironmentConfig.class).withArgs(2, 4, new GceEnvironmentConfig(1, "proj-x", "us-central-1", "druid-mig")).addMockedMethod("createComputeServiceImpl").createMock();
EasyMock.expect(autoScaler.createComputeServiceImpl()).andReturn(null);
EasyMock.expect(autoScaler.createComputeServiceImpl()).andReturn(mockCompute);
EasyMock.replay(autoScaler);
// testing the ip --> id part
Instance i0 = makeInstance("baz", "1.2.3.6");
InstanceList mockInstanceListResponse = new InstanceList();
mockInstanceListResponse.setNextPageToken(null);
mockInstanceListResponse.setItems(Collections.singletonList(i0));
EasyMock.expect(mockIpToIdRequest.execute()).andReturn(mockInstanceListResponse);
EasyMock.expect(mockIpToIdRequest.setPageToken(EasyMock.anyString())).andReturn(// the method needs to return something, what is actually irrelevant here
mockIpToIdRequest);
EasyMock.replay(mockIpToIdRequest);
EasyMock.expect(mockInstances.list("proj-x", "us-central-1")).andReturn(mockIpToIdRequest);
EasyMock.expect(mockCompute.instances()).andReturn(mockInstances);
EasyMock.replay(mockInstances);
// testing the delete part
InstanceGroupManagersListManagedInstancesResponse beforeRunningInstance = createRunningInstances(Arrays.asList("http://xyz/foo", "http://xyz/bar", "http://xyz/baz"));
InstanceGroupManagersListManagedInstancesResponse afterRunningInstance = createRunningInstances(Arrays.asList("http://xyz/foo", "http://xyz/bar"));
// 1st call
EasyMock.expect(mockInstancesRequest.execute()).andReturn(beforeRunningInstance);
EasyMock.expect(mockInstancesRequest.setMaxResults(500L)).andReturn(mockInstancesRequest);
// 2nd call
EasyMock.expect(mockInstancesRequest.execute()).andReturn(afterRunningInstance);
EasyMock.expect(mockInstancesRequest.setMaxResults(500L)).andReturn(mockInstancesRequest);
EasyMock.replay(mockInstancesRequest);
EasyMock.expect(mockInstanceGroupManagers.listManagedInstances("proj-x", "us-central-1", "druid-mig")).andReturn(mockInstancesRequest).times(2);
// set up the delete operation
Operation mockResponse = new Operation();
mockResponse.setStatus("DONE");
mockResponse.setError(new Operation.Error());
EasyMock.expect(mockDeleteRequest.execute()).andReturn(mockResponse);
EasyMock.replay(mockDeleteRequest);
InstanceGroupManagersDeleteInstancesRequest requestBody = new InstanceGroupManagersDeleteInstancesRequest();
requestBody.setInstances(Collections.singletonList("zones/us-central-1/instances/baz"));
EasyMock.expect(mockInstanceGroupManagers.deleteInstances("proj-x", "us-central-1", "druid-mig", requestBody)).andReturn(mockDeleteRequest);
EasyMock.replay(mockInstanceGroupManagers);
// called twice in getRunningInstances...
EasyMock.expect(mockCompute.instanceGroupManagers()).andReturn(mockInstanceGroupManagers);
EasyMock.expect(mockCompute.instanceGroupManagers()).andReturn(mockInstanceGroupManagers);
// ...and once in terminateWithIds
EasyMock.expect(mockCompute.instanceGroupManagers()).andReturn(mockInstanceGroupManagers);
// and that's all folks!
EasyMock.replay(mockCompute);
AutoScalingData autoScalingData = autoScaler.terminate(Collections.singletonList("1.2.3.6"));
Assert.assertEquals(1, autoScalingData.getNodeIds().size());
Assert.assertEquals("baz", autoScalingData.getNodeIds().get(0));
EasyMock.verify(mockCompute);
EasyMock.verify(mockIpToIdRequest);
EasyMock.verify(mockInstanceGroupManagers);
EasyMock.verify(mockDeleteRequest);
EasyMock.verify(mockInstancesRequest);
}
use of org.apache.druid.indexing.overlord.autoscaling.AutoScalingData in project druid by druid-io.
the class EC2AutoScalerTest method testScale.
@Test
public void testScale() {
RunInstancesResult runInstancesResult = EasyMock.createMock(RunInstancesResult.class);
EC2AutoScaler autoScaler = new EC2AutoScaler(0, 1, ENV_CONFIG, amazonEC2Client, managementConfig);
EasyMock.expect(amazonEC2Client.runInstances(EasyMock.anyObject(RunInstancesRequest.class))).andReturn(runInstancesResult);
EasyMock.expect(amazonEC2Client.describeInstances(EasyMock.anyObject(DescribeInstancesRequest.class))).andReturn(describeInstancesResult);
EasyMock.expect(amazonEC2Client.terminateInstances(EasyMock.anyObject(TerminateInstancesRequest.class))).andReturn(null);
EasyMock.replay(amazonEC2Client);
EasyMock.expect(runInstancesResult.getReservation()).andReturn(reservation).atLeastOnce();
EasyMock.replay(runInstancesResult);
EasyMock.expect(describeInstancesResult.getReservations()).andReturn(Collections.singletonList(reservation)).atLeastOnce();
EasyMock.replay(describeInstancesResult);
EasyMock.expect(reservation.getInstances()).andReturn(Collections.singletonList(instance)).atLeastOnce();
EasyMock.replay(reservation);
AutoScalingData created = autoScaler.provision();
Assert.assertEquals(created.getNodeIds().size(), 1);
Assert.assertEquals("theInstance", created.getNodeIds().get(0));
AutoScalingData deleted = autoScaler.terminate(Collections.singletonList("dummyIP"));
Assert.assertEquals(deleted.getNodeIds().size(), 1);
Assert.assertEquals(INSTANCE_ID, deleted.getNodeIds().get(0));
EasyMock.verify(runInstancesResult);
}
Aggregations