InfrastructureVersions { public void setTargetVersion(NodeType nodeType, Version newTargetVersion, boolean force) { assertLegalNodeTypeForTargetVersion(nodeType); try (Lock lock = db.lockInfrastructureVersions()) { Map<NodeType, Version> infrastructureVersions = db.readInfrastructureVersions(); Version currentTargetVersion = Optional.ofNullable(infrastructureVersions.get(nodeType)) .orElse(Version.emptyVersion); if (currentTargetVersion.equals(newTargetVersion)) return; if (!force && currentTargetVersion.isAfter(newTargetVersion)) { throw new IllegalArgumentException(String.format("Cannot downgrade version without setting 'force'. Current target version: %s, attempted to set target version: %s", currentTargetVersion.toFullString(), newTargetVersion.toFullString())); } if (newTargetVersion.isEmpty()) { infrastructureVersions.remove(nodeType); logger.info("Removing target version for " + nodeType); } else { infrastructureVersions.put(nodeType, newTargetVersion); logger.info("Setting target version for " + nodeType + " to " + newTargetVersion.toFullString()); } db.writeInfrastructureVersions(infrastructureVersions); } } InfrastructureVersions(CuratorDatabaseClient db);   InfrastructureVersions(CuratorDatabaseClient db, Version defaultVersion); void setTargetVersion(NodeType nodeType, Version newTargetVersion, boolean force); Version getTargetVersionFor(NodeType nodeType); Map<NodeType, Version> getTargetVersions();  }
@Test public void can_only_set_version_on_certain_node_types() { infrastructureVersions.setTargetVersion(NodeType.config, version, false); try { infrastructureVersions.setTargetVersion(NodeType.tenant, version, false); fail("Should not be able to set version for tenant nodes"); } catch (IllegalArgumentException ignored) { } try { infrastructureVersions.setTargetVersion(NodeType.tenant, version, true); fail("Should not be able to set version for tenant nodes"); } catch (IllegalArgumentException ignored) { } }