SynchronizationTaskService extends TaskService<SynchronizationTaskService.State> { public static SynchronizationTaskService create(Supplier<Service> childServiceInstantiator) { if (childServiceInstantiator.get() == null) { throw new IllegalArgumentException("childServiceInstantiator created null child service"); } SynchronizationTaskService taskService = new SynchronizationTaskService(); taskService.childServiceInstantiator = childServiceInstantiator; return taskService; } SynchronizationTaskService(); static SynchronizationTaskService create(Supplier<Service> childServiceInstantiator); @Override void handleStart(Operation post); @Override void handlePut(Operation put); State validatePutRequest(State currentTask, Operation put); @Override void handlePatch(Operation patch); void handleSubStage(State task); void setParentService(FactoryService factoryService); static final String FACTORY_LINK; static final String STAT_NAME_CHILD_SYNCH_RETRY_COUNT; static final String STAT_NAME_SYNCH_RETRY_COUNT; static final int MAX_CHILD_SYNCH_RETRY_COUNT; }
@Test public void synchAfterClusterRestart() throws Throwable { setUpMultiNode(); String factoryLink = ExampleService.FACTORY_LINK; this.host.setNodeGroupQuorum(this.nodeCount); this.host.waitForNodeGroupConvergence(); List<ExampleServiceState> exampleStates = this.host.createExampleServices( this.host.getPeerHost(), this.serviceCount, null, factoryLink); Map<String, ExampleServiceState> exampleStatesMap = exampleStates.stream().collect(Collectors.toMap(s -> s.documentSelfLink, s -> s)); this.host.waitForReplicatedFactoryChildServiceConvergence( this.host.getNodeGroupToFactoryMap(factoryLink), exampleStatesMap, this.exampleStateConvergenceChecker, exampleStatesMap.size(), 0, this.nodeCount); List<VerificationHost> hosts = new ArrayList<>(); for (Map.Entry<URI, VerificationHost> entry : this.host.getInProcessHostMap().entrySet()) { VerificationHost host = entry.getValue(); this.host.stopHostAndPreserveState(host); hosts.add(host); } for (VerificationHost host : hosts) { ServiceHost.Arguments args = new ServiceHost.Arguments(); args.sandbox = Paths.get(host.getStorageSandbox()).getParent(); args.port = 0; VerificationHost newHost = VerificationHost.create(args); newHost.setPort(host.getPort()); newHost.start(); this.host.addPeerNode(newHost); } this.host.joinNodesAndVerifyConvergence(this.nodeCount); this.host.waitForNodeGroupConvergence(this.nodeCount, this.nodeCount); this.host.waitForReplicatedFactoryChildServiceConvergence( this.host.getNodeGroupToFactoryMap(factoryLink), exampleStatesMap, this.exampleStateConvergenceChecker, exampleStatesMap.size(), 0, this.nodeCount); VerificationHost nodeToStop = this.host.getPeerHost(); this.host.stopHost(nodeToStop); this.host.setUpLocalPeerHost(nodeToStop.getPort(), VerificationHost.FAST_MAINT_INTERVAL_MILLIS, null, null); this.host.joinNodesAndVerifyConvergence(this.nodeCount); this.host.waitForNodeGroupConvergence(this.nodeCount, this.nodeCount); this.host.waitForReplicatedFactoryChildServiceConvergence( this.host.getNodeGroupToFactoryMap(factoryLink), exampleStatesMap, this.exampleStateConvergenceChecker, exampleStatesMap.size(), 0, this.nodeCount); }
@Test public void cacheUpdateAfterSynchronization() throws Throwable { setUpMultiNode(); for (VerificationHost host : this.host.getInProcessHostMap().values()) { host.setServiceCacheClearDelayMicros(TimeUnit.MINUTES.toMicros(3)); } this.host.setNodeGroupQuorum(this.nodeCount - 1); this.host.waitForNodeGroupConvergence(); List<ExampleServiceState> exampleStates = this.host.createExampleServices( this.host.getPeerHost(), this.serviceCount, null, ExampleService.FACTORY_LINK); Map<String, ExampleServiceState> exampleStatesMap = exampleStates.stream().collect(Collectors.toMap(s -> s.documentSelfLink, s -> s)); VerificationHost hostToStop = this.host.getPeerHost(); this.host.stopHost(hostToStop); this.host.waitForNodeUnavailable(ServiceUriPaths.DEFAULT_NODE_GROUP, this.host.getInProcessHostMap().values(), hostToStop); this.host.waitForNodeGroupConvergence(this.host.getPeerCount()); VerificationHost peer = this.host.getPeerHost(); this.host.waitForReplicatedFactoryChildServiceConvergence( this.host.getNodeGroupToFactoryMap(ExampleService.FACTORY_LINK), exampleStatesMap, this.exampleStateConvergenceChecker, exampleStatesMap.size(), 0, this.nodeCount - 1); List<Operation> ops = new ArrayList<>(); for (ExampleServiceState s : exampleStates) { Operation op = Operation.createGet(peer, s.documentSelfLink); ops.add(op); } List<ExampleServiceState> newExampleStates = this.host.getTestRequestSender().sendAndWait(ops, ExampleServiceState.class); Map<String, ExampleServiceState> newExampleStatesMap = newExampleStates.stream().collect(Collectors.toMap(s -> s.documentSelfLink, s -> s)); for (ExampleServiceState s : exampleStates) { ExampleServiceState ns = newExampleStatesMap.get(s.documentSelfLink); if (ns.documentEpoch > s.documentEpoch) { ServiceHost newOwner = this.host.getInProcessHostMap().values().stream().filter(h -> h.getId().equals(ns.documentOwner)).iterator().next(); QueryTask.Query query = QueryTask.Query.Builder.create() .addKindFieldClause(ExampleServiceState.class) .addFieldClause(ServiceDocument.FIELD_NAME_SELF_LINK, s.documentSelfLink) .build(); QueryTask task = QueryTask.Builder.createDirectTask() .setQuery(query) .addOption(QueryTask.QuerySpecification.QueryOption.EXPAND_CONTENT) .build(); Operation op = Operation.createPost(newOwner, ServiceUriPaths.CORE_LOCAL_QUERY_TASKS) .setBody(task); task = this.host.getTestRequestSender().sendAndWait(op, QueryTask.class); ServiceDocumentQueryResult result = task.results; assertEquals(1, result.documentCount.longValue()); ExampleServiceState nsFromIndex = Utils.fromJson(result.documents.values().iterator().next(), ExampleServiceState.class); assertFalse(ns.documentVersion < nsFromIndex.documentVersion); } } }