Toggle navigation
Toggle navigation
This project
Loading...
Sign in
홍길동
/
onos
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Snippets
Network
Create a new issue
Builds
Commits
Issue Boards
Authored by
Brian O'Connor
2014-10-07 21:55:33 -0700
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
cb900f4eb6c9270c30c83ef4c95e6e0c0e8c6450
cb900f4e
1 parent
31b8eabe
Initial implementation of async installers
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
256 additions
and
44 deletions
core/api/src/main/java/org/onlab/onos/net/intent/IntentInstaller.java
core/api/src/test/java/org/onlab/onos/net/intent/IntentServiceTest.java
core/net/src/main/java/org/onlab/onos/net/intent/impl/IntentManager.java
core/net/src/main/java/org/onlab/onos/net/intent/impl/PathIntentInstaller.java
core/api/src/main/java/org/onlab/onos/net/intent/IntentInstaller.java
View file @
cb900f4
package
org
.
onlab
.
onos
.
net
.
intent
;
import
java.util.concurrent.Future
;
import
org.onlab.onos.net.flow.CompletedBatchOperation
;
/**
* Abstraction of entity capable of installing intents to the environment.
*/
...
...
@@ -10,7 +14,7 @@ public interface IntentInstaller<T extends InstallableIntent> {
* @param intent intent to be installed
* @throws IntentException if issues are encountered while installing the intent
*/
void
install
(
T
intent
);
Future
<
CompletedBatchOperation
>
install
(
T
intent
);
/**
* Uninstalls the specified intent from the environment.
...
...
@@ -18,5 +22,5 @@ public interface IntentInstaller<T extends InstallableIntent> {
* @param intent intent to be uninstalled
* @throws IntentException if issues are encountered while uninstalling the intent
*/
void
uninstall
(
T
intent
);
Future
<
CompletedBatchOperation
>
uninstall
(
T
intent
);
}
...
...
core/api/src/test/java/org/onlab/onos/net/intent/IntentServiceTest.java
View file @
cb900f4
package
org
.
onlab
.
onos
.
net
.
intent
;
import
org.junit.After
;
import
org.junit.Before
;
import
org.junit.Test
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
junit
.
Assert
.
assertFalse
;
import
static
org
.
junit
.
Assert
.
assertNull
;
import
static
org
.
junit
.
Assert
.
fail
;
import
static
org
.
onlab
.
onos
.
net
.
intent
.
IntentEvent
.
Type
.
FAILED
;
import
static
org
.
onlab
.
onos
.
net
.
intent
.
IntentEvent
.
Type
.
INSTALLED
;
import
static
org
.
onlab
.
onos
.
net
.
intent
.
IntentEvent
.
Type
.
SUBMITTED
;
import
static
org
.
onlab
.
onos
.
net
.
intent
.
IntentEvent
.
Type
.
WITHDRAWN
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.Collections
;
import
java.util.Iterator
;
import
java.util.List
;
import
java.util.concurrent.Future
;
import
static
org
.
junit
.
Assert
.*;
import
static
org
.
onlab
.
onos
.
net
.
intent
.
IntentEvent
.
Type
.*;
import
org.junit.After
;
import
org.junit.Before
;
import
org.junit.Test
;
import
org.onlab.onos.net.flow.CompletedBatchOperation
;
/**
* Suite of tests for the intent service contract.
...
...
@@ -290,17 +298,19 @@ public class IntentServiceTest {
}
@Override
public
void
install
(
TestInstallableIntent
intent
)
{
public
Future
<
CompletedBatchOperation
>
install
(
TestInstallableIntent
intent
)
{
if
(
fail
)
{
throw
new
IntentException
(
"install failed by design"
);
}
return
null
;
}
@Override
public
void
uninstall
(
TestInstallableIntent
intent
)
{
public
Future
<
CompletedBatchOperation
>
uninstall
(
TestInstallableIntent
intent
)
{
if
(
fail
)
{
throw
new
IntentException
(
"remove failed by design"
);
}
return
null
;
}
}
...
...
core/net/src/main/java/org/onlab/onos/net/intent/impl/IntentManager.java
View file @
cb900f4
...
...
@@ -13,12 +13,14 @@ import static org.onlab.util.Tools.namedThreads;
import
static
org
.
slf4j
.
LoggerFactory
.
getLogger
;
import
java.util.ArrayList
;
import
java.util.Iterator
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Objects
;
import
java.util.concurrent.ConcurrentHashMap
;
import
java.util.concurrent.ConcurrentMap
;
import
java.util.concurrent.ExecutorService
;
import
java.util.concurrent.Future
;
import
org.apache.felix.scr.annotations.Activate
;
import
org.apache.felix.scr.annotations.Component
;
...
...
@@ -28,6 +30,7 @@ import org.apache.felix.scr.annotations.ReferenceCardinality;
import
org.apache.felix.scr.annotations.Service
;
import
org.onlab.onos.event.AbstractListenerRegistry
;
import
org.onlab.onos.event.EventDeliveryService
;
import
org.onlab.onos.net.flow.CompletedBatchOperation
;
import
org.onlab.onos.net.intent.InstallableIntent
;
import
org.onlab.onos.net.intent.Intent
;
import
org.onlab.onos.net.intent.IntentCompiler
;
...
...
@@ -44,7 +47,9 @@ import org.onlab.onos.net.intent.IntentStore;
import
org.onlab.onos.net.intent.IntentStoreDelegate
;
import
org.slf4j.Logger
;
import
com.google.common.collect.ImmutableList
;
import
com.google.common.collect.ImmutableMap
;
import
com.google.common.collect.Lists
;
/**
* An implementation of Intent Manager.
...
...
@@ -67,7 +72,8 @@ public class IntentManager
private
final
AbstractListenerRegistry
<
IntentEvent
,
IntentListener
>
listenerRegistry
=
new
AbstractListenerRegistry
<>();
private
final
ExecutorService
executor
=
newSingleThreadExecutor
(
namedThreads
(
"onos-intents"
));
private
ExecutorService
executor
;
private
ExecutorService
monitorExecutor
;
private
final
IntentStoreDelegate
delegate
=
new
InternalStoreDelegate
();
private
final
TopologyChangeDelegate
topoDelegate
=
new
InternalTopoChangeDelegate
();
...
...
@@ -86,6 +92,8 @@ public class IntentManager
store
.
setDelegate
(
delegate
);
trackerService
.
setDelegate
(
topoDelegate
);
eventDispatcher
.
addSink
(
IntentEvent
.
class
,
listenerRegistry
);
executor
=
newSingleThreadExecutor
(
namedThreads
(
"onos-intents"
));
monitorExecutor
=
newSingleThreadExecutor
(
namedThreads
(
"onos-intent-monitor"
));
log
.
info
(
"Started"
);
}
...
...
@@ -94,6 +102,8 @@ public class IntentManager
store
.
unsetDelegate
(
delegate
);
trackerService
.
unsetDelegate
(
topoDelegate
);
eventDispatcher
.
removeSink
(
IntentEvent
.
class
);
executor
.
shutdown
();
monitorExecutor
.
shutdown
();
log
.
info
(
"Stopped"
);
}
...
...
@@ -240,14 +250,23 @@ public class IntentManager
}
}
// FIXME: To make SDN-IP workable ASAP, only single level compilation is implemented
// TODO: implement compilation traversing tree structure
/**
* Compiles an intent recursively.
*
* @param intent intent
* @return result of compilation
*/
private
List
<
InstallableIntent
>
compileIntent
(
Intent
intent
)
{
if
(
intent
instanceof
InstallableIntent
)
{
return
ImmutableList
.
of
((
InstallableIntent
)
intent
);
}
List
<
InstallableIntent
>
installable
=
new
ArrayList
<>();
// TODO do we need to registerSubclassCompiler?
for
(
Intent
compiled
:
getCompiler
(
intent
).
compile
(
intent
))
{
InstallableIntent
installableIntent
=
(
InstallableIntent
)
compiled
;
installable
.
add
(
installableIntent
);
installable
.
addAll
(
compileIntent
(
compiled
));
}
return
installable
;
}
...
...
@@ -261,6 +280,7 @@ public class IntentManager
// Indicate that the intent is entering the installing phase.
store
.
setState
(
intent
,
INSTALLING
);
List
<
Future
<
CompletedBatchOperation
>>
installFutures
=
Lists
.
newArrayList
();
try
{
List
<
InstallableIntent
>
installables
=
store
.
getInstallableIntents
(
intent
.
id
());
if
(
installables
!=
null
)
{
...
...
@@ -268,17 +288,20 @@ public class IntentManager
registerSubclassInstallerIfNeeded
(
installable
);
trackerService
.
addTrackedResources
(
intent
.
id
(),
installable
.
requiredLinks
());
getInstaller
(
installable
).
install
(
installable
);
Future
<
CompletedBatchOperation
>
future
=
getInstaller
(
installable
).
install
(
installable
);
installFutures
.
add
(
future
);
}
}
eventDispatcher
.
post
(
store
.
setState
(
intent
,
INSTALLED
));
// FIXME we have to wait for the installable intents
//eventDispatcher.post(store.setState(intent, INSTALLED));
monitorExecutor
.
execute
(
new
IntentInstallMonitor
(
intent
,
installFutures
,
INSTALLED
));
}
catch
(
Exception
e
)
{
log
.
warn
(
"Unable to install intent {} due to: {}"
,
intent
.
id
(),
e
);
uninstallIntent
(
intent
);
uninstallIntent
(
intent
,
RECOMPILING
);
// If compilation failed, kick off the recompiling phase.
executeRecompilingPhase
(
intent
);
// FIXME
//executeRecompilingPhase(intent);
}
}
...
...
@@ -327,12 +350,14 @@ public class IntentManager
private
void
executeWithdrawingPhase
(
Intent
intent
)
{
// Indicate that the intent is being withdrawn.
store
.
setState
(
intent
,
WITHDRAWING
);
uninstallIntent
(
intent
);
uninstallIntent
(
intent
,
WITHDRAWN
);
// If all went well, disassociate the top-level intent with its
// installable derivatives and mark it as withdrawn.
store
.
removeInstalledIntents
(
intent
.
id
());
eventDispatcher
.
post
(
store
.
setState
(
intent
,
WITHDRAWN
));
// FIXME need to clean up
//store.removeInstalledIntents(intent.id());
// FIXME
//eventDispatcher.post(store.setState(intent, WITHDRAWN));
}
/**
...
...
@@ -340,14 +365,17 @@ public class IntentManager
*
* @param intent intent to be uninstalled
*/
private
void
uninstallIntent
(
Intent
intent
)
{
private
void
uninstallIntent
(
Intent
intent
,
IntentState
nextState
)
{
List
<
Future
<
CompletedBatchOperation
>>
uninstallFutures
=
Lists
.
newArrayList
();
try
{
List
<
InstallableIntent
>
installables
=
store
.
getInstallableIntents
(
intent
.
id
());
if
(
installables
!=
null
)
{
for
(
InstallableIntent
installable
:
installables
)
{
getInstaller
(
installable
).
uninstall
(
installable
);
Future
<
CompletedBatchOperation
>
future
=
getInstaller
(
installable
).
uninstall
(
installable
);
uninstallFutures
.
add
(
future
);
}
}
monitorExecutor
.
execute
(
new
IntentInstallMonitor
(
intent
,
uninstallFutures
,
nextState
));
}
catch
(
IntentException
e
)
{
log
.
warn
(
"Unable to uninstall intent {} due to: {}"
,
intent
.
id
(),
e
);
}
...
...
@@ -422,9 +450,10 @@ public class IntentManager
// Attempt recompilation of the specified intents first.
for
(
IntentId
intentId
:
intentIds
)
{
Intent
intent
=
getIntent
(
intentId
);
uninstallIntent
(
intent
);
uninstallIntent
(
intent
,
RECOMPILING
);
executeRecompilingPhase
(
intent
);
//FIXME
//executeRecompilingPhase(intent);
}
if
(
compileAllFailed
)
{
...
...
@@ -460,4 +489,44 @@ public class IntentManager
}
}
private
class
IntentInstallMonitor
implements
Runnable
{
private
final
Intent
intent
;
private
final
List
<
Future
<
CompletedBatchOperation
>>
futures
;
private
final
IntentState
nextState
;
public
IntentInstallMonitor
(
Intent
intent
,
List
<
Future
<
CompletedBatchOperation
>>
futures
,
IntentState
nextState
)
{
this
.
intent
=
intent
;
this
.
futures
=
futures
;
this
.
nextState
=
nextState
;
}
private
void
updateIntent
(
Intent
intent
)
{
if
(
nextState
==
RECOMPILING
)
{
executor
.
execute
(
new
IntentTask
(
nextState
,
intent
));
}
else
if
(
nextState
==
INSTALLED
||
nextState
==
WITHDRAWN
)
{
eventDispatcher
.
post
(
store
.
setState
(
intent
,
nextState
));
}
else
{
log
.
warn
(
"Invalid next intent state {} for intent {}"
,
nextState
,
intent
);
}
}
@Override
public
void
run
()
{
for
(
Iterator
<
Future
<
CompletedBatchOperation
>>
i
=
futures
.
iterator
();
i
.
hasNext
();)
{
Future
<
CompletedBatchOperation
>
future
=
i
.
next
();
if
(
future
.
isDone
())
{
// TODO: we may want to get the future here
i
.
remove
();
}
}
if
(
futures
.
isEmpty
())
{
updateIntent
(
intent
);
}
else
{
// resubmit ourselves if we are not done yet
monitorExecutor
.
submit
(
this
);
}
}
}
}
...
...
core/net/src/main/java/org/onlab/onos/net/intent/impl/PathIntentInstaller.java
View file @
cb900f4
...
...
@@ -5,7 +5,7 @@ import static org.slf4j.LoggerFactory.getLogger;
import
java.util.Iterator
;
import
java.util.List
;
import
java.util.concurrent.
ExecutionException
;
import
java.util.concurrent.
Future
;
import
org.apache.felix.scr.annotations.Activate
;
import
org.apache.felix.scr.annotations.Component
;
...
...
@@ -15,6 +15,7 @@ import org.apache.felix.scr.annotations.ReferenceCardinality;
import
org.onlab.onos.ApplicationId
;
import
org.onlab.onos.net.ConnectPoint
;
import
org.onlab.onos.net.Link
;
import
org.onlab.onos.net.flow.CompletedBatchOperation
;
import
org.onlab.onos.net.flow.DefaultFlowRule
;
import
org.onlab.onos.net.flow.DefaultTrafficSelector
;
import
org.onlab.onos.net.flow.FlowRule
;
...
...
@@ -57,8 +58,26 @@ public class PathIntentInstaller implements IntentInstaller<PathIntent> {
intentManager
.
unregisterInstaller
(
PathIntent
.
class
);
}
/**
* Apply a list of FlowRules.
*
* @param rules rules to apply
*/
private
Future
<
CompletedBatchOperation
>
applyBatch
(
List
<
FlowRuleBatchEntry
>
rules
)
{
FlowRuleBatchOperation
batch
=
new
FlowRuleBatchOperation
(
rules
);
Future
<
CompletedBatchOperation
>
future
=
flowRuleService
.
applyBatch
(
batch
);
return
future
;
// try {
// //FIXME don't do this here
// future.get();
// } catch (InterruptedException | ExecutionException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
}
@Override
public
void
install
(
PathIntent
intent
)
{
public
Future
<
CompletedBatchOperation
>
install
(
PathIntent
intent
)
{
TrafficSelector
.
Builder
builder
=
DefaultTrafficSelector
.
builder
(
intent
.
selector
());
Iterator
<
Link
>
links
=
intent
.
path
().
links
().
iterator
();
...
...
@@ -74,20 +93,14 @@ public class PathIntentInstaller implements IntentInstaller<PathIntent> {
builder
.
build
(),
treatment
,
123
,
appId
,
600
);
rules
.
add
(
new
FlowRuleBatchEntry
(
FlowRuleOperation
.
ADD
,
rule
));
//flowRuleService.applyFlowRules(rule);
prev
=
link
.
dst
();
}
FlowRuleBatchOperation
batch
=
new
FlowRuleBatchOperation
(
rules
);
try
{
flowRuleService
.
applyBatch
(
batch
).
get
();
}
catch
(
InterruptedException
|
ExecutionException
e
)
{
// TODO Auto-generated catch block
e
.
printStackTrace
();
}
return
applyBatch
(
rules
);
}
@Override
public
void
uninstall
(
PathIntent
intent
)
{
public
Future
<
CompletedBatchOperation
>
uninstall
(
PathIntent
intent
)
{
TrafficSelector
.
Builder
builder
=
DefaultTrafficSelector
.
builder
(
intent
.
selector
());
Iterator
<
Link
>
links
=
intent
.
path
().
links
().
iterator
();
...
...
@@ -103,15 +116,131 @@ public class PathIntentInstaller implements IntentInstaller<PathIntent> {
builder
.
build
(),
treatment
,
123
,
appId
,
600
);
rules
.
add
(
new
FlowRuleBatchEntry
(
FlowRuleOperation
.
REMOVE
,
rule
));
//flowRuleService.removeFlowRules(rule);
prev
=
link
.
dst
();
}
FlowRuleBatchOperation
batch
=
new
FlowRuleBatchOperation
(
rules
);
try
{
flowRuleService
.
applyBatch
(
batch
).
get
();
}
catch
(
InterruptedException
|
ExecutionException
e
)
{
// TODO Auto-generated catch block
e
.
printStackTrace
();
return
applyBatch
(
rules
);
}
// TODO refactor below this line... ----------------------------
/**
* Generates the series of MatchActionOperations from the
* {@link FlowBatchOperation}.
* <p>
* FIXME: Currently supporting PacketPathFlow and SingleDstTreeFlow only.
* <p>
* FIXME: MatchActionOperations should have dependency field to the other
* match action operations, and this method should use this.
*
* @param op the {@link FlowBatchOperation} object
* @return the list of {@link MatchActionOperations} objects
*/
/*
private List<MatchActionOperations>
generateMatchActionOperationsList(FlowBatchOperation op) {
// MatchAction operations at head (ingress) switches.
MatchActionOperations headOps = matchActionService.createOperationsList();
// MatchAction operations at rest of the switches.
MatchActionOperations tailOps = matchActionService.createOperationsList();
MatchActionOperations removeOps = matchActionService.createOperationsList();
for (BatchOperationEntry<Operator, ?> e : op.getOperations()) {
if (e.getOperator() == FlowBatchOperation.Operator.ADD) {
generateInstallMatchActionOperations(e, tailOps, headOps);
} else if (e.getOperator() == FlowBatchOperation.Operator.REMOVE) {
generateRemoveMatchActionOperations(e, removeOps);
} else {
throw new UnsupportedOperationException(
"FlowManager supports ADD and REMOVE operations only.");
}
}
return Arrays.asList(tailOps, headOps, removeOps);
}
*/
/**
* Generates MatchActionOperations for an INSTALL FlowBatchOperation.
* <p/>
* FIXME: Currently only supports flows that generate exactly two match
* action operation sets.
*
* @param e Flow BatchOperationEntry
* @param tailOps MatchActionOperation set that the tail
* MatchActionOperations will be placed in
* @param headOps MatchActionOperation set that the head
* MatchActionOperations will be placed in
*/
/*
private void generateInstallMatchActionOperations(
BatchOperationEntry<Operator, ?> e,
MatchActionOperations tailOps,
MatchActionOperations headOps) {
if (!(e.getTarget() instanceof Flow)) {
throw new IllegalStateException(
"The target is not Flow object: " + e.getTarget());
}
// Compile flows to match-actions
Flow flow = (Flow) e.getTarget();
List<MatchActionOperations> maOps = flow.compile(
e.getOperator(), matchActionService);
verifyNotNull(maOps, "Could not compile the flow: " + flow);
verify(maOps.size() == 2,
"The flow generates unspported match-action operations.");
// Map FlowId to MatchActionIds
for (MatchActionOperations maOp : maOps) {
for (MatchActionOperationEntry entry : maOp.getOperations()) {
flowMatchActionsMap.put(
KryoFactory.serialize(flow.getId()),
KryoFactory.serialize(entry.getTarget()));
}
}
// Merge match-action operations
for (MatchActionOperationEntry mae : maOps.get(0).getOperations()) {
verify(mae.getOperator() == MatchActionOperations.Operator.INSTALL);
tailOps.addOperation(mae);
}
for (MatchActionOperationEntry mae : maOps.get(1).getOperations()) {
verify(mae.getOperator() == MatchActionOperations.Operator.INSTALL);
headOps.addOperation(mae);
}
}
*/
/**
* Generates MatchActionOperations for a REMOVE FlowBatchOperation.
*
* @param e Flow BatchOperationEntry
* @param removeOps MatchActionOperation set that the remove
* MatchActionOperations will be placed in
*/
/*
private void generateRemoveMatchActionOperations(
BatchOperationEntry<Operator, ?> e,
MatchActionOperations removeOps) {
if (!(e.getTarget() instanceof FlowId)) {
throw new IllegalStateException(
"The target is not a FlowId object: " + e.getTarget());
}
// Compile flows to match-actions
FlowId flowId = (FlowId) e.getTarget();
for (byte[] matchActionIdBytes :
flowMatchActionsMap.remove(KryoFactory.serialize(flowId))) {
MatchActionId matchActionId = KryoFactory.deserialize(matchActionIdBytes);
removeOps.addOperation(new MatchActionOperationEntry(
MatchActionOperations.Operator.REMOVE, matchActionId));
}
}
*/
}
...
...
Please
register
or
login
to post a comment