Committed by
Gerrit Code Review
ONOS-1404 - Rerouting delayed due to flows being removed out of order
ONOS-1409 - handle all links to a switch going away and coming back Change-Id: Ib7216530fa8eef41b1088c5122a40bf9265481ca
Showing
8 changed files
with
93 additions
and
313 deletions
| ... | @@ -15,7 +15,15 @@ | ... | @@ -15,7 +15,15 @@ |
| 15 | */ | 15 | */ |
| 16 | package org.onosproject.net.intent.impl; | 16 | package org.onosproject.net.intent.impl; |
| 17 | 17 | ||
| 18 | -import com.google.common.collect.ImmutableList; | 18 | +import java.util.Collection; |
| 19 | +import java.util.EnumSet; | ||
| 20 | +import java.util.List; | ||
| 21 | +import java.util.Map; | ||
| 22 | +import java.util.concurrent.ExecutionException; | ||
| 23 | +import java.util.concurrent.ExecutorService; | ||
| 24 | +import java.util.concurrent.Future; | ||
| 25 | +import java.util.stream.Collectors; | ||
| 26 | + | ||
| 19 | import org.apache.felix.scr.annotations.Activate; | 27 | import org.apache.felix.scr.annotations.Activate; |
| 20 | import org.apache.felix.scr.annotations.Component; | 28 | import org.apache.felix.scr.annotations.Component; |
| 21 | import org.apache.felix.scr.annotations.Deactivate; | 29 | import org.apache.felix.scr.annotations.Deactivate; |
| ... | @@ -48,15 +56,7 @@ import org.onosproject.net.intent.impl.phase.IntentProcessPhase; | ... | @@ -48,15 +56,7 @@ import org.onosproject.net.intent.impl.phase.IntentProcessPhase; |
| 48 | import org.onosproject.net.intent.impl.phase.IntentWorker; | 56 | import org.onosproject.net.intent.impl.phase.IntentWorker; |
| 49 | import org.slf4j.Logger; | 57 | import org.slf4j.Logger; |
| 50 | 58 | ||
| 51 | -import java.util.Collection; | 59 | +import com.google.common.collect.ImmutableList; |
| 52 | -import java.util.Collections; | ||
| 53 | -import java.util.EnumSet; | ||
| 54 | -import java.util.List; | ||
| 55 | -import java.util.Map; | ||
| 56 | -import java.util.concurrent.ExecutionException; | ||
| 57 | -import java.util.concurrent.ExecutorService; | ||
| 58 | -import java.util.concurrent.Future; | ||
| 59 | -import java.util.stream.Collectors; | ||
| 60 | 60 | ||
| 61 | import static com.google.common.base.Preconditions.checkNotNull; | 61 | import static com.google.common.base.Preconditions.checkNotNull; |
| 62 | import static java.util.concurrent.Executors.newFixedThreadPool; | 62 | import static java.util.concurrent.Executors.newFixedThreadPool; |
| ... | @@ -359,97 +359,92 @@ public class IntentManager | ... | @@ -359,97 +359,92 @@ public class IntentManager |
| 359 | } | 359 | } |
| 360 | 360 | ||
| 361 | @Override | 361 | @Override |
| 362 | - public void install(IntentData data) { | 362 | + public void apply(IntentData toUninstall, IntentData toInstall) { |
| 363 | - IntentManager.this.install(data); | 363 | + IntentManager.this.apply(toUninstall, toInstall); |
| 364 | } | 364 | } |
| 365 | - | ||
| 366 | - @Override | ||
| 367 | - public void uninstall(IntentData data) { | ||
| 368 | - IntentManager.this.uninstall(data); | ||
| 369 | - } | ||
| 370 | - | ||
| 371 | } | 365 | } |
| 372 | 366 | ||
| 373 | - private void install(IntentData data) { | 367 | + private enum Direction { |
| 374 | - // need to consider if FlowRuleIntent is only one as installable intent or not | 368 | + ADD, |
| 375 | - List<Intent> installables = data.installables(); | 369 | + REMOVE |
| 376 | - if (!installables.stream().allMatch(x -> x instanceof FlowRuleIntent)) { | 370 | + } |
| 377 | - throw new IllegalStateException("installable intents must be FlowRuleIntent"); | ||
| 378 | - } | ||
| 379 | 371 | ||
| 380 | - trackerService.addTrackedResources(data.key(), data.intent().resources()); | 372 | + private void applyIntentData(IntentData data, |
| 381 | - installables.forEach(installable -> | 373 | + FlowRuleOperations.Builder builder, |
| 382 | - trackerService.addTrackedResources(data.key(), installable.resources())); | 374 | + Direction direction) { |
| 375 | + if (data != null) { | ||
| 376 | + List<Intent> intentsToApply = data.installables(); | ||
| 377 | + if (!intentsToApply.stream().allMatch(x -> x instanceof FlowRuleIntent)) { | ||
| 378 | + throw new IllegalStateException("installable intents must be FlowRuleIntent"); | ||
| 379 | + } | ||
| 383 | 380 | ||
| 384 | - List<Collection<FlowRule>> stages = installables.stream() | 381 | + if (direction == Direction.ADD) { |
| 385 | - .map(x -> (FlowRuleIntent) x) | 382 | + trackerService.addTrackedResources(data.key(), data.intent().resources()); |
| 386 | - .map(FlowRuleIntent::flowRules) | 383 | + intentsToApply.forEach(installable -> |
| 387 | - .collect(Collectors.toList()); | 384 | + trackerService.addTrackedResources(data.key(), installable.resources())); |
| 385 | + } else { | ||
| 386 | + trackerService.removeTrackedResources(data.key(), data.intent().resources()); | ||
| 387 | + intentsToApply.forEach(installable -> | ||
| 388 | + trackerService.removeTrackedResources(data.intent().key(), | ||
| 389 | + installable.resources())); | ||
| 390 | + } | ||
| 388 | 391 | ||
| 389 | - FlowRuleOperations.Builder builder = FlowRuleOperations.builder(); | 392 | + // FIXME do FlowRuleIntents have stages??? Can we do uninstall work in parallel? I think so. |
| 390 | - for (Collection<FlowRule> rules : stages) { | ||
| 391 | - rules.forEach(builder::add); | ||
| 392 | builder.newStage(); | 393 | builder.newStage(); |
| 393 | - } | ||
| 394 | 394 | ||
| 395 | - FlowRuleOperations operations = builder.build(new FlowRuleOperationsContext() { | 395 | + List<Collection<FlowRule>> stages = intentsToApply.stream() |
| 396 | - @Override | 396 | + .map(x -> (FlowRuleIntent) x) |
| 397 | - public void onSuccess(FlowRuleOperations ops) { | 397 | + .map(FlowRuleIntent::flowRules) |
| 398 | - log.debug("Completed installing: {}", data.key()); | 398 | + .collect(Collectors.toList()); |
| 399 | - data.setState(INSTALLED); | ||
| 400 | - store.write(data); | ||
| 401 | - } | ||
| 402 | 399 | ||
| 403 | - @Override | 400 | + for (Collection<FlowRule> rules : stages) { |
| 404 | - public void onError(FlowRuleOperations ops) { | 401 | + if (direction == Direction.ADD) { |
| 405 | - log.warn("Failed installation: {} {} on {}", data.key(), data.intent(), ops); | 402 | + rules.forEach(builder::add); |
| 406 | - data.setState(FAILED); | 403 | + } else { |
| 407 | - store.write(data); | 404 | + rules.forEach(builder::remove); |
| 405 | + } | ||
| 408 | } | 406 | } |
| 409 | - }); | ||
| 410 | - | ||
| 411 | - flowRuleService.apply(operations); | ||
| 412 | - } | ||
| 413 | - | ||
| 414 | - private void uninstall(IntentData data) { | ||
| 415 | - List<Intent> installables = data.installables(); | ||
| 416 | - if (!installables.stream().allMatch(x -> x instanceof FlowRuleIntent)) { | ||
| 417 | - throw new IllegalStateException("installable intents must be FlowRuleIntent"); | ||
| 418 | } | 407 | } |
| 419 | 408 | ||
| 420 | - trackerService.removeTrackedResources(data.key(), data.intent().resources()); | 409 | + } |
| 421 | - installables.forEach(installable -> | ||
| 422 | - trackerService.removeTrackedResources(data.intent().key(), | ||
| 423 | - installable.resources())); | ||
| 424 | 410 | ||
| 425 | - List<Collection<FlowRule>> stages = installables.stream() | 411 | + private void apply(IntentData toUninstall, IntentData toInstall) { |
| 426 | - .map(x -> (FlowRuleIntent) x) | 412 | + // need to consider if FlowRuleIntent is only one as installable intent or not |
| 427 | - .map(FlowRuleIntent::flowRules) | ||
| 428 | - .collect(Collectors.toList()); | ||
| 429 | 413 | ||
| 430 | FlowRuleOperations.Builder builder = FlowRuleOperations.builder(); | 414 | FlowRuleOperations.Builder builder = FlowRuleOperations.builder(); |
| 431 | - for (Collection<FlowRule> rules : stages) { | 415 | + applyIntentData(toUninstall, builder, Direction.REMOVE); |
| 432 | - rules.forEach(builder::remove); | 416 | + applyIntentData(toInstall, builder, Direction.ADD); |
| 433 | - builder.newStage(); | ||
| 434 | - } | ||
| 435 | 417 | ||
| 436 | FlowRuleOperations operations = builder.build(new FlowRuleOperationsContext() { | 418 | FlowRuleOperations operations = builder.build(new FlowRuleOperationsContext() { |
| 437 | @Override | 419 | @Override |
| 438 | public void onSuccess(FlowRuleOperations ops) { | 420 | public void onSuccess(FlowRuleOperations ops) { |
| 439 | - log.debug("Completed withdrawing: {}", data.key()); | 421 | + if (toInstall != null) { |
| 440 | - data.setState(WITHDRAWN); | 422 | + log.debug("Completed installing: {}", toInstall.key()); |
| 441 | - data.setInstallables(Collections.emptyList()); | 423 | + //FIXME state depends on install.... we might want to pass this in. |
| 442 | - store.write(data); | 424 | + toInstall.setState(INSTALLED); |
| 425 | + store.write(toInstall); | ||
| 426 | + } else if (toUninstall != null) { | ||
| 427 | + log.debug("Completed withdrawing: {}", toUninstall.key()); | ||
| 428 | + //FIXME state depends on install.... we might want to pass this in. | ||
| 429 | + toUninstall.setState(WITHDRAWN); | ||
| 430 | + store.write(toUninstall); | ||
| 431 | + } | ||
| 443 | } | 432 | } |
| 444 | 433 | ||
| 445 | @Override | 434 | @Override |
| 446 | public void onError(FlowRuleOperations ops) { | 435 | public void onError(FlowRuleOperations ops) { |
| 447 | - log.warn("Failed withdraw: {}", data.key()); | 436 | + if (toInstall != null) { |
| 448 | - data.setState(FAILED); | 437 | + log.warn("Failed installation: {} {} on {}", toInstall.key(), toInstall.intent(), ops); |
| 449 | - store.write(data); | 438 | + //FIXME |
| 439 | + toInstall.setState(FAILED); | ||
| 440 | + store.write(toInstall); | ||
| 441 | + } | ||
| 442 | + // if toInstall was cause of error, then recompile (manage/increment counter, when exceeded -> CORRUPT) | ||
| 443 | + // if toUninstall was cause of error, then CORRUPT (another job will lean this up) | ||
| 450 | } | 444 | } |
| 451 | }); | 445 | }); |
| 452 | 446 | ||
| 453 | flowRuleService.apply(operations); | 447 | flowRuleService.apply(operations); |
| 454 | } | 448 | } |
| 449 | + | ||
| 455 | } | 450 | } | ... | ... |
| ... | @@ -38,16 +38,8 @@ public interface IntentProcessor { | ... | @@ -38,16 +38,8 @@ public interface IntentProcessor { |
| 38 | List<Intent> compile(Intent intent, List<Intent> previousInstallables); | 38 | List<Intent> compile(Intent intent, List<Intent> previousInstallables); |
| 39 | 39 | ||
| 40 | /** | 40 | /** |
| 41 | - * Installs an intent included in the specified intent data. | 41 | + * @param toUninstall Intent data describing flows to uninstall. May be null. |
| 42 | - * | 42 | + * @param toInstall Intent data describing flows to install. May be null. |
| 43 | - * @param data intent data containing an intent to be installed | ||
| 44 | - */ | ||
| 45 | - void install(IntentData data); | ||
| 46 | - | ||
| 47 | - /** | ||
| 48 | - * Uninstalls an intent included in the specified intent data. | ||
| 49 | - * | ||
| 50 | - * @param data intent data containing an intent to be uninstalled | ||
| 51 | */ | 43 | */ |
| 52 | - void uninstall(IntentData data); | 44 | + void apply(IntentData toUninstall, IntentData toInstall); |
| 53 | } | 45 | } | ... | ... |
| ... | @@ -50,7 +50,7 @@ final class Compiling implements IntentProcessPhase { | ... | @@ -50,7 +50,7 @@ final class Compiling implements IntentProcessPhase { |
| 50 | public Optional<IntentProcessPhase> execute() { | 50 | public Optional<IntentProcessPhase> execute() { |
| 51 | try { | 51 | try { |
| 52 | data.setInstallables(processor.compile(data.intent(), null)); | 52 | data.setInstallables(processor.compile(data.intent(), null)); |
| 53 | - return Optional.of(new Installing(processor, data)); | 53 | + return Optional.of(new Installing(processor, data, null)); |
| 54 | } catch (IntentException e) { | 54 | } catch (IntentException e) { |
| 55 | log.debug("Unable to compile intent {} due to: {}", data.intent(), e); | 55 | log.debug("Unable to compile intent {} due to: {}", data.intent(), e); |
| 56 | return Optional.of(new CompileFailed(data)); | 56 | return Optional.of(new CompileFailed(data)); | ... | ... |
| ... | @@ -28,6 +28,7 @@ class Installing extends FinalIntentProcessPhase { | ... | @@ -28,6 +28,7 @@ class Installing extends FinalIntentProcessPhase { |
| 28 | 28 | ||
| 29 | private final IntentProcessor processor; | 29 | private final IntentProcessor processor; |
| 30 | private final IntentData data; | 30 | private final IntentData data; |
| 31 | + private final IntentData stored; | ||
| 31 | 32 | ||
| 32 | /** | 33 | /** |
| 33 | * Create an installing phase. | 34 | * Create an installing phase. |
| ... | @@ -35,15 +36,16 @@ class Installing extends FinalIntentProcessPhase { | ... | @@ -35,15 +36,16 @@ class Installing extends FinalIntentProcessPhase { |
| 35 | * @param processor intent processor that does work for installing | 36 | * @param processor intent processor that does work for installing |
| 36 | * @param data intent data containing an intent to be installed | 37 | * @param data intent data containing an intent to be installed |
| 37 | */ | 38 | */ |
| 38 | - Installing(IntentProcessor processor, IntentData data) { | 39 | + Installing(IntentProcessor processor, IntentData data, IntentData stored) { |
| 39 | this.processor = checkNotNull(processor); | 40 | this.processor = checkNotNull(processor); |
| 40 | this.data = checkNotNull(data); | 41 | this.data = checkNotNull(data); |
| 41 | this.data.setState(INSTALLING); | 42 | this.data.setState(INSTALLING); |
| 43 | + this.stored = stored; | ||
| 42 | } | 44 | } |
| 43 | 45 | ||
| 44 | @Override | 46 | @Override |
| 45 | public void preExecute() { | 47 | public void preExecute() { |
| 46 | - processor.install(data); | 48 | + processor.apply(stored, data); |
| 47 | } | 49 | } |
| 48 | 50 | ||
| 49 | @Override | 51 | @Override | ... | ... |
| ... | @@ -17,7 +17,10 @@ package org.onosproject.net.intent.impl.phase; | ... | @@ -17,7 +17,10 @@ package org.onosproject.net.intent.impl.phase; |
| 17 | 17 | ||
| 18 | import org.onosproject.net.intent.Intent; | 18 | import org.onosproject.net.intent.Intent; |
| 19 | import org.onosproject.net.intent.IntentData; | 19 | import org.onosproject.net.intent.IntentData; |
| 20 | +import org.onosproject.net.intent.IntentException; | ||
| 20 | import org.onosproject.net.intent.impl.IntentProcessor; | 21 | import org.onosproject.net.intent.impl.IntentProcessor; |
| 22 | +import org.slf4j.Logger; | ||
| 23 | +import org.slf4j.LoggerFactory; | ||
| 21 | 24 | ||
| 22 | import java.util.List; | 25 | import java.util.List; |
| 23 | import java.util.Optional; | 26 | import java.util.Optional; |
| ... | @@ -29,6 +32,8 @@ import static com.google.common.base.Preconditions.checkNotNull; | ... | @@ -29,6 +32,8 @@ import static com.google.common.base.Preconditions.checkNotNull; |
| 29 | */ | 32 | */ |
| 30 | class Recompiling implements IntentProcessPhase { | 33 | class Recompiling implements IntentProcessPhase { |
| 31 | 34 | ||
| 35 | + private static final Logger log = LoggerFactory.getLogger(Recompiling.class); | ||
| 36 | + | ||
| 32 | private final IntentProcessor processor; | 37 | private final IntentProcessor processor; |
| 33 | private final IntentData data; | 38 | private final IntentData data; |
| 34 | private final IntentData stored; | 39 | private final IntentData stored; |
| ... | @@ -48,8 +53,14 @@ class Recompiling implements IntentProcessPhase { | ... | @@ -48,8 +53,14 @@ class Recompiling implements IntentProcessPhase { |
| 48 | 53 | ||
| 49 | @Override | 54 | @Override |
| 50 | public Optional<IntentProcessPhase> execute() { | 55 | public Optional<IntentProcessPhase> execute() { |
| 51 | - List<Intent> compiled = processor.compile(data.intent(), stored.installables()); | 56 | + try { |
| 52 | - data.setInstallables(compiled); | 57 | + List<Intent> compiled = processor.compile(data.intent(), stored.installables()); |
| 53 | - return Optional.of(new Replacing(processor, data, stored)); | 58 | + data.setInstallables(compiled); |
| 59 | + return Optional.of(new Installing(processor, data, stored)); | ||
| 60 | + } catch (IntentException e) { | ||
| 61 | + log.debug("Unable to recompile intent {} due to: {}", data.intent(), e); | ||
| 62 | + // FIXME we need to removed orphaned flows and deallocate resources | ||
| 63 | + return Optional.of(new CompileFailed(data)); | ||
| 64 | + } | ||
| 54 | } | 65 | } |
| 55 | } | 66 | } | ... | ... |
| 1 | -/* | ||
| 2 | - * Copyright 2015 Open Networking Laboratory | ||
| 3 | - * | ||
| 4 | - * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | - * you may not use this file except in compliance with the License. | ||
| 6 | - * You may obtain a copy of the License at | ||
| 7 | - * | ||
| 8 | - * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | - * | ||
| 10 | - * Unless required by applicable law or agreed to in writing, software | ||
| 11 | - * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | - * See the License for the specific language governing permissions and | ||
| 14 | - * limitations under the License. | ||
| 15 | - */ | ||
| 16 | -package org.onosproject.net.intent.impl.phase; | ||
| 17 | - | ||
| 18 | -import org.onosproject.net.intent.IntentData; | ||
| 19 | -import org.onosproject.net.intent.IntentException; | ||
| 20 | -import org.onosproject.net.intent.impl.IntentProcessor; | ||
| 21 | -import org.slf4j.Logger; | ||
| 22 | -import org.slf4j.LoggerFactory; | ||
| 23 | - | ||
| 24 | -import java.util.Optional; | ||
| 25 | - | ||
| 26 | -import static com.google.common.base.Preconditions.checkNotNull; | ||
| 27 | - | ||
| 28 | -/** | ||
| 29 | - * Represents a phase to replace an intent. | ||
| 30 | - */ | ||
| 31 | -final class Replacing implements IntentProcessPhase { | ||
| 32 | - | ||
| 33 | - private static final Logger log = LoggerFactory.getLogger(Replacing.class); | ||
| 34 | - | ||
| 35 | - private final IntentProcessor processor; | ||
| 36 | - private final IntentData data; | ||
| 37 | - private final IntentData stored; | ||
| 38 | - | ||
| 39 | - /** | ||
| 40 | - * Creates a replacing phase. | ||
| 41 | - * | ||
| 42 | - * @param processor intent processor that does work for replacing | ||
| 43 | - * @param data intent data containing an intent to be replaced | ||
| 44 | - * @param stored intent data stored in the store | ||
| 45 | - */ | ||
| 46 | - Replacing(IntentProcessor processor, IntentData data, IntentData stored) { | ||
| 47 | - this.processor = checkNotNull(processor); | ||
| 48 | - this.data = checkNotNull(data); | ||
| 49 | - this.stored = checkNotNull(stored); | ||
| 50 | - } | ||
| 51 | - | ||
| 52 | - @Override | ||
| 53 | - public Optional<IntentProcessPhase> execute() { | ||
| 54 | - try { | ||
| 55 | - processor.uninstall(stored); | ||
| 56 | - return Optional.of(new Installing(processor, data)); | ||
| 57 | - } catch (IntentException e) { | ||
| 58 | - log.warn("Unable to generate a FlowRuleOperations from intent {} due to:", data.intent().id(), e); | ||
| 59 | - return Optional.of(new ReplaceFailed(data)); | ||
| 60 | - } | ||
| 61 | - } | ||
| 62 | -} |
| ... | @@ -44,7 +44,7 @@ class Withdrawing extends FinalIntentProcessPhase { | ... | @@ -44,7 +44,7 @@ class Withdrawing extends FinalIntentProcessPhase { |
| 44 | 44 | ||
| 45 | @Override | 45 | @Override |
| 46 | protected void preExecute() { | 46 | protected void preExecute() { |
| 47 | - processor.uninstall(data); | 47 | + processor.apply(data, null); |
| 48 | } | 48 | } |
| 49 | 49 | ||
| 50 | @Override | 50 | @Override | ... | ... |
| 1 | -/* | ||
| 2 | - * Copyright 2015 Open Networking Laboratory | ||
| 3 | - * | ||
| 4 | - * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| 5 | - * you may not use this file except in compliance with the License. | ||
| 6 | - * You may obtain a copy of the License at | ||
| 7 | - * | ||
| 8 | - * http://www.apache.org/licenses/LICENSE-2.0 | ||
| 9 | - * | ||
| 10 | - * Unless required by applicable law or agreed to in writing, software | ||
| 11 | - * distributed under the License is distributed on an "AS IS" BASIS, | ||
| 12 | - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| 13 | - * See the License for the specific language governing permissions and | ||
| 14 | - * limitations under the License. | ||
| 15 | - */ | ||
| 16 | -package org.onosproject.net.intent.impl.phase; | ||
| 17 | - | ||
| 18 | -import org.junit.After; | ||
| 19 | -import org.junit.Before; | ||
| 20 | -import org.junit.Test; | ||
| 21 | -import org.onosproject.TestApplicationId; | ||
| 22 | -import org.onosproject.core.ApplicationId; | ||
| 23 | -import org.onosproject.core.IdGenerator; | ||
| 24 | -import org.onosproject.net.ConnectPoint; | ||
| 25 | -import org.onosproject.net.DefaultLink; | ||
| 26 | -import org.onosproject.net.DefaultPath; | ||
| 27 | -import org.onosproject.net.Link; | ||
| 28 | -import org.onosproject.net.Path; | ||
| 29 | -import org.onosproject.net.flow.DefaultTrafficSelector; | ||
| 30 | -import org.onosproject.net.flow.DefaultTrafficTreatment; | ||
| 31 | -import org.onosproject.net.flow.TrafficSelector; | ||
| 32 | -import org.onosproject.net.flow.TrafficTreatment; | ||
| 33 | -import org.onosproject.net.intent.Intent; | ||
| 34 | -import org.onosproject.net.intent.IntentData; | ||
| 35 | -import org.onosproject.net.intent.MockIdGenerator; | ||
| 36 | -import org.onosproject.net.intent.PathIntent; | ||
| 37 | -import org.onosproject.net.intent.PointToPointIntent; | ||
| 38 | -import org.onosproject.net.intent.impl.IntentInstallationException; | ||
| 39 | -import org.onosproject.net.intent.impl.IntentProcessor; | ||
| 40 | -import org.onosproject.net.provider.ProviderId; | ||
| 41 | -import org.onosproject.store.Timestamp; | ||
| 42 | - | ||
| 43 | -import java.util.Arrays; | ||
| 44 | -import java.util.List; | ||
| 45 | -import java.util.Optional; | ||
| 46 | - | ||
| 47 | -import static org.easymock.EasyMock.createMock; | ||
| 48 | -import static org.easymock.EasyMock.expectLastCall; | ||
| 49 | -import static org.easymock.EasyMock.replay; | ||
| 50 | -import static org.easymock.EasyMock.verify; | ||
| 51 | -import static org.hamcrest.Matchers.instanceOf; | ||
| 52 | -import static org.hamcrest.Matchers.is; | ||
| 53 | -import static org.junit.Assert.assertThat; | ||
| 54 | -import static org.onosproject.net.DeviceId.deviceId; | ||
| 55 | -import static org.onosproject.net.Link.Type.DIRECT; | ||
| 56 | -import static org.onosproject.net.PortNumber.portNumber; | ||
| 57 | -import static org.onosproject.net.intent.IntentState.INSTALLED; | ||
| 58 | -import static org.onosproject.net.intent.IntentState.INSTALL_REQ; | ||
| 59 | - | ||
| 60 | -/** | ||
| 61 | - * Unit tests for InstallingCoordinating phase. | ||
| 62 | - */ | ||
| 63 | -public class ReplacingTest { | ||
| 64 | - | ||
| 65 | - private final ApplicationId appId = new TestApplicationId("test"); | ||
| 66 | - private final ProviderId pid = new ProviderId("of", "test"); | ||
| 67 | - private final TrafficSelector selector = DefaultTrafficSelector.emptySelector(); | ||
| 68 | - private final TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment(); | ||
| 69 | - private final ConnectPoint cp1 = new ConnectPoint(deviceId("1"), portNumber(1)); | ||
| 70 | - private final ConnectPoint cp2 = new ConnectPoint(deviceId("1"), portNumber(2)); | ||
| 71 | - private final ConnectPoint cp3 = new ConnectPoint(deviceId("2"), portNumber(1)); | ||
| 72 | - private final ConnectPoint cp4 = new ConnectPoint(deviceId("2"), portNumber(2)); | ||
| 73 | - | ||
| 74 | - private final List<Link> links = Arrays.asList(new DefaultLink(pid, cp2, cp4, DIRECT)); | ||
| 75 | - private final Path path = new DefaultPath(pid, links, 10); | ||
| 76 | - | ||
| 77 | - private PointToPointIntent input; | ||
| 78 | - private PathIntent compiled; | ||
| 79 | - | ||
| 80 | - private IdGenerator idGenerator; | ||
| 81 | - private IntentProcessor processor; | ||
| 82 | - private Timestamp version; | ||
| 83 | - | ||
| 84 | - @Before | ||
| 85 | - public void setUp() { | ||
| 86 | - processor = createMock(IntentProcessor.class); | ||
| 87 | - version = createMock(Timestamp.class); | ||
| 88 | - | ||
| 89 | - idGenerator = new MockIdGenerator(); | ||
| 90 | - | ||
| 91 | - Intent.bindIdGenerator(idGenerator); | ||
| 92 | - | ||
| 93 | - // Intent creation should be placed after binding an ID generator | ||
| 94 | - input = PointToPointIntent.builder() | ||
| 95 | - .appId(appId) | ||
| 96 | - .selector(selector) | ||
| 97 | - .treatment(treatment) | ||
| 98 | - .ingressPoint(cp1) | ||
| 99 | - .egressPoint(cp3) | ||
| 100 | - .build(); | ||
| 101 | - compiled = PathIntent.builder() | ||
| 102 | - .appId(appId) | ||
| 103 | - .selector(selector) | ||
| 104 | - .treatment(treatment) | ||
| 105 | - .path(path) | ||
| 106 | - .build(); | ||
| 107 | - } | ||
| 108 | - | ||
| 109 | - | ||
| 110 | - @After | ||
| 111 | - public void tearDown() { | ||
| 112 | - Intent.unbindIdGenerator(idGenerator); | ||
| 113 | - } | ||
| 114 | - | ||
| 115 | - /** | ||
| 116 | - * Tests a next phase when no exception occurs. | ||
| 117 | - */ | ||
| 118 | - @Test | ||
| 119 | - public void testMoveToNextPhaseWithoutError() { | ||
| 120 | - IntentData pending = new IntentData(input, INSTALL_REQ, version); | ||
| 121 | - pending.setInstallables(Arrays.asList(compiled)); | ||
| 122 | - | ||
| 123 | - IntentData current = new IntentData(input, INSTALLED, version); | ||
| 124 | - current.setInstallables(Arrays.asList(compiled)); | ||
| 125 | - | ||
| 126 | - processor.uninstall(current); | ||
| 127 | - replay(processor); | ||
| 128 | - | ||
| 129 | - Replacing sut = new Replacing(processor, pending, current); | ||
| 130 | - | ||
| 131 | - Optional<IntentProcessPhase> executed = sut.execute(); | ||
| 132 | - | ||
| 133 | - verify(processor); | ||
| 134 | - assertThat(executed.get(), is(instanceOf(Installing.class))); | ||
| 135 | - } | ||
| 136 | - | ||
| 137 | - /** | ||
| 138 | - * Tests a next phase when IntentInstallationException occurs. | ||
| 139 | - */ | ||
| 140 | - @Test | ||
| 141 | - public void testWhenIntentInstallExceptionOccurs() { | ||
| 142 | - IntentData pending = new IntentData(input, INSTALL_REQ, version); | ||
| 143 | - pending.setInstallables(Arrays.asList(compiled)); | ||
| 144 | - | ||
| 145 | - IntentData current = new IntentData(input, INSTALLED, version); | ||
| 146 | - | ||
| 147 | - processor.uninstall(current); | ||
| 148 | - expectLastCall().andThrow(new IntentInstallationException()); | ||
| 149 | - replay(processor); | ||
| 150 | - | ||
| 151 | - Replacing sut = new Replacing(processor, pending, current); | ||
| 152 | - | ||
| 153 | - Optional<IntentProcessPhase> executed = sut.execute(); | ||
| 154 | - | ||
| 155 | - verify(processor); | ||
| 156 | - assertThat(executed.get(), is(instanceOf(ReplaceFailed.class))); | ||
| 157 | - } | ||
| 158 | -} |
-
Please register or login to post a comment