@Override public ServiceConstraint deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException { JsonObject jsonObj = json.getAsJsonObject(); JsonObject quantities = jsonObj.get("quantities").getAsJsonObject(); Integer min = context.deserialize(quantities.get("min"), Integer.class); Integer max = context.deserialize(quantities.get("max"), Integer.class); Set<String> requiredHardwareTypes = context.deserialize(jsonObj.get("hardwaretypes"), new TypeToken<Set<String>>() { }.getType()); Set<String> requiredImageTypes = context.deserialize(jsonObj.get("imagetypes"), new TypeToken<Set<String>>() { }.getType()); return new ServiceConstraint(requiredHardwareTypes, requiredImageTypes, min, max); } }
@Override public JsonElement serialize(ServiceConstraint serviceConstraint, Type type, JsonSerializationContext context) { JsonObject jsonObj = new JsonObject(); jsonObj.add("hardwaretypes", context.serialize(serviceConstraint.getRequiredHardwareTypes())); jsonObj.add("imagetypes", context.serialize(serviceConstraint.getRequiredImageTypes())); JsonObject quantities = new JsonObject(); quantities.add("min", context.serialize(serviceConstraint.getMinCount())); quantities.add("max", context.serialize(serviceConstraint.getMaxCount())); jsonObj.add("quantities", quantities); return jsonObj; }
private boolean isValidCluster(Map<String, Integer> serviceCounts) { for (Map.Entry<String, ServiceConstraint> entry : serviceConstraints.entrySet()) { String service = entry.getKey(); ServiceConstraint constraint = entry.getValue(); int serviceCount = serviceCounts.get(service); // TODO: ratio constraint if (serviceCount < constraint.getMinCount() || serviceCount > constraint.getMaxCount() || serviceCount > numMachines) { return false; } } return true; }
/** * Determine if this is a valid node layout given the service constraints. * * @param serviceConstraints Service constraints to use for checking validity. * @return True if it satisfies all service constraints, false if not. */ public boolean satisfiesServiceConstraints(Map<String, ServiceConstraint> serviceConstraints) { for (String service : services) { ServiceConstraint constraint = serviceConstraints.get(service); if (constraint != null) { // check that no required hardware rules are broken Set<String> requiredHardwareTypes = constraint.getRequiredHardwareTypes(); if (requiredHardwareTypes != null && !requiredHardwareTypes.isEmpty() && !requiredHardwareTypes.contains(hardwareType)) { return false; } // check that no required image rules are broken Set<String> requiredImageTypes = constraint.getRequiredImageTypes(); if (requiredImageTypes != null && !requiredImageTypes.isEmpty() && !requiredImageTypes.contains(imageType)) { return false; } } } return true; }
private int[] getGlobalNodeLayoutMaxes() { int[] layoutsMaxes = new int[nodePreferences.size()]; for (int i = 0; i < layoutsMaxes.length; i++) { NodeLayout layout = nodePreferences.get(i); int max = Integer.MAX_VALUE; for (String service : layout.getServiceNames()) { ServiceConstraint constraint = serviceConstraints.get(service); if (constraint != null) { int constraintMax = constraint.getMaxCount(); if (constraintMax < max) { max = constraintMax; } } } layoutsMaxes[i] = max; } return layoutsMaxes; }
@Override public int compare(Map.Entry<String, ServiceConstraint> entry1, Map.Entry<String, ServiceConstraint> entry2) { ServiceConstraint constraint1 = entry1.getValue(); ServiceConstraint constraint2 = entry2.getValue(); if (constraint1 == null && constraint2 != null) { return 1; } else if (constraint1 != null && constraint2 == null) { return -1; } else if (constraint1 != null) { int compare = ((Integer) constraint1.getMaxCount()).compareTo(constraint2.getMaxCount()); if (compare != 0) { return compare; } compare = 0 - ((Integer) constraint1.getMinCount()).compareTo(constraint2.getMinCount()); if (compare != 0) { return compare; } } return entry1.getKey().compareTo(entry2.getKey()); } }
int getMaxForNodelayout(int i, int[] counts) { int maxSoFar = numMachines - getTotalCount(counts); if (maxSoFar == 0) { return 0; } NodeLayout nodeLayout = nodePreferences.get(i); for (String service : nodeLayout.getServiceNames()) { ServiceConstraint constraint = serviceConstraints.get(service); if (constraint != null) { int serviceCount = serviceCounts.get(service); int serviceMax = constraint.getMaxCount() - serviceCount; if (serviceMax < maxSoFar) { maxSoFar = serviceMax; } } } return maxSoFar; }
ImmutableMap.<String, ServiceConstraint>of( "master1", new ServiceConstraint( ImmutableSet.of("large"), ImmutableSet.of("centos6", "ubuntu12"), 1, 1), "slave1", new ServiceConstraint( ImmutableSet.of("medium"), ImmutableSet.of("centos6", "ubuntu12"), 1, 50), "slave2", new ServiceConstraint( ImmutableSet.of("medium"), ImmutableSet.of("centos6", "ubuntu12"), 1, 50), "base", new ServiceConstraint( null, ImmutableSet.of("centos6", "ubuntu12"), 0, 50), "app", new ServiceConstraint( ImmutableSet.of("medium"), ImmutableSet.of("centos6", "ubuntu12"), 1, 50)
private boolean satisfiesConstraints(Constraints constraints) { // check node layouts Set<String> clusterServices = serviceCounts.elementSet(); for (NodeLayout nodeLayout : layout.elementSet()) { if (!nodeLayout.satisfiesConstraints(constraints, clusterServices)) { return false; } } // check service counts Map<String, ServiceConstraint> serviceConstraints = constraints.getServiceConstraints(); for (Multiset.Entry<String> entry : serviceCounts.entrySet()) { ServiceConstraint constraint = serviceConstraints.get(entry.getElement()); if (constraint != null) { int serviceCount = entry.getCount(); // TODO: ratio constraint if (serviceCount < constraint.getMinCount() || serviceCount > constraint.getMaxCount() || serviceCount > layout.size()) { return false; } } } return true; }
@BeforeClass public static void beforeClass() { constraints = new Constraints( ImmutableMap.<String, ServiceConstraint>of( "master1", new ServiceConstraint( ImmutableSet.of("large"), ImmutableSet.of("centos6", "ubuntu12"), 1, 1), "slave1", new ServiceConstraint( ImmutableSet.of("medium"), ImmutableSet.of("centos6", "ubuntu12"), 1, 50), "slave2", new ServiceConstraint( ImmutableSet.of("medium"), ImmutableSet.of("centos6", "ubuntu12"), 1, 50) ), new LayoutConstraint( ImmutableSet.<Set<String>>of( ImmutableSet.of("slave1", "slave2") ), ImmutableSet.<Set<String>>of( ImmutableSet.of("master1", "slave1"), ImmutableSet.of("master1", "slave2") ) ), SizeConstraint.EMPTY ); } }
this.nodesToAddTo = Math.min(serviceConstraint.getMaxCount(), this.nodesToAddTo); this.minNodesToAddTo = Math.max(serviceConstraint.getMinCount(), this.minNodesToAddTo);
ImmutableMap.<String, ServiceConstraint>of( "namenode", new ServiceConstraint( ImmutableSet.of("large-mem"), ImmutableSet.of("centos6", "ubuntu12"), 1, 1), "datanode", new ServiceConstraint( ImmutableSet.of("medium", "large-cpu"), ImmutableSet.of("centos6", "ubuntu12"), 1, 50), "zookeeper", new ServiceConstraint( ImmutableSet.of("small", "medium"), ImmutableSet.of("centos6"), 1, 5), "reactor", new ServiceConstraint( ImmutableSet.of("medium", "large"), null, 1, 5)
ImmutableMap.<String, ServiceConstraint>of( "namenode", new ServiceConstraint( ImmutableSet.of("large-mem"), ImmutableSet.of("centos6", "ubuntu12"), 1, 1), "datanode", new ServiceConstraint( ImmutableSet.of("medium", "large-cpu"), ImmutableSet.of("centos6", "ubuntu12"), 1, 50), "zookeeper", new ServiceConstraint( ImmutableSet.of("small", "medium"), ImmutableSet.of("centos6"), 1, 5), "reactor", new ServiceConstraint( ImmutableSet.of("medium", "large"), null, 1, 5)
@BeforeClass public static void setupClusterServiceTests() throws Exception { clusterService = injector.getInstance(ClusterService.class); TenantProvisionerService tenantProvisionerService = injector.getInstance(TenantProvisionerService.class); // setup data tenantProvisionerService.writeProvisioner(new Provisioner("p1", "host", 50056, 100, null, null)); tenantProvisionerService.writeTenantSpecification(new TenantSpecification("tenantX", 10, 1, 10)); Tenant tenant = tenantStore.getTenantByName("tenantX"); account = new Account(Constants.ADMIN_USER, tenant.getId()); entityStoreView = entityStoreService.getView(account); serviceConstraints.put("mysql-server", new ServiceConstraint(null, null, 1, 1)); serviceConstraints.put("zookeeper-server", new ServiceConstraint(null, null, 1, 1)); }
@Test public void testNodesMustHaveServices() throws Exception { Set<String> services = ImmutableSet.of("svc1", "svc2", "svc3"); ClusterTemplate template = ClusterTemplate.builder() .setName("simple") .setDescription("all services on all nodes template") .setClusterDefaults(ClusterDefaults.builder().setServices(services).setProvider("joyent").build()) .setCompatibilities(Compatibilities.builder().setServices(services).build()) .setConstraints(new Constraints( ImmutableMap.<String, ServiceConstraint>of("svc1", new ServiceConstraint(null, null, 1, 1)), new LayoutConstraint( ImmutableSet.<Set<String>>of(ImmutableSet.of("svc1", "svc2", "svc3")), ImmutableSet.<Set<String>>of() ), SizeConstraint.EMPTY )).build(); List<NodeLayout> expected = ImmutableList.of( new NodeLayout("small", "centos6", ImmutableSet.of("svc1", "svc2", "svc3")) ); NodeLayoutGenerator nodeLayoutGenerator = new NodeLayoutGenerator(template, services, ImmutableSet.<String>of("small"), ImmutableSet.<String>of("centos6")); List<NodeLayout> actual = nodeLayoutGenerator.generateNodeLayoutPreferences(); Assert.assertEquals(expected, actual); }
@Test public void testNoSolutionReturnsNull() { Set<String> services = ImmutableSet.of("svc1", "svc2", "svc3"); ClusterTemplate template = ClusterTemplate.builder() .setName("simple") .setDescription("all services on all nodes template") .setClusterDefaults(ClusterDefaults.builder().setServices(services).setProvider("joyent").build()) .setCompatibilities(Compatibilities.builder().setServices(services).build()) .setConstraints(new Constraints( ImmutableMap.<String, ServiceConstraint>of("svc1", new ServiceConstraint(null, null, 1, 1)), new LayoutConstraint( ImmutableSet.<Set<String>>of(ImmutableSet.of("svc1", "svc2", "svc3")), ImmutableSet.<Set<String>>of() ), SizeConstraint.EMPTY)) .build(); List<NodeLayout> nodePreferences = ImmutableList.of( new NodeLayout("small", "centos6", ImmutableSet.of("svc1", "svc2", "svc3")) ); ClusterLayoutFinder finder = new ClusterLayoutFinder(nodePreferences, template, services, 2); Assert.assertNull(finder.findValidNodeCounts()); }
ImmutableMap.<String, ServiceConstraint>of( "namenode", new ServiceConstraint( ImmutableSet.of("large-mem"), ImmutableSet.of("centos6", "ubuntu12"), 1, 1), "datanode", new ServiceConstraint( ImmutableSet.of("medium", "large-cpu"), ImmutableSet.of("centos6", "ubuntu12"), 1, 50), "zookeeper", new ServiceConstraint( ImmutableSet.of("small", "medium"), ImmutableSet.of("centos6"), 1, 5), "reactor", new ServiceConstraint( ImmutableSet.of("medium", "large"), null, 1, 5)
ImmutableMap.<String, ServiceConstraint>of( "namenode", new ServiceConstraint( ImmutableSet.of("large-mem"), ImmutableSet.of("centos6", "ubuntu12"), 1, 1), "datanode", new ServiceConstraint( ImmutableSet.of("medium", "large-cpu"), ImmutableSet.of("centos6", "ubuntu12"), 1, 50), "zookeeper", new ServiceConstraint( ImmutableSet.of("small", "medium"), ImmutableSet.of("centos6"), 1, 5), "reactor", new ServiceConstraint( ImmutableSet.of("medium", "large"), null, 1, 5)
ImmutableMap.<String, ServiceConstraint>of( "namenode", new ServiceConstraint( ImmutableSet.of("large-mem"), ImmutableSet.of("centos6", "ubuntu12"), 1, 1), "datanode", new ServiceConstraint( ImmutableSet.of("medium", "large-cpu"), ImmutableSet.of("centos6", "ubuntu12"), 1, 50), "zookeeper", new ServiceConstraint( ImmutableSet.of("small", "medium"), ImmutableSet.of("centos6"), 1, 5), "reactor", new ServiceConstraint( ImmutableSet.of("medium", "large"), null, 1, 5)