EnumSet<Utils.MergeResult> mergeResult = Utils.mergeWithStateAdvanced(description, currentState, stateClass, op); hasStateChanged = mergeResult.contains(Utils.MergeResult.STATE_CHANGED);
@Override public void handlePatch(Operation op) { if (!op.hasBody()) { op.fail(new IllegalArgumentException("body is required")); return; } UserState currentState = getState(op); try { UserState newState = getBody(op); if (newState.email != null && !validate(op, newState)) { op.fail(new IllegalArgumentException("Invalid email address")); return; } Utils.mergeWithStateAdvanced(getStateDescription(), currentState, UserState.class, op); } catch (NoSuchFieldException | IllegalAccessException e) { op.fail(e); return; } op.setBody(currentState).complete(); }
@Test public void testCollectionsUpdateThroughMergeMethod() throws Throwable { MergeTest state = new MergeTest(); state.setOfStrings = new HashSet<String>(); Map<String, Collection<Object>> collectionsToAdd = new HashMap<>(); collectionsToAdd.put("setOfStrings", new ArrayList<>(Arrays.asList(SOME_STRING_VALUE))); ServiceStateCollectionUpdateRequest request = ServiceStateCollectionUpdateRequest .create(collectionsToAdd, null); Operation patchOperation = Operation.createPatch(new URI("http://test")).setBody(request); ServiceDocumentDescription desc = ServiceDocumentDescription.Builder.create() .buildDescription(MergeTest.class); EnumSet<MergeResult> result = Utils.mergeWithStateAdvanced(desc, state, MergeTest.class, patchOperation); assertTrue(result.contains(MergeResult.SPECIAL_MERGE)); assertTrue(result.contains(MergeResult.STATE_CHANGED)); assertEquals(state.setOfStrings.size(), 1); // repeating the update should not change the state anymore result = Utils.mergeWithStateAdvanced(desc, state, MergeTest.class, patchOperation); assertTrue(result.contains(MergeResult.SPECIAL_MERGE)); assertFalse(result.contains(MergeResult.STATE_CHANGED)); }
@Test public void testCollectionsUpdateThroughMergeMethod() throws Throwable { MergeTest state = new MergeTest(); state.setOfStrings = new HashSet<String>(); Map<String, Collection<Object>> collectionsToAdd = new HashMap<>(); collectionsToAdd.put("setOfStrings", new ArrayList<>(Arrays.asList(SOME_STRING_VALUE))); ServiceStateCollectionUpdateRequest request = ServiceStateCollectionUpdateRequest .create(collectionsToAdd, null); Operation patchOperation = Operation.createPatch(new URI("http://test")).setBody(request); ServiceDocumentDescription desc = ServiceDocumentDescription.Builder.create() .buildDescription(MergeTest.class); EnumSet<MergeResult> result = Utils.mergeWithStateAdvanced(desc, state, MergeTest.class, patchOperation); assertTrue(result.contains(MergeResult.SPECIAL_MERGE)); assertTrue(result.contains(MergeResult.STATE_CHANGED)); assertEquals(state.setOfStrings.size(), 1); // repeating the update should not change the state anymore result = Utils.mergeWithStateAdvanced(desc, state, MergeTest.class, patchOperation); assertTrue(result.contains(MergeResult.SPECIAL_MERGE)); assertFalse(result.contains(MergeResult.STATE_CHANGED)); }
/** * Comes in here for a http patch on an existing doc * For patch only the values being changed are sent. * getState() method fills in the missing values from the existing doc. */ @Override public void handlePatch(Operation patch) { checkHasBody(patch); try { SubnetRangeState currentState = getState(patch); // Merge the patch values to current state // In order to validate the merged result EnumSet<Utils.MergeResult> mergeResult = Utils.mergeWithStateAdvanced(getStateDescription(), currentState, SubnetRangeState.class, patch); boolean hasStateChanged = mergeResult.contains(Utils.MergeResult.STATE_CHANGED); if (hasStateChanged) { validateAll(currentState) .thenAccept((ignored) -> setState(patch, currentState)) .whenCompleteNotify(patch); } else { patch.setStatusCode(Operation.STATUS_CODE_NOT_MODIFIED); patch.complete(); } } catch (Exception e) { this.logSevere(String.format("SubnetRangeService: failed to perform patch [%s]", e.getMessage())); patch.fail(e); } }
@Override public void handlePatch(Operation patch) { ElasticPlacementZoneState currentState = getState(patch); boolean hasStateChanged = false; try { EnumSet<Utils.MergeResult> mergeResult = Utils.mergeWithStateAdvanced( getStateDescription(), currentState, ElasticPlacementZoneState.class, patch); hasStateChanged = mergeResult.contains(MergeResult.STATE_CHANGED); } catch (NoSuchFieldException | IllegalAccessException e) { patch.fail(e); return; } if (!hasStateChanged) { patch.setStatusCode(Operation.STATUS_CODE_NOT_MODIFIED); patch.complete(); } else { // update the underlying resource pool setOrRemoveResourcePoolElasticity(currentState, (t) -> { if (t != null) { patch.fail(t); } else { patch.complete(); } }); } }
@Test public void testSetFieldUpdate() throws Throwable { // current state with null set MergeTest state = new MergeTest(); // collection update with a list collection instead of a set collection Map<String, Collection<Object>> collectionsToAdd = new HashMap<>(); collectionsToAdd.put("setOfStrings", Arrays.asList(SOME_STRING_VALUE)); ServiceStateCollectionUpdateRequest request = ServiceStateCollectionUpdateRequest .create(collectionsToAdd, null); Operation patchOperation = Operation.createPatch(new URI("http://test")).setBody(request); ServiceDocumentDescription desc = ServiceDocumentDescription.Builder.create() .buildDescription(MergeTest.class); EnumSet<MergeResult> result = Utils.mergeWithStateAdvanced(desc, state, MergeTest.class, patchOperation); assertTrue(result.contains(MergeResult.SPECIAL_MERGE)); assertTrue(result.contains(MergeResult.STATE_CHANGED)); assertEquals(1, state.setOfStrings.size()); assertEquals(SOME_STRING_VALUE, state.setOfStrings.iterator().next()); }
@Test public void testSetFieldUpdate() throws Throwable { // current state with null set MergeTest state = new MergeTest(); // collection update with a list collection instead of a set collection Map<String, Collection<Object>> collectionsToAdd = new HashMap<>(); collectionsToAdd.put("setOfStrings", Arrays.asList(SOME_STRING_VALUE)); ServiceStateCollectionUpdateRequest request = ServiceStateCollectionUpdateRequest .create(collectionsToAdd, null); Operation patchOperation = Operation.createPatch(new URI("http://test")).setBody(request); ServiceDocumentDescription desc = ServiceDocumentDescription.Builder.create() .buildDescription(MergeTest.class); EnumSet<MergeResult> result = Utils.mergeWithStateAdvanced(desc, state, MergeTest.class, patchOperation); assertTrue(result.contains(MergeResult.SPECIAL_MERGE)); assertTrue(result.contains(MergeResult.STATE_CHANGED)); assertEquals(1, state.setOfStrings.size()); assertEquals(SOME_STRING_VALUE, state.setOfStrings.iterator().next()); }
ServiceDocumentDescription desc = ServiceDocumentDescription.Builder.create() .buildDescription(MergeTest.class); EnumSet<MergeResult> result = Utils.mergeWithStateAdvanced(desc, state, MergeTest.class, patchOperation); assertTrue(result.contains(MergeResult.SPECIAL_MERGE)); result = Utils.mergeWithStateAdvanced(desc, state, MergeTest.class, patchOperation); assertTrue(result.contains(MergeResult.SPECIAL_MERGE)); assertTrue(result.contains(MergeResult.STATE_CHANGED)); result = Utils.mergeWithStateAdvanced(desc, state, MergeTest.class, patchOperation); assertTrue(result.contains(MergeResult.SPECIAL_MERGE)); assertFalse(result.contains(MergeResult.STATE_CHANGED));
ServiceDocumentDescription desc = ServiceDocumentDescription.Builder.create() .buildDescription(MergeTest.class); EnumSet<MergeResult> result = Utils.mergeWithStateAdvanced(desc, state, MergeTest.class, patchOperation); assertTrue(result.contains(MergeResult.SPECIAL_MERGE)); result = Utils.mergeWithStateAdvanced(desc, state, MergeTest.class, patchOperation); assertTrue(result.contains(MergeResult.SPECIAL_MERGE)); assertTrue(result.contains(MergeResult.STATE_CHANGED)); result = Utils.mergeWithStateAdvanced(desc, state, MergeTest.class, patchOperation); assertTrue(result.contains(MergeResult.SPECIAL_MERGE)); assertFalse(result.contains(MergeResult.STATE_CHANGED));
Utils.mergeWithStateAdvanced(getStateDescription(), currentState, SubnetRangeState.class, patch);
@Test public void testMergeWithStateAdvanced() throws Throwable { MergeTest state = new MergeTest(); state.s = "one"; MergeTest patch = new MergeTest(); patch.s = "two"; Operation patchOperation = Operation.createPatch(new URI("http://test")).setBody(patch); ServiceDocumentDescription desc = ServiceDocumentDescription.Builder.create() .buildDescription(MergeTest.class); EnumSet<MergeResult> result = Utils.mergeWithStateAdvanced(desc, state, MergeTest.class, patchOperation); assertFalse(result.contains(MergeResult.SPECIAL_MERGE)); assertTrue(result.contains(MergeResult.STATE_CHANGED)); assertEquals("two", state.s); // repeating the update should not change the state anymore result = Utils.mergeWithStateAdvanced(desc, state, MergeTest.class, patchOperation); assertFalse(result.contains(MergeResult.SPECIAL_MERGE)); assertFalse(result.contains(MergeResult.STATE_CHANGED)); assertEquals("two", state.s); }
Utils.mergeWithStateAdvanced(description, currentState, stateClass, op); hasStateChanged |= mergeResult.contains(Utils.MergeResult.STATE_CHANGED);
@Test public void testMergeWithStateAdvanced() throws Throwable { MergeTest state = new MergeTest(); state.s = "one"; MergeTest patch = new MergeTest(); patch.s = "two"; Operation patchOperation = Operation.createPatch(new URI("http://test")).setBody(patch); ServiceDocumentDescription desc = ServiceDocumentDescription.Builder.create() .buildDescription(MergeTest.class); EnumSet<MergeResult> result = Utils.mergeWithStateAdvanced(desc, state, MergeTest.class, patchOperation); assertFalse(result.contains(MergeResult.SPECIAL_MERGE)); assertTrue(result.contains(MergeResult.STATE_CHANGED)); assertEquals("two", state.s); // repeating the update should not change the state anymore result = Utils.mergeWithStateAdvanced(desc, state, MergeTest.class, patchOperation); assertFalse(result.contains(MergeResult.SPECIAL_MERGE)); assertFalse(result.contains(MergeResult.STATE_CHANGED)); assertEquals("two", state.s); }