use of org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.OriginalFlow in project openflowplugin by opendaylight.
the class SalFlowServiceImplTest method updateFlow.
private void updateFlow(short version) throws Exception {
UpdateFlowInput mockedUpdateFlowInput = mock(UpdateFlowInput.class);
UpdateFlowInput mockedUpdateFlowInput1 = mock(UpdateFlowInput.class);
UpdatedFlow mockedUpdateFlow = new UpdatedFlowBuilder().setMatch(match).setTableId((short) 1).build();
UpdatedFlow mockedUpdateFlow1 = new UpdatedFlowBuilder().setMatch(match).setTableId((short) 1).setPriority(1).build();
when(mockedUpdateFlowInput.getUpdatedFlow()).thenReturn(mockedUpdateFlow);
when(mockedUpdateFlowInput1.getUpdatedFlow()).thenReturn(mockedUpdateFlow1);
FlowRef mockedFlowRef = mock(FlowRef.class);
Mockito.doReturn(TABLE_II.child(Flow.class, new FlowKey(new FlowId(DUMMY_FLOW_ID)))).when(mockedFlowRef).getValue();
when(mockedUpdateFlowInput.getFlowRef()).thenReturn(mockedFlowRef);
when(mockedUpdateFlowInput1.getFlowRef()).thenReturn(mockedFlowRef);
OriginalFlow mockedOriginalFlow = new OriginalFlowBuilder().setMatch(match).setTableId((short) 1).build();
OriginalFlow mockedOriginalFlow1 = new OriginalFlowBuilder().setMatch(match).setTableId((short) 1).setPriority(2).build();
when(mockedUpdateFlowInput.getOriginalFlow()).thenReturn(mockedOriginalFlow);
when(mockedUpdateFlowInput1.getOriginalFlow()).thenReturn(mockedOriginalFlow1);
SalFlowServiceImpl salFlowService = mockSalFlowService(version);
verifyOutput(salFlowService.updateFlow(mockedUpdateFlowInput));
verifyOutput(salFlowService.updateFlow(mockedUpdateFlowInput1));
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.OriginalFlow in project openflowplugin by opendaylight.
the class SalFlowServiceImpl method updateFlow.
@Override
public Future<RpcResult<UpdateFlowOutput>> updateFlow(final UpdateFlowInput input) {
final UpdatedFlow updated = input.getUpdatedFlow();
final OriginalFlow original = input.getOriginalFlow();
final List<FlowModInputBuilder> allFlowMods = new ArrayList<>();
final List<FlowModInputBuilder> ofFlowModInputs;
ListenableFuture<RpcResult<UpdateFlowOutput>> future;
if (flowUpdateMessage.canUseSingleLayerSerialization()) {
if (!FlowCreatorUtil.canModifyFlow(original, updated, flowUpdateMessage.getVersion())) {
final SettableFuture<RpcResult<UpdateFlowOutput>> objectSettableFuture = SettableFuture.create();
final ListenableFuture<List<RpcResult<UpdateFlowOutput>>> listListenableFuture = Futures.successfulAsList(flowUpdateMessage.handleServiceCall(input.getOriginalFlow()), flowUpdateMessage.handleServiceCall(input.getUpdatedFlow()));
Futures.addCallback(listListenableFuture, new FutureCallback<List<RpcResult<UpdateFlowOutput>>>() {
@Override
public void onSuccess(@Nonnull final List<RpcResult<UpdateFlowOutput>> results) {
final ArrayList<RpcError> errors = new ArrayList();
for (RpcResult<UpdateFlowOutput> flowModResult : results) {
if (flowModResult == null) {
errors.add(RpcResultBuilder.newError(RpcError.ErrorType.PROTOCOL, OFConstants.APPLICATION_TAG, "unexpected flowMod result (null) occurred"));
} else if (!flowModResult.isSuccessful()) {
errors.addAll(flowModResult.getErrors());
}
}
final RpcResultBuilder<UpdateFlowOutput> rpcResultBuilder;
if (errors.isEmpty()) {
rpcResultBuilder = RpcResultBuilder.success();
} else {
rpcResultBuilder = RpcResultBuilder.<UpdateFlowOutput>failed().withRpcErrors(errors);
}
objectSettableFuture.set(rpcResultBuilder.build());
}
@Override
public void onFailure(final Throwable throwable) {
RpcResultBuilder<UpdateFlowOutput> rpcResultBuilder = RpcResultBuilder.failed();
objectSettableFuture.set(rpcResultBuilder.build());
}
}, MoreExecutors.directExecutor());
future = objectSettableFuture;
} else {
future = flowUpdateMessage.handleServiceCall(input.getUpdatedFlow());
}
} else {
if (!FlowCreatorUtil.canModifyFlow(original, updated, flowUpdate.getVersion())) {
// We would need to remove original and add updated.
// remove flow
final RemoveFlowInputBuilder removeflow = new RemoveFlowInputBuilder(original);
final List<FlowModInputBuilder> ofFlowRemoveInput = flowUpdate.toFlowModInputs(removeflow.build());
// remove flow should be the first
allFlowMods.addAll(ofFlowRemoveInput);
final AddFlowInputBuilder addFlowInputBuilder = new AddFlowInputBuilder(updated);
ofFlowModInputs = flowUpdate.toFlowModInputs(addFlowInputBuilder.build());
} else {
ofFlowModInputs = flowUpdate.toFlowModInputs(updated);
}
allFlowMods.addAll(ofFlowModInputs);
future = flowUpdate.processFlowModInputBuilders(allFlowMods);
}
Futures.addCallback(future, new UpdateFlowCallback(input), MoreExecutors.directExecutor());
return future;
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.OriginalFlow in project openflowplugin by opendaylight.
the class FlowCreatorUtilTest method testCanModifyFlow.
/**
* Test method for
* {@link FlowCreatorUtil#canModifyFlow(OriginalFlow, UpdatedFlow, Short)}.
*/
@Test
public void testCanModifyFlow() {
final Short of10 = Short.valueOf(OFConstants.OFP_VERSION_1_0);
final Short of13 = Short.valueOf(OFConstants.OFP_VERSION_1_3);
final Short[] versions = { null, of10, of13 };
final Boolean[] bools = { null, Boolean.TRUE, Boolean.FALSE };
final Integer defPri = Integer.valueOf(0x8000);
final Integer defIdle = Integer.valueOf(0);
final Integer defHard = Integer.valueOf(0);
final FlowModFlags defFlags = FlowModFlags.getDefaultInstance("sENDFLOWREM");
final FlowModFlags flags = new FlowModFlags(false, true, false, true, false);
final FlowCookie defCookie = new FlowCookie(BigInteger.ZERO);
final FlowCookie cookie = new FlowCookie(BigInteger.valueOf(0x12345L));
final FlowCookie cookie1 = new FlowCookie(BigInteger.valueOf(0x67890L));
final FlowCookie cookieMask = new FlowCookie(BigInteger.valueOf(0xffff00L));
for (final Short ver : versions) {
final OriginalFlowBuilder originalBuilder = new OriginalFlowBuilder();
final UpdatedFlowBuilder updatedBuilder = new UpdatedFlowBuilder();
canModifyFlowTest(true, originalBuilder, updatedBuilder, ver);
// Default value tests.
canModifyFlowTest(true, new OriginalFlowBuilder().setPriority(defPri), updatedBuilder, ver);
canModifyFlowTest(true, originalBuilder, new UpdatedFlowBuilder().setPriority(defPri), ver);
canModifyFlowTest(true, new OriginalFlowBuilder().setIdleTimeout(defIdle), updatedBuilder, ver);
canModifyFlowTest(true, originalBuilder, new UpdatedFlowBuilder().setIdleTimeout(defIdle), ver);
canModifyFlowTest(true, new OriginalFlowBuilder().setHardTimeout(defHard), updatedBuilder, ver);
canModifyFlowTest(true, originalBuilder, new UpdatedFlowBuilder().setHardTimeout(defHard), ver);
canModifyFlowTest(false, new OriginalFlowBuilder().setFlags(defFlags), updatedBuilder, ver);
canModifyFlowTest(false, originalBuilder, new UpdatedFlowBuilder().setFlags(defFlags), ver);
canModifyFlowTest(true, new OriginalFlowBuilder().setCookie(defCookie), updatedBuilder, ver);
canModifyFlowTest(true, originalBuilder, new UpdatedFlowBuilder().setCookie(defCookie), ver);
// Set non-default values.
canModifyFlowTest(true, originalBuilder.setMatch(createMatch(0x800L)), updatedBuilder.setMatch(createMatch(0x800L)), ver);
canModifyFlowTest(true, originalBuilder.setIdleTimeout(600), updatedBuilder.setIdleTimeout(600), ver);
canModifyFlowTest(true, originalBuilder.setHardTimeout(1200), updatedBuilder.setHardTimeout(1200), ver);
canModifyFlowTest(true, originalBuilder.setPriority(100), updatedBuilder.setPriority(100), ver);
canModifyFlowTest(true, originalBuilder.setFlags(flags), updatedBuilder.setFlags(flags), ver);
canModifyFlowTest(true, originalBuilder.setCookie(cookie), updatedBuilder.setCookie(cookie), ver);
final OriginalFlow org = originalBuilder.build();
final UpdatedFlow upd = updatedBuilder.build();
// Set different match.
final org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match[] matches = { null, createMatch(0x86ddL) };
for (final org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match m : matches) {
canModifyFlowTest(false, originalBuilder, new UpdatedFlowBuilder(upd).setMatch(m), ver);
canModifyFlowTest(false, new OriginalFlowBuilder(org).setMatch(m), updatedBuilder, ver);
}
// Set different idle-timeout, hard-timeout, priority.
final Integer[] integers = { null, Integer.valueOf(3600) };
for (final Integer i : integers) {
canModifyFlowTest(false, originalBuilder, new UpdatedFlowBuilder(upd).setIdleTimeout(i), ver);
canModifyFlowTest(false, new OriginalFlowBuilder(org).setIdleTimeout(i), updatedBuilder, ver);
canModifyFlowTest(false, originalBuilder, new UpdatedFlowBuilder(upd).setHardTimeout(i), ver);
canModifyFlowTest(false, new OriginalFlowBuilder(org).setHardTimeout(i), updatedBuilder, ver);
canModifyFlowTest(false, originalBuilder, new UpdatedFlowBuilder(upd).setPriority(i), ver);
canModifyFlowTest(false, new OriginalFlowBuilder(org).setPriority(i), updatedBuilder, ver);
}
// Set different FLOW_MOD flags.
final FlowModFlags[] flowModFlags = { null, defFlags, new FlowModFlags(true, true, true, true, true) };
for (final FlowModFlags f : flowModFlags) {
canModifyFlowTest(false, originalBuilder, new UpdatedFlowBuilder(upd).setFlags(f), ver);
canModifyFlowTest(false, new OriginalFlowBuilder(org).setFlags(f), updatedBuilder, ver);
}
// Set different cookie.
final FlowCookie[] cookies = { null, defCookie, new FlowCookie(BigInteger.valueOf(0x123456L)) };
for (final FlowCookie c : cookies) {
canModifyFlowTest(false, originalBuilder, new UpdatedFlowBuilder(upd).setCookie(c), ver);
canModifyFlowTest(false, new OriginalFlowBuilder(org).setCookie(c), updatedBuilder, ver);
}
// Cookie mask test.
// Cookie mask is used by OF13 non-strict MODIFY command.
updatedBuilder.setCookie(cookie1);
for (final Boolean strict : bools) {
updatedBuilder.setCookieMask(null).setStrict(strict);
canModifyFlowTest(false, originalBuilder, updatedBuilder, ver);
updatedBuilder.setCookieMask(defCookie);
canModifyFlowTest(false, originalBuilder, updatedBuilder, ver);
updatedBuilder.setCookieMask(cookieMask);
final boolean expected = (of13.equals(ver) && !Boolean.TRUE.equals(strict));
canModifyFlowTest(expected, originalBuilder, updatedBuilder, ver);
}
}
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.OriginalFlow in project openflowplugin by opendaylight.
the class FlowForwarderTest method updateTest.
@Test
public void updateTest() throws Exception {
Mockito.when(salFlowService.updateFlow(updateFlowInputCpt.capture())).thenReturn(RpcResultBuilder.success(new UpdateFlowOutputBuilder().setTransactionId(new TransactionId(BigInteger.ONE)).build()).buildFuture());
final Instructions originalInstructions = new InstructionsBuilder().setInstruction(Collections.singletonList(new InstructionBuilder().setInstruction(new ApplyActionsCaseBuilder().setApplyActions(new ApplyActionsBuilder().setAction(Collections.singletonList(new ActionBuilder().setAction(new DropActionCaseBuilder().build()).build())).build()).build()).build())).build();
final Flow flowUpdated = new FlowBuilder(flow).setInstructions(originalInstructions).setMatch(new MatchBuilder().build()).build();
final Future<RpcResult<UpdateFlowOutput>> updateResult = flowForwarder.update(flowPath, flow, flowUpdated, flowCapableNodePath);
Mockito.verify(salFlowService).updateFlow(Matchers.<UpdateFlowInput>any());
final UpdateFlowInput updateFlowInput = updateFlowInputCpt.getValue();
final OriginalFlow flowOrigInput = updateFlowInput.getOriginalFlow();
final UpdatedFlow flowInput = updateFlowInput.getUpdatedFlow();
Assert.assertEquals(nodePath, updateFlowInput.getNode().getValue());
Assert.assertEquals(flowPath, updateFlowInput.getFlowRef().getValue());
Assert.assertEquals(2, flowInput.getTableId().shortValue());
Assert.assertEquals(emptyMatch, flowInput.getMatch());
Assert.assertEquals(originalInstructions, flowInput.getInstructions());
Assert.assertEquals(true, flowInput.isStrict());
Assert.assertEquals(2, flowOrigInput.getTableId().shortValue());
Assert.assertEquals(emptyMatch, flowOrigInput.getMatch());
Assert.assertEquals(null, flowOrigInput.getInstructions());
Assert.assertEquals(true, flowOrigInput.isStrict());
final RpcResult<UpdateFlowOutput> updateFlowOutputRpcResult = updateResult.get(2, TimeUnit.SECONDS);
Assert.assertTrue(updateFlowOutputRpcResult.isSuccessful());
final UpdateFlowOutput resultValue = updateFlowOutputRpcResult.getResult();
Assert.assertEquals(1, resultValue.getTransactionId().getValue().intValue());
}
use of org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.flow.update.OriginalFlow in project openflowplugin by opendaylight.
the class FlowCreatorUtil method canModifyFlow.
/**
* Determine whether a flow entry can be modified or not.
*
* @param original An original flow entry.
* @param updated An updated flow entry.
* @param version Protocol version.
* @return {@code true} only if a flow entry can be modified.
*/
public static boolean canModifyFlow(OriginalFlow original, UpdatedFlow updated, Short version) {
// flags, and cookie.
if (!Objects.equals(original.getMatch(), updated.getMatch()) || !equalsWithDefault(original.getPriority(), updated.getPriority(), FlowConvertor.DEFAULT_PRIORITY) || !equalsWithDefault(original.getIdleTimeout(), updated.getIdleTimeout(), FlowConvertor.DEFAULT_IDLE_TIMEOUT) || !equalsWithDefault(original.getHardTimeout(), updated.getHardTimeout(), FlowConvertor.DEFAULT_HARD_TIMEOUT) || !equalsFlowModFlags(original.getFlags(), updated.getFlags())) {
return false;
}
if (!Boolean.TRUE.equals(updated.isStrict()) && version != null && version.shortValue() != OFConstants.OFP_VERSION_1_0) {
FlowCookie cookieMask = updated.getCookieMask();
if (cookieMask != null) {
BigInteger mask = cookieMask.getValue();
if (mask != null && !mask.equals(BigInteger.ZERO)) {
// Allow FLOW_MOD with filtering by cookie.
return true;
}
}
}
FlowCookie oc = original.getCookie();
FlowCookie uc = updated.getCookie();
BigInteger orgCookie;
BigInteger updCookie;
if (oc == null) {
if (uc == null) {
return true;
}
orgCookie = OFConstants.DEFAULT_COOKIE;
updCookie = uc.getValue();
} else {
orgCookie = oc.getValue();
updCookie = (uc == null) ? OFConstants.DEFAULT_COOKIE : uc.getValue();
}
return equalsWithDefault(orgCookie, updCookie, OFConstants.DEFAULT_COOKIE);
}
Aggregations