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
Madan Jampani
2014-10-02 15:17:40 -0700
Browse Files
Options
Browse Files
Download
Plain Diff
Commit
48e54c34d6cf34fa14eff76c4d0cad62de8f0152
48e54c34
2 parents
e4ff21be
55710e70
Merge branch 'master' of
ssh://gerrit.onlab.us:29418/onos-next
Hide whitespace changes
Inline
Side-by-side
Showing
31 changed files
with
1737 additions
and
34 deletions
core/api/src/main/java/org/onlab/onos/net/DefaultAnnotations.java
core/api/src/main/java/org/onlab/onos/net/device/DefaultDeviceDescription.java
core/api/src/main/java/org/onlab/onos/net/device/DefaultPortDescription.java
core/api/src/main/java/org/onlab/onos/net/device/PortDescription.java
core/api/src/main/java/org/onlab/onos/net/intent/AbstractIntent.java
core/api/src/main/java/org/onlab/onos/net/intent/BatchOperation.java
core/api/src/main/java/org/onlab/onos/net/intent/BatchOperationEntry.java
core/api/src/main/java/org/onlab/onos/net/intent/BatchOperationTarget.java
core/api/src/main/java/org/onlab/onos/net/intent/ConnectivityIntent.java
core/api/src/main/java/org/onlab/onos/net/intent/InstallableIntent.java
core/api/src/main/java/org/onlab/onos/net/intent/Intent.java
core/api/src/main/java/org/onlab/onos/net/intent/IntentBatchOperation.java
core/api/src/main/java/org/onlab/onos/net/intent/IntentCompiler.java
core/api/src/main/java/org/onlab/onos/net/intent/IntentEvent.java
core/api/src/main/java/org/onlab/onos/net/intent/IntentEventListener.java
core/api/src/main/java/org/onlab/onos/net/intent/IntentException.java
core/api/src/main/java/org/onlab/onos/net/intent/IntentExtensionService.java
core/api/src/main/java/org/onlab/onos/net/intent/IntentId.java
core/api/src/main/java/org/onlab/onos/net/intent/IntentInstaller.java
core/api/src/main/java/org/onlab/onos/net/intent/IntentOperations.java
core/api/src/main/java/org/onlab/onos/net/intent/IntentService.java
core/api/src/main/java/org/onlab/onos/net/intent/IntentState.java
core/api/src/main/java/org/onlab/onos/net/intent/MultiPointToSinglePointIntent.java
core/api/src/main/java/org/onlab/onos/net/intent/OpticalConnectivityIntent.java
core/api/src/main/java/org/onlab/onos/net/intent/PacketConnectivityIntent.java
core/api/src/main/java/org/onlab/onos/net/intent/PathIntent.java
core/api/src/main/java/org/onlab/onos/net/intent/PointToPointIntent.java
core/api/src/main/java/org/onlab/onos/net/intent/SinglePointToMultiPointIntent.java
core/api/src/main/java/org/onlab/onos/net/intent/package-info.java
core/store/trivial/src/main/java/org/onlab/onos/store/trivial/impl/SimpleDeviceStore.java
core/store/trivial/src/test/java/org/onlab/onos/store/trivial/impl/SimpleDeviceStoreTest.java
core/api/src/main/java/org/onlab/onos/net/DefaultAnnotations.java
View file @
48e54c3
package
org
.
onlab
.
onos
.
net
;
import
java.util.Collections
;
import
java.util.HashMap
;
import
java.util.Map
;
import
java.util.Objects
;
...
...
@@ -71,9 +72,33 @@ public final class DefaultAnnotations implements SparseAnnotations {
return
new
DefaultAnnotations
(
merged
);
}
/**
* Convert Annotations to DefaultAnnotations if needed and merges.
*
* @see #merge(DefaultAnnotations, SparseAnnotations)
*
* @param annotations base annotations
* @param sparseAnnotations additional sparse annotations
* @return combined annotations or the original base annotations if there
* are not additional annotations
*/
public
static
DefaultAnnotations
merge
(
Annotations
annotations
,
SparseAnnotations
sparseAnnotations
)
{
if
(
annotations
instanceof
DefaultAnnotations
)
{
return
merge
((
DefaultAnnotations
)
annotations
,
sparseAnnotations
);
}
DefaultAnnotations
.
Builder
builder
=
DefaultAnnotations
.
builder
();
for
(
String
key
:
annotations
.
keys
())
{
builder
.
set
(
key
,
annotations
.
value
(
key
));
}
return
merge
(
builder
.
build
(),
sparseAnnotations
);
}
@Override
public
Set
<
String
>
keys
()
{
return
map
.
keySet
();
// TODO: unmodifiable to be removed after switching to ImmutableMap;
return
Collections
.
unmodifiableSet
(
map
.
keySet
());
}
@Override
...
...
core/api/src/main/java/org/onlab/onos/net/device/DefaultDeviceDescription.java
View file @
48e54c3
...
...
@@ -45,6 +45,18 @@ public class DefaultDeviceDescription extends AbstractDescription
this
.
serialNumber
=
serialNumber
;
}
/**
* Creates a device description using the supplied information.
* @param base DeviceDescription to basic information
* @param annotations Annotations to use.
*/
public
DefaultDeviceDescription
(
DeviceDescription
base
,
SparseAnnotations
...
annotations
)
{
this
(
base
.
deviceURI
(),
base
.
type
(),
base
.
manufacturer
(),
base
.
hwVersion
(),
base
.
swVersion
(),
base
.
serialNumber
(),
annotations
);
}
@Override
public
URI
deviceURI
()
{
return
uri
;
...
...
core/api/src/main/java/org/onlab/onos/net/device/DefaultPortDescription.java
View file @
48e54c3
package
org
.
onlab
.
onos
.
net
.
device
;
import
org.onlab.onos.net.AbstractDescription
;
import
org.onlab.onos.net.PortNumber
;
import
org.onlab.onos.net.SparseAnnotations
;
/**
* Default implementation of immutable port description.
*/
public
class
DefaultPortDescription
implements
PortDescription
{
public
class
DefaultPortDescription
extends
AbstractDescription
implements
PortDescription
{
private
final
PortNumber
number
;
private
final
boolean
isEnabled
;
public
DefaultPortDescription
(
PortNumber
number
,
boolean
isEnabled
)
{
/**
* Creates a port description using the supplied information.
*
* @param number port number
* @param isEnabled port enabled state
* @param annotations optional key/value annotations map
*/
public
DefaultPortDescription
(
PortNumber
number
,
boolean
isEnabled
,
SparseAnnotations
...
annotations
)
{
super
(
annotations
);
this
.
number
=
number
;
this
.
isEnabled
=
isEnabled
;
}
/**
* Creates a port description using the supplied information.
*
* @param base PortDescription to get basic information from
* @param annotations optional key/value annotations map
*/
public
DefaultPortDescription
(
PortDescription
base
,
SparseAnnotations
annotations
)
{
this
(
base
.
portNumber
(),
base
.
isEnabled
(),
annotations
);
}
@Override
public
PortNumber
portNumber
()
{
return
number
;
...
...
core/api/src/main/java/org/onlab/onos/net/device/PortDescription.java
View file @
48e54c3
package
org
.
onlab
.
onos
.
net
.
device
;
import
org.onlab.onos.net.Description
;
import
org.onlab.onos.net.PortNumber
;
/**
* Information about a port.
*/
public
interface
PortDescription
{
public
interface
PortDescription
extends
Description
{
// TODO: possibly relocate this to a common ground so that this can also used by host tracking if required
...
...
core/api/src/main/java/org/onlab/onos/net/intent/AbstractIntent.java
0 → 100644
View file @
48e54c3
package
org
.
onlab
.
onos
.
net
.
intent
;
/**
* Base intent implementation.
*/
public
abstract
class
AbstractIntent
implements
Intent
{
private
final
IntentId
id
;
/**
* Creates a base intent with the specified identifier.
*
* @param id intent identifier
*/
protected
AbstractIntent
(
IntentId
id
)
{
this
.
id
=
id
;
}
/**
* Constructor for serializer.
*/
protected
AbstractIntent
()
{
this
.
id
=
null
;
}
@Override
public
IntentId
getId
()
{
return
id
;
}
@Override
public
boolean
equals
(
Object
o
)
{
if
(
this
==
o
)
{
return
true
;
}
if
(
o
==
null
||
getClass
()
!=
o
.
getClass
())
{
return
false
;
}
AbstractIntent
that
=
(
AbstractIntent
)
o
;
return
id
.
equals
(
that
.
id
);
}
@Override
public
int
hashCode
()
{
return
id
.
hashCode
();
}
}
core/api/src/main/java/org/onlab/onos/net/intent/BatchOperation.java
0 → 100644
View file @
48e54c3
package
org
.
onlab
.
onos
.
net
.
intent
;
import
static
com
.
google
.
common
.
base
.
Preconditions
.
checkNotNull
;
import
java.util.Collections
;
import
java.util.LinkedList
;
import
java.util.List
;
/**
* A list of BatchOperationEntry.
*
* @param <T> the enum of operators <br>
* This enum must be defined in each sub-classes.
*
*/
public
abstract
class
BatchOperation
<
T
extends
BatchOperationEntry
<?,
?>>
{
private
List
<
T
>
ops
;
/**
* Creates new {@link BatchOperation} object.
*/
public
BatchOperation
()
{
ops
=
new
LinkedList
<>();
}
/**
* Creates {@link BatchOperation} object from a list of batch operation
* entries.
*
* @param batchOperations the list of batch operation entries.
*/
public
BatchOperation
(
List
<
T
>
batchOperations
)
{
ops
=
new
LinkedList
<>(
checkNotNull
(
batchOperations
));
}
/**
* Removes all operations maintained in this object.
*/
public
void
clear
()
{
ops
.
clear
();
}
/**
* Returns the number of operations in this object.
*
* @return the number of operations in this object
*/
public
int
size
()
{
return
ops
.
size
();
}
/**
* Returns the operations in this object.
*
* @return the operations in this object
*/
public
List
<
T
>
getOperations
()
{
return
Collections
.
unmodifiableList
(
ops
);
}
/**
* Adds an operation.
*
* @param entry the operation to be added
* @return this object if succeeded, null otherwise
*/
public
BatchOperation
<
T
>
addOperation
(
T
entry
)
{
return
ops
.
add
(
entry
)
?
this
:
null
;
}
@Override
public
boolean
equals
(
Object
o
)
{
if
(
this
==
o
)
{
return
true
;
}
if
(
o
==
null
)
{
return
false
;
}
if
(
getClass
()
!=
o
.
getClass
())
{
return
false
;
}
BatchOperation
<?>
other
=
(
BatchOperation
<?>)
o
;
return
this
.
ops
.
equals
(
other
.
ops
);
}
@Override
public
int
hashCode
()
{
return
ops
.
hashCode
();
}
@Override
public
String
toString
()
{
return
ops
.
toString
();
}
}
core/api/src/main/java/org/onlab/onos/net/intent/BatchOperationEntry.java
0 → 100644
View file @
48e54c3
package
org
.
onlab
.
onos
.
net
.
intent
;
import
java.util.Objects
;
import
com.google.common.base.MoreObjects
;
/**
* A super class for batch operation entry classes.
* <p>
* This is the interface to classes which are maintained by BatchOperation as
* its entries.
*/
public
class
BatchOperationEntry
<
T
extends
Enum
<?>,
U
extends
BatchOperationTarget
>
{
private
final
T
operator
;
private
final
U
target
;
/**
* Default constructor for serializer.
*/
@Deprecated
protected
BatchOperationEntry
()
{
this
.
operator
=
null
;
this
.
target
=
null
;
}
/**
* Constructs new instance for the entry of the BatchOperation.
*
* @param operator the operator of this operation
* @param target the target object of this operation
*/
public
BatchOperationEntry
(
T
operator
,
U
target
)
{
this
.
operator
=
operator
;
this
.
target
=
target
;
}
/**
* Gets the target object of this operation.
*
* @return the target object of this operation
*/
public
U
getTarget
()
{
return
target
;
}
/**
* Gets the operator of this operation.
*
* @return the operator of this operation
*/
public
T
getOperator
()
{
return
operator
;
}
@Override
public
boolean
equals
(
Object
o
)
{
if
(
this
==
o
)
{
return
true
;
}
if
(
o
==
null
||
getClass
()
!=
o
.
getClass
())
{
return
false
;
}
BatchOperationEntry
<?,
?>
other
=
(
BatchOperationEntry
<?,
?>)
o
;
return
(
this
.
operator
==
other
.
operator
)
&&
Objects
.
equals
(
this
.
target
,
other
.
target
);
}
@Override
public
int
hashCode
()
{
return
Objects
.
hash
(
operator
,
target
);
}
@Override
public
String
toString
()
{
return
MoreObjects
.
toStringHelper
(
this
)
.
add
(
"operator"
,
operator
)
.
add
(
"target"
,
target
)
.
toString
();
}
}
core/api/src/main/java/org/onlab/onos/net/intent/BatchOperationTarget.java
0 → 100644
View file @
48e54c3
package
org
.
onlab
.
onos
.
net
.
intent
;
/**
* An interface of the class which is assigned to BatchOperation.
*/
public
interface
BatchOperationTarget
{
}
core/api/src/main/java/org/onlab/onos/net/intent/ConnectivityIntent.java
0 → 100644
View file @
48e54c3
package
org
.
onlab
.
onos
.
net
.
intent
;
import
static
com
.
google
.
common
.
base
.
Preconditions
.
checkNotNull
;
import
org.onlab.onos.net.flow.TrafficSelector
;
import
org.onlab.onos.net.flow.TrafficTreatment
;
import
com.google.common.base.Objects
;
/**
* Abstraction of connectivity intent for traffic matching some criteria.
*/
public
abstract
class
ConnectivityIntent
extends
AbstractIntent
{
// TODO: other forms of intents should be considered for this family:
// point-to-point with constraints (waypoints/obstacles)
// multi-to-single point with constraints (waypoints/obstacles)
// single-to-multi point with constraints (waypoints/obstacles)
// concrete path (with alternate)
// ...
private
final
TrafficSelector
selector
;
// TODO: should consider which is better for multiple actions,
// defining compound action class or using list of actions.
private
final
TrafficTreatment
treatment
;
/**
* Creates a connectivity intent that matches on the specified intent
* and applies the specified action.
*
* @param id intent identifier
* @param match traffic match
* @param action action
* @throws NullPointerException if the match or action is null
*/
protected
ConnectivityIntent
(
IntentId
id
,
TrafficSelector
match
,
TrafficTreatment
action
)
{
super
(
id
);
this
.
selector
=
checkNotNull
(
match
);
this
.
treatment
=
checkNotNull
(
action
);
}
/**
* Constructor for serializer.
*/
protected
ConnectivityIntent
()
{
super
();
this
.
selector
=
null
;
this
.
treatment
=
null
;
}
/**
* Returns the match specifying the type of traffic.
*
* @return traffic match
*/
public
TrafficSelector
getTrafficSelector
()
{
return
selector
;
}
/**
* Returns the action applied to the traffic.
*
* @return applied action
*/
public
TrafficTreatment
getTrafficTreatment
()
{
return
treatment
;
}
@Override
public
boolean
equals
(
Object
o
)
{
if
(!
super
.
equals
(
o
))
{
return
false
;
}
ConnectivityIntent
that
=
(
ConnectivityIntent
)
o
;
return
Objects
.
equal
(
this
.
selector
,
that
.
selector
)
&&
Objects
.
equal
(
this
.
treatment
,
that
.
treatment
);
}
@Override
public
int
hashCode
()
{
return
Objects
.
hashCode
(
super
.
hashCode
(),
selector
,
treatment
);
}
}
core/api/src/main/java/org/onlab/onos/net/intent/InstallableIntent.java
0 → 100644
View file @
48e54c3
package
org
.
onlab
.
onos
.
net
.
intent
;
/**
* Abstraction of an intent that can be installed into
* the underlying system without additional compilation.
*/
public
interface
InstallableIntent
extends
Intent
{
}
core/api/src/main/java/org/onlab/onos/net/intent/Intent.java
0 → 100644
View file @
48e54c3
package
org
.
onlab
.
onos
.
net
.
intent
;
/**
* Abstraction of an application level intent.
*
* Make sure that an Intent should be immutable when a new type is defined.
*/
public
interface
Intent
extends
BatchOperationTarget
{
/**
* Returns the intent identifier.
*
* @return intent identifier
*/
IntentId
getId
();
}
core/api/src/main/java/org/onlab/onos/net/intent/IntentBatchOperation.java
0 → 100644
View file @
48e54c3
package
org
.
onlab
.
onos
.
net
.
intent
;
/**
* A list of intent operations.
*/
public
class
IntentBatchOperation
extends
BatchOperation
<
BatchOperationEntry
<
IntentBatchOperation
.
Operator
,
?>>
{
/**
* The intent operators.
*/
public
enum
Operator
{
ADD
,
REMOVE
,
}
/**
* Adds an add-intent operation.
*
* @param intent the intent to be added
* @return the IntentBatchOperation object if succeeded, null otherwise
*/
public
IntentBatchOperation
addAddIntentOperation
(
Intent
intent
)
{
return
(
null
==
super
.
addOperation
(
new
BatchOperationEntry
<
Operator
,
Intent
>(
Operator
.
ADD
,
intent
)))
?
null
:
this
;
}
/**
* Adds a remove-intent operation.
*
* @param id the ID of intent to be removed
* @return the IntentBatchOperation object if succeeded, null otherwise
*/
public
IntentBatchOperation
addRemoveIntentOperation
(
IntentId
id
)
{
return
(
null
==
super
.
addOperation
(
new
BatchOperationEntry
<
Operator
,
IntentId
>(
Operator
.
REMOVE
,
id
)))
?
null
:
this
;
}
}
core/api/src/main/java/org/onlab/onos/net/intent/IntentCompiler.java
0 → 100644
View file @
48e54c3
package
org
.
onlab
.
onos
.
net
.
intent
;
import
java.util.List
;
/**
* Abstraction of a compiler which is capable of taking an intent
* and translating it to other, potentially installable, intents.
*
* @param <T> the type of intent
*/
public
interface
IntentCompiler
<
T
extends
Intent
>
{
/**
* Compiles the specified intent into other intents.
*
* @param intent intent to be compiled
* @return list of resulting intents
* @throws IntentException if issues are encountered while compiling the intent
*/
List
<
Intent
>
compile
(
T
intent
);
}
core/api/src/main/java/org/onlab/onos/net/intent/IntentEvent.java
0 → 100644
View file @
48e54c3
package
org
.
onlab
.
onos
.
net
.
intent
;
import
static
com
.
google
.
common
.
base
.
Preconditions
.
checkNotNull
;
import
java.util.Objects
;
import
com.google.common.base.MoreObjects
;
/**
* A class to represent an intent related event.
*/
public
class
IntentEvent
{
// TODO: determine a suitable parent class; if one does not exist, consider introducing one
private
final
long
time
;
private
final
Intent
intent
;
private
final
IntentState
state
;
private
final
IntentState
previous
;
/**
* Creates an event describing a state change of an intent.
*
* @param intent subject intent
* @param state new intent state
* @param previous previous intent state
* @param time time the event created in milliseconds since start of epoch
* @throws NullPointerException if the intent or state is null
*/
public
IntentEvent
(
Intent
intent
,
IntentState
state
,
IntentState
previous
,
long
time
)
{
this
.
intent
=
checkNotNull
(
intent
);
this
.
state
=
checkNotNull
(
state
);
this
.
previous
=
previous
;
this
.
time
=
time
;
}
/**
* Constructor for serializer.
*/
protected
IntentEvent
()
{
this
.
intent
=
null
;
this
.
state
=
null
;
this
.
previous
=
null
;
this
.
time
=
0
;
}
/**
* Returns the state of the intent which caused the event.
*
* @return the state of the intent
*/
public
IntentState
getState
()
{
return
state
;
}
/**
* Returns the previous state of the intent which caused the event.
*
* @return the previous state of the intent
*/
public
IntentState
getPreviousState
()
{
return
previous
;
}
/**
* Returns the intent associated with the event.
*
* @return the intent
*/
public
Intent
getIntent
()
{
return
intent
;
}
/**
* Returns the time at which the event was created.
*
* @return the time in milliseconds since start of epoch
*/
public
long
getTime
()
{
return
time
;
}
@Override
public
boolean
equals
(
Object
o
)
{
if
(
this
==
o
)
{
return
true
;
}
if
(
o
==
null
||
getClass
()
!=
o
.
getClass
())
{
return
false
;
}
IntentEvent
that
=
(
IntentEvent
)
o
;
return
Objects
.
equals
(
this
.
intent
,
that
.
intent
)
&&
Objects
.
equals
(
this
.
state
,
that
.
state
)
&&
Objects
.
equals
(
this
.
previous
,
that
.
previous
)
&&
Objects
.
equals
(
this
.
time
,
that
.
time
);
}
@Override
public
int
hashCode
()
{
return
Objects
.
hash
(
intent
,
state
,
previous
,
time
);
}
@Override
public
String
toString
()
{
return
MoreObjects
.
toStringHelper
(
getClass
())
.
add
(
"intent"
,
intent
)
.
add
(
"state"
,
state
)
.
add
(
"previous"
,
previous
)
.
add
(
"time"
,
time
)
.
toString
();
}
}
core/api/src/main/java/org/onlab/onos/net/intent/IntentEventListener.java
0 → 100644
View file @
48e54c3
package
org
.
onlab
.
onos
.
net
.
intent
;
/**
* Listener for {@link IntentEvent intent events}.
*/
public
interface
IntentEventListener
{
/**
* Processes the specified intent event.
*
* @param event the event to process
*/
void
event
(
IntentEvent
event
);
}
core/api/src/main/java/org/onlab/onos/net/intent/IntentException.java
0 → 100644
View file @
48e54c3
package
org
.
onlab
.
onos
.
net
.
intent
;
/**
* Represents an intent related error.
*/
public
class
IntentException
extends
RuntimeException
{
private
static
final
long
serialVersionUID
=
1907263634145241319L
;
/**
* Constructs an exception with no message and no underlying cause.
*/
public
IntentException
()
{
}
/**
* Constructs an exception with the specified message.
*
* @param message the message describing the specific nature of the error
*/
public
IntentException
(
String
message
)
{
super
(
message
);
}
/**
* Constructs an exception with the specified message and the underlying cause.
*
* @param message the message describing the specific nature of the error
* @param cause the underlying cause of this error
*/
public
IntentException
(
String
message
,
Throwable
cause
)
{
super
(
message
,
cause
);
}
}
core/api/src/main/java/org/onlab/onos/net/intent/IntentExtensionService.java
0 → 100644
View file @
48e54c3
package
org
.
onlab
.
onos
.
net
.
intent
;
import
java.util.Map
;
/**
* Service for extending the capability of intent framework by
* adding additional compilers or/and installers.
*/
public
interface
IntentExtensionService
{
/**
* Registers the specified compiler for the given intent class.
*
* @param cls intent class
* @param compiler intent compiler
* @param <T> the type of intent
*/
<
T
extends
Intent
>
void
registerCompiler
(
Class
<
T
>
cls
,
IntentCompiler
<
T
>
compiler
);
/**
* Unregisters the compiler for the specified intent class.
*
* @param cls intent class
* @param <T> the type of intent
*/
<
T
extends
Intent
>
void
unregisterCompiler
(
Class
<
T
>
cls
);
/**
* Returns immutable set of bindings of currently registered intent compilers.
*
* @return the set of compiler bindings
*/
Map
<
Class
<?
extends
Intent
>,
IntentCompiler
<?
extends
Intent
>>
getCompilers
();
/**
* Registers the specified installer for the given installable intent class.
*
* @param cls installable intent class
* @param installer intent installer
* @param <T> the type of installable intent
*/
<
T
extends
InstallableIntent
>
void
registerInstaller
(
Class
<
T
>
cls
,
IntentInstaller
<
T
>
installer
);
/**
* Unregisters the installer for the given installable intent class.
*
* @param cls installable intent class
* @param <T> the type of installable intent
*/
<
T
extends
InstallableIntent
>
void
unregisterInstaller
(
Class
<
T
>
cls
);
/**
* Returns immutable set of bindings of currently registered intent installers.
*
* @return the set of installer bindings
*/
Map
<
Class
<?
extends
InstallableIntent
>,
IntentInstaller
<?
extends
InstallableIntent
>>
getInstallers
();
}
core/api/src/main/java/org/onlab/onos/net/intent/IntentId.java
0 → 100644
View file @
48e54c3
package
org
.
onlab
.
onos
.
net
.
intent
;
/**
* Intent identifier suitable as an external key.
*
* This class is immutable.
*/
public
final
class
IntentId
implements
BatchOperationTarget
{
private
static
final
int
DEC
=
10
;
private
static
final
int
HEX
=
16
;
private
final
long
id
;
/**
* Creates an intent identifier from the specified string representation.
*
* @param value long value
* @return intent identifier
*/
public
static
IntentId
valueOf
(
String
value
)
{
long
id
=
value
.
toLowerCase
().
startsWith
(
"0x"
)
?
Long
.
parseLong
(
value
.
substring
(
2
),
HEX
)
:
Long
.
parseLong
(
value
,
DEC
);
return
new
IntentId
(
id
);
}
/**
* Constructor for serializer.
*/
protected
IntentId
()
{
this
.
id
=
0
;
}
/**
* Constructs the ID corresponding to a given long value.
*
* @param id the underlying value of this ID
*/
public
IntentId
(
long
id
)
{
this
.
id
=
id
;
}
@Override
public
int
hashCode
()
{
return
(
int
)
(
id
^
(
id
>>>
32
));
}
@Override
public
boolean
equals
(
Object
obj
)
{
if
(
obj
==
this
)
{
return
true
;
}
if
(!(
obj
instanceof
IntentId
))
{
return
false
;
}
IntentId
that
=
(
IntentId
)
obj
;
return
this
.
id
==
that
.
id
;
}
@Override
public
String
toString
()
{
return
"0x"
+
Long
.
toHexString
(
id
);
}
}
core/api/src/main/java/org/onlab/onos/net/intent/IntentInstaller.java
0 → 100644
View file @
48e54c3
package
org
.
onlab
.
onos
.
net
.
intent
;
/**
* Abstraction of entity capable of installing intents to the environment.
*/
public
interface
IntentInstaller
<
T
extends
InstallableIntent
>
{
/**
* Installs the specified intent to the environment.
*
* @param intent intent to be installed
* @throws IntentException if issues are encountered while installing the intent
*/
void
install
(
T
intent
);
/**
* Uninstalls the specified intent from the environment.
*
* @param intent intent to be uninstalled
* @throws IntentException if issues are encountered while uninstalling the intent
*/
void
uninstall
(
T
intent
);
}
core/api/src/main/java/org/onlab/onos/net/intent/IntentOperations.java
0 → 100644
View file @
48e54c3
package
org
.
onlab
.
onos
.
net
.
intent
;
/**
* Abstraction of a batch of intent submit/withdraw operations.
*/
public
interface
IntentOperations
{
// TODO: elaborate once the revised BatchOperation scheme is in place
}
core/api/src/main/java/org/onlab/onos/net/intent/IntentService.java
0 → 100644
View file @
48e54c3
package
org
.
onlab
.
onos
.
net
.
intent
;
import
java.util.Set
;
/**
* Service for application submitting or withdrawing their intents.
*/
public
interface
IntentService
{
/**
* Submits an intent into the system.
*
* This is an asynchronous request meaning that any compiling
* or installation activities may be done at later time.
*
* @param intent intent to be submitted
*/
void
submit
(
Intent
intent
);
/**
* Withdraws an intent from the system.
*
* This is an asynchronous request meaning that the environment
* may be affected at later time.
*
* @param intent intent to be withdrawn
*/
void
withdraw
(
Intent
intent
);
/**
* Submits a batch of submit & withdraw operations. Such a batch is
* assumed to be processed together.
*
* This is an asynchronous request meaning that the environment
* may be affected at later time.
*
* @param operations batch of intent operations
*/
void
execute
(
IntentOperations
operations
);
/**
* Returns immutable set of intents currently in the system.
*
* @return set of intents
*/
Set
<
Intent
>
getIntents
();
/**
* Retrieves the intent specified by its identifier.
*
* @param id intent identifier
* @return the intent or null if one with the given identifier is not found
*/
Intent
getIntent
(
IntentId
id
);
/**
* Retrieves the state of an intent by its identifier.
*
* @param id intent identifier
* @return the intent state or null if one with the given identifier is not found
*/
IntentState
getIntentState
(
IntentId
id
);
/**
* Adds the specified listener for intent events.
*
* @param listener listener to be added
*/
void
addListener
(
IntentEventListener
listener
);
/**
* Removes the specified listener for intent events.
*
* @param listener listener to be removed
*/
void
removeListener
(
IntentEventListener
listener
);
}
core/api/src/main/java/org/onlab/onos/net/intent/IntentState.java
0 → 100644
View file @
48e54c3
package
org
.
onlab
.
onos
.
net
.
intent
;
/**
* This class represents the states of an intent.
*
* <p>
* Note: The state is expressed as enum, but there is possibility
* in the future that we define specific class instead of enum to improve
* the extensibility of state definition.
* </p>
*/
public
enum
IntentState
{
// FIXME: requires discussion on State vs. EventType and a solid state-transition diagram
// TODO: consider the impact of conflict detection
// TODO: consider the impact that external events affect an installed intent
/**
* The beginning state.
*
* All intent in the runtime take this state first.
*/
SUBMITTED
,
/**
* The intent compilation has been completed.
*
* An intent translation graph (tree) is completely created.
* Leaves of the graph are installable intent type.
*/
COMPILED
,
/**
* The intent has been successfully installed.
*/
INSTALLED
,
/**
* The intent is being withdrawn.
*
* When {@link IntentService#withdraw(Intent)} is called,
* the intent takes this state first.
*/
WITHDRAWING
,
/**
* The intent has been successfully withdrawn.
*/
WITHDRAWN
,
/**
* The intent has failed to be compiled, installed, or withdrawn.
*
* When the intent failed to be withdrawn, it is still, at least partially installed.
*/
FAILED
,
}
core/api/src/main/java/org/onlab/onos/net/intent/MultiPointToSinglePointIntent.java
0 → 100644
View file @
48e54c3
package
org
.
onlab
.
onos
.
net
.
intent
;
import
static
com
.
google
.
common
.
base
.
Preconditions
.
checkArgument
;
import
static
com
.
google
.
common
.
base
.
Preconditions
.
checkNotNull
;
import
java.util.Objects
;
import
java.util.Set
;
import
org.onlab.onos.net.ConnectPoint
;
import
org.onlab.onos.net.flow.TrafficSelector
;
import
org.onlab.onos.net.flow.TrafficTreatment
;
import
com.google.common.base.MoreObjects
;
import
com.google.common.collect.Sets
;
/**
* Abstraction of multiple source to single destination connectivity intent.
*/
public
class
MultiPointToSinglePointIntent
extends
ConnectivityIntent
{
private
final
Set
<
ConnectPoint
>
ingressPorts
;
private
final
ConnectPoint
egressPort
;
/**
* Creates a new multi-to-single point connectivity intent for the specified
* traffic match and action.
*
* @param id intent identifier
* @param match traffic match
* @param action action
* @param ingressPorts set of ports from which ingress traffic originates
* @param egressPort port to which traffic will egress
* @throws NullPointerException if {@code ingressPorts} or
* {@code egressPort} is null.
* @throws IllegalArgumentException if the size of {@code ingressPorts} is
* not more than 1
*/
public
MultiPointToSinglePointIntent
(
IntentId
id
,
TrafficSelector
match
,
TrafficTreatment
action
,
Set
<
ConnectPoint
>
ingressPorts
,
ConnectPoint
egressPort
)
{
super
(
id
,
match
,
action
);
checkNotNull
(
ingressPorts
);
checkArgument
(!
ingressPorts
.
isEmpty
(),
"there should be at least one ingress port"
);
this
.
ingressPorts
=
Sets
.
newHashSet
(
ingressPorts
);
this
.
egressPort
=
checkNotNull
(
egressPort
);
}
/**
* Constructor for serializer.
*/
protected
MultiPointToSinglePointIntent
()
{
super
();
this
.
ingressPorts
=
null
;
this
.
egressPort
=
null
;
}
/**
* Returns the set of ports on which ingress traffic should be connected to
* the egress port.
*
* @return set of ingress ports
*/
public
Set
<
ConnectPoint
>
getIngressPorts
()
{
return
ingressPorts
;
}
/**
* Returns the port on which the traffic should egress.
*
* @return egress port
*/
public
ConnectPoint
getEgressPort
()
{
return
egressPort
;
}
@Override
public
boolean
equals
(
Object
o
)
{
if
(
this
==
o
)
{
return
true
;
}
if
(
o
==
null
||
getClass
()
!=
o
.
getClass
())
{
return
false
;
}
if
(!
super
.
equals
(
o
))
{
return
false
;
}
MultiPointToSinglePointIntent
that
=
(
MultiPointToSinglePointIntent
)
o
;
return
Objects
.
equals
(
this
.
ingressPorts
,
that
.
ingressPorts
)
&&
Objects
.
equals
(
this
.
egressPort
,
that
.
egressPort
);
}
@Override
public
int
hashCode
()
{
return
Objects
.
hash
(
super
.
hashCode
(),
ingressPorts
,
egressPort
);
}
@Override
public
String
toString
()
{
return
MoreObjects
.
toStringHelper
(
getClass
())
.
add
(
"id"
,
getId
())
.
add
(
"match"
,
getTrafficSelector
())
.
add
(
"action"
,
getTrafficTreatment
())
.
add
(
"ingressPorts"
,
getIngressPorts
())
.
add
(
"egressPort"
,
getEgressPort
())
.
toString
();
}
}
core/api/src/main/java/org/onlab/onos/net/intent/OpticalConnectivityIntent.java
0 → 100644
View file @
48e54c3
package
org
.
onlab
.
onos
.
net
.
intent
;
import
org.onlab.onos.net.ConnectPoint
;
// TODO: consider if this intent should be sub-class of ConnectivityIntent
/**
* An optical layer Intent for a connectivity from a transponder port to another
* transponder port.
* <p>
* This class doesn't accepts lambda specifier. This class computes path between
* ports and assign lambda automatically. The lambda can be specified using
* OpticalPathFlow class.
*/
public
class
OpticalConnectivityIntent
extends
AbstractIntent
{
protected
ConnectPoint
srcConnectPoint
;
protected
ConnectPoint
dstConnectPoint
;
/**
* Constructor.
*
* @param id ID for this new Intent object.
* @param srcConnectPoint The source transponder port.
* @param dstConnectPoint The destination transponder port.
*/
public
OpticalConnectivityIntent
(
IntentId
id
,
ConnectPoint
srcConnectPoint
,
ConnectPoint
dstConnectPoint
)
{
super
(
id
);
this
.
srcConnectPoint
=
srcConnectPoint
;
this
.
dstConnectPoint
=
dstConnectPoint
;
}
/**
* Constructor for serializer.
*/
protected
OpticalConnectivityIntent
()
{
super
();
this
.
srcConnectPoint
=
null
;
this
.
dstConnectPoint
=
null
;
}
/**
* Gets source transponder port.
*
* @return The source transponder port.
*/
public
ConnectPoint
getSrcConnectPoint
()
{
return
srcConnectPoint
;
}
/**
* Gets destination transponder port.
*
* @return The source transponder port.
*/
public
ConnectPoint
getDstConnectPoint
()
{
return
dstConnectPoint
;
}
}
core/api/src/main/java/org/onlab/onos/net/intent/PacketConnectivityIntent.java
0 → 100644
View file @
48e54c3
package
org
.
onlab
.
onos
.
net
.
intent
;
import
java.util.Collection
;
import
java.util.Collections
;
import
java.util.HashSet
;
import
java.util.Set
;
import
org.onlab.onos.net.ConnectPoint
;
import
org.onlab.onos.net.flow.TrafficSelector
;
// TODO: consider if this intent should be sub-class of Connectivity intent
/**
* A packet layer Intent for a connectivity from a set of ports to a set of
* ports.
* <p>
* TODO: Design methods to support the ReactiveForwarding and the SDN-IP. <br>
* NOTE: Should this class support modifier methods? Should this object a
* read-only object?
*/
public
class
PacketConnectivityIntent
extends
AbstractIntent
{
protected
Set
<
ConnectPoint
>
srcConnectPoints
;
protected
TrafficSelector
selector
;
protected
Set
<
ConnectPoint
>
dstConnectPoints
;
protected
boolean
canSetupOpticalFlow
;
protected
int
idleTimeoutValue
;
protected
int
hardTimeoutValue
;
/**
* Creates a connectivity intent for the packet layer.
* <p>
* When the "canSetupOpticalFlow" option is true, this intent will compute
* the packet/optical converged path, decompose it to the OpticalPathFlow
* and the PacketPathFlow objects, and execute the operations to add them
* considering the dependency between the packet and optical layers.
*
* @param id ID for this new Intent object.
* @param srcConnectPoints The set of source switch ports.
* @param match Traffic specifier for this object.
* @param dstConnectPoints The set of destination switch ports.
* @param canSetupOpticalFlow The flag whether this intent can create
* optical flows if needed.
*/
public
PacketConnectivityIntent
(
IntentId
id
,
Collection
<
ConnectPoint
>
srcConnectPoints
,
TrafficSelector
match
,
Collection
<
ConnectPoint
>
dstConnectPoints
,
boolean
canSetupOpticalFlow
)
{
super
(
id
);
this
.
srcConnectPoints
=
new
HashSet
<
ConnectPoint
>(
srcConnectPoints
);
this
.
selector
=
match
;
this
.
dstConnectPoints
=
new
HashSet
<
ConnectPoint
>(
dstConnectPoints
);
this
.
canSetupOpticalFlow
=
canSetupOpticalFlow
;
this
.
idleTimeoutValue
=
0
;
this
.
hardTimeoutValue
=
0
;
// TODO: check consistency between these parameters.
}
/**
* Constructor for serializer.
*/
protected
PacketConnectivityIntent
()
{
super
();
this
.
srcConnectPoints
=
null
;
this
.
selector
=
null
;
this
.
dstConnectPoints
=
null
;
this
.
canSetupOpticalFlow
=
false
;
this
.
idleTimeoutValue
=
0
;
this
.
hardTimeoutValue
=
0
;
}
/**
* Gets the set of source switch ports.
*
* @return the set of source switch ports.
*/
public
Collection
<
ConnectPoint
>
getSrcConnectPoints
()
{
return
Collections
.
unmodifiableCollection
(
srcConnectPoints
);
}
/**
* Gets the traffic specifier.
*
* @return The traffic specifier.
*/
public
TrafficSelector
getMatch
()
{
return
selector
;
}
/**
* Gets the set of destination switch ports.
*
* @return the set of destination switch ports.
*/
public
Collection
<
ConnectPoint
>
getDstConnectPoints
()
{
return
Collections
.
unmodifiableCollection
(
dstConnectPoints
);
}
/**
* Adds the specified port to the set of source ports.
*
* @param port ConnectPoint object to be added
*/
public
void
addSrcConnectPoint
(
ConnectPoint
port
)
{
// TODO implement it.
}
/**
* Adds the specified port to the set of destination ports.
*
* @param port ConnectPoint object to be added
*/
public
void
addDstConnectPoint
(
ConnectPoint
port
)
{
// TODO implement it.
}
/**
* Removes the specified port from the set of source ports.
*
* @param port ConnectPoint object to be removed
*/
public
void
removeSrcConnectPoint
(
ConnectPoint
port
)
{
// TODO implement it.
}
/**
* Removes the specified port from the set of destination ports.
*
* @param port ConnectPoint object to be removed
*/
public
void
removeDstConnectPoint
(
ConnectPoint
port
)
{
// TODO implement it.
}
/**
* Sets idle-timeout value.
*
* @param timeout Idle-timeout value (seconds)
*/
public
void
setIdleTimeout
(
int
timeout
)
{
idleTimeoutValue
=
timeout
;
}
/**
* Sets hard-timeout value.
*
* @param timeout Hard-timeout value (seconds)
*/
public
void
setHardTimeout
(
int
timeout
)
{
hardTimeoutValue
=
timeout
;
}
/**
* Gets idle-timeout value.
*
* @return Idle-timeout value (seconds)
*/
public
int
getIdleTimeout
()
{
return
idleTimeoutValue
;
}
/**
* Gets hard-timeout value.
*
* @return Hard-timeout value (seconds)
*/
public
int
getHardTimeout
()
{
return
hardTimeoutValue
;
}
/**
* Returns whether this intent can create optical flows if needed.
*
* @return whether this intent can create optical flows.
*/
public
boolean
canSetupOpticalFlow
()
{
return
canSetupOpticalFlow
;
}
}
core/api/src/main/java/org/onlab/onos/net/intent/PathIntent.java
0 → 100644
View file @
48e54c3
package
org
.
onlab
.
onos
.
net
.
intent
;
import
java.util.Objects
;
import
org.onlab.onos.net.ConnectPoint
;
import
org.onlab.onos.net.Path
;
import
org.onlab.onos.net.flow.TrafficSelector
;
import
org.onlab.onos.net.flow.TrafficTreatment
;
import
com.google.common.base.MoreObjects
;
/**
* Abstraction of explicitly path specified connectivity intent.
*/
public
class
PathIntent
extends
PointToPointIntent
{
private
final
Path
path
;
/**
* Creates a new point-to-point intent with the supplied ingress/egress
* ports and using the specified explicit path.
*
* @param id intent identifier
* @param match traffic match
* @param action action
* @param ingressPort ingress port
* @param egressPort egress port
* @param path traversed links
* @throws NullPointerException {@code path} is null
*/
public
PathIntent
(
IntentId
id
,
TrafficSelector
match
,
TrafficTreatment
action
,
ConnectPoint
ingressPort
,
ConnectPoint
egressPort
,
Path
path
)
{
super
(
id
,
match
,
action
,
ingressPort
,
egressPort
);
this
.
path
=
path
;
}
protected
PathIntent
()
{
super
();
this
.
path
=
null
;
}
/**
* Returns the links which the traffic goes along.
*
* @return traversed links
*/
public
Path
getPath
()
{
return
path
;
}
@Override
public
boolean
equals
(
Object
o
)
{
if
(
this
==
o
)
{
return
true
;
}
if
(
o
==
null
||
getClass
()
!=
o
.
getClass
())
{
return
false
;
}
if
(!
super
.
equals
(
o
))
{
return
false
;
}
PathIntent
that
=
(
PathIntent
)
o
;
if
(!
path
.
equals
(
that
.
path
))
{
return
false
;
}
return
true
;
}
@Override
public
int
hashCode
()
{
return
Objects
.
hash
(
super
.
hashCode
(),
path
);
}
@Override
public
String
toString
()
{
return
MoreObjects
.
toStringHelper
(
getClass
())
.
add
(
"id"
,
getId
())
.
add
(
"match"
,
getTrafficSelector
())
.
add
(
"action"
,
getTrafficTreatment
())
.
add
(
"ingressPort"
,
getIngressPort
())
.
add
(
"egressPort"
,
getEgressPort
())
.
add
(
"path"
,
path
)
.
toString
();
}
}
core/api/src/main/java/org/onlab/onos/net/intent/PointToPointIntent.java
0 → 100644
View file @
48e54c3
package
org
.
onlab
.
onos
.
net
.
intent
;
import
static
com
.
google
.
common
.
base
.
Preconditions
.
checkNotNull
;
import
java.util.Objects
;
import
org.onlab.onos.net.ConnectPoint
;
import
org.onlab.onos.net.flow.TrafficSelector
;
import
org.onlab.onos.net.flow.TrafficTreatment
;
import
com.google.common.base.MoreObjects
;
/**
* Abstraction of point-to-point connectivity.
*/
public
class
PointToPointIntent
extends
ConnectivityIntent
{
private
final
ConnectPoint
ingressPort
;
private
final
ConnectPoint
egressPort
;
/**
* Creates a new point-to-point intent with the supplied ingress/egress
* ports.
*
* @param id intent identifier
* @param match traffic match
* @param action action
* @param ingressPort ingress port
* @param egressPort egress port
* @throws NullPointerException if {@code ingressPort} or {@code egressPort} is null.
*/
public
PointToPointIntent
(
IntentId
id
,
TrafficSelector
match
,
TrafficTreatment
action
,
ConnectPoint
ingressPort
,
ConnectPoint
egressPort
)
{
super
(
id
,
match
,
action
);
this
.
ingressPort
=
checkNotNull
(
ingressPort
);
this
.
egressPort
=
checkNotNull
(
egressPort
);
}
/**
* Constructor for serializer.
*/
protected
PointToPointIntent
()
{
super
();
this
.
ingressPort
=
null
;
this
.
egressPort
=
null
;
}
/**
* Returns the port on which the ingress traffic should be connected to
* the egress.
*
* @return ingress port
*/
public
ConnectPoint
getIngressPort
()
{
return
ingressPort
;
}
/**
* Returns the port on which the traffic should egress.
*
* @return egress port
*/
public
ConnectPoint
getEgressPort
()
{
return
egressPort
;
}
@Override
public
boolean
equals
(
Object
o
)
{
if
(
this
==
o
)
{
return
true
;
}
if
(
o
==
null
||
getClass
()
!=
o
.
getClass
())
{
return
false
;
}
if
(!
super
.
equals
(
o
))
{
return
false
;
}
PointToPointIntent
that
=
(
PointToPointIntent
)
o
;
return
Objects
.
equals
(
this
.
ingressPort
,
that
.
ingressPort
)
&&
Objects
.
equals
(
this
.
egressPort
,
that
.
egressPort
);
}
@Override
public
int
hashCode
()
{
return
Objects
.
hash
(
super
.
hashCode
(),
ingressPort
,
egressPort
);
}
@Override
public
String
toString
()
{
return
MoreObjects
.
toStringHelper
(
getClass
())
.
add
(
"id"
,
getId
())
.
add
(
"match"
,
getTrafficSelector
())
.
add
(
"action"
,
getTrafficTreatment
())
.
add
(
"ingressPort"
,
ingressPort
)
.
add
(
"egressPort"
,
egressPort
)
.
toString
();
}
}
core/api/src/main/java/org/onlab/onos/net/intent/SinglePointToMultiPointIntent.java
0 → 100644
View file @
48e54c3
package
org
.
onlab
.
onos
.
net
.
intent
;
import
static
com
.
google
.
common
.
base
.
Preconditions
.
checkArgument
;
import
static
com
.
google
.
common
.
base
.
Preconditions
.
checkNotNull
;
import
java.util.Objects
;
import
java.util.Set
;
import
org.onlab.onos.net.ConnectPoint
;
import
org.onlab.onos.net.flow.TrafficSelector
;
import
org.onlab.onos.net.flow.TrafficTreatment
;
import
com.google.common.base.MoreObjects
;
import
com.google.common.collect.Sets
;
/**
* Abstraction of single source, multiple destination connectivity intent.
*/
public
class
SinglePointToMultiPointIntent
extends
ConnectivityIntent
{
private
final
ConnectPoint
ingressPort
;
private
final
Set
<
ConnectPoint
>
egressPorts
;
/**
* Creates a new single-to-multi point connectivity intent.
*
* @param id intent identifier
* @param match traffic match
* @param action action
* @param ingressPort port on which traffic will ingress
* @param egressPorts set of ports on which traffic will egress
* @throws NullPointerException if {@code ingressPort} or
* {@code egressPorts} is null
* @throws IllegalArgumentException if the size of {@code egressPorts} is
* not more than 1
*/
public
SinglePointToMultiPointIntent
(
IntentId
id
,
TrafficSelector
match
,
TrafficTreatment
action
,
ConnectPoint
ingressPort
,
Set
<
ConnectPoint
>
egressPorts
)
{
super
(
id
,
match
,
action
);
checkNotNull
(
egressPorts
);
checkArgument
(!
egressPorts
.
isEmpty
(),
"there should be at least one egress port"
);
this
.
ingressPort
=
checkNotNull
(
ingressPort
);
this
.
egressPorts
=
Sets
.
newHashSet
(
egressPorts
);
}
/**
* Constructor for serializer.
*/
protected
SinglePointToMultiPointIntent
()
{
super
();
this
.
ingressPort
=
null
;
this
.
egressPorts
=
null
;
}
/**
* Returns the port on which the ingress traffic should be connected to the egress.
*
* @return ingress port
*/
public
ConnectPoint
getIngressPort
()
{
return
ingressPort
;
}
/**
* Returns the set of ports on which the traffic should egress.
*
* @return set of egress ports
*/
public
Set
<
ConnectPoint
>
getEgressPorts
()
{
return
egressPorts
;
}
@Override
public
boolean
equals
(
Object
o
)
{
if
(
this
==
o
)
{
return
true
;
}
if
(
o
==
null
||
getClass
()
!=
o
.
getClass
())
{
return
false
;
}
if
(!
super
.
equals
(
o
))
{
return
false
;
}
SinglePointToMultiPointIntent
that
=
(
SinglePointToMultiPointIntent
)
o
;
return
Objects
.
equals
(
this
.
ingressPort
,
that
.
ingressPort
)
&&
Objects
.
equals
(
this
.
egressPorts
,
that
.
egressPorts
);
}
@Override
public
int
hashCode
()
{
return
Objects
.
hash
(
super
.
hashCode
(),
ingressPort
,
egressPorts
);
}
@Override
public
String
toString
()
{
return
MoreObjects
.
toStringHelper
(
getClass
())
.
add
(
"id"
,
getId
())
.
add
(
"match"
,
getTrafficSelector
())
.
add
(
"action"
,
getTrafficTreatment
())
.
add
(
"ingressPort"
,
ingressPort
)
.
add
(
"egressPort"
,
egressPorts
)
.
toString
();
}
}
core/api/src/main/java/org/onlab/onos/net/intent/package-info.java
0 → 100644
View file @
48e54c3
/**
* Intent Package. TODO
*/
package
org
.
onlab
.
onos
.
net
.
intent
;
\ No newline at end of file
core/store/trivial/src/main/java/org/onlab/onos/store/trivial/impl/SimpleDeviceStore.java
View file @
48e54c3
...
...
@@ -9,6 +9,8 @@ import org.apache.felix.scr.annotations.Activate;
import
org.apache.felix.scr.annotations.Component
;
import
org.apache.felix.scr.annotations.Deactivate
;
import
org.apache.felix.scr.annotations.Service
;
import
org.onlab.onos.net.Annotations
;
import
org.onlab.onos.net.DefaultAnnotations
;
import
org.onlab.onos.net.DefaultDevice
;
import
org.onlab.onos.net.DefaultPort
;
import
org.onlab.onos.net.Device
;
...
...
@@ -16,6 +18,9 @@ import org.onlab.onos.net.Device.Type;
import
org.onlab.onos.net.DeviceId
;
import
org.onlab.onos.net.Port
;
import
org.onlab.onos.net.PortNumber
;
import
org.onlab.onos.net.SparseAnnotations
;
import
org.onlab.onos.net.device.DefaultDeviceDescription
;
import
org.onlab.onos.net.device.DefaultPortDescription
;
import
org.onlab.onos.net.device.DeviceDescription
;
import
org.onlab.onos.net.device.DeviceEvent
;
import
org.onlab.onos.net.device.DeviceStore
;
...
...
@@ -45,6 +50,7 @@ import static com.google.common.base.Predicates.notNull;
import
static
org
.
onlab
.
onos
.
net
.
device
.
DeviceEvent
.
Type
.*;
import
static
org
.
slf4j
.
LoggerFactory
.
getLogger
;
import
static
org
.
apache
.
commons
.
lang3
.
concurrent
.
ConcurrentUtils
.
createIfAbsentUnchecked
;
import
static
org
.
onlab
.
onos
.
net
.
DefaultAnnotations
.
merge
;
// TODO: synchronization should be done in more fine-grained manner.
/**
...
...
@@ -112,8 +118,8 @@ public class SimpleDeviceStore
=
createIfAbsentUnchecked
(
providerDescs
,
providerId
,
new
InitDeviceDescs
(
deviceDescription
));
// update description
descs
.
putDeviceDesc
(
deviceDescription
);
Device
newDevice
=
composeDevice
(
deviceId
,
providerDescs
);
if
(
oldDevice
==
null
)
{
...
...
@@ -144,7 +150,8 @@ public class SimpleDeviceStore
// We allow only certain attributes to trigger update
if
(!
Objects
.
equals
(
oldDevice
.
hwVersion
(),
newDevice
.
hwVersion
())
||
!
Objects
.
equals
(
oldDevice
.
swVersion
(),
newDevice
.
swVersion
()))
{
!
Objects
.
equals
(
oldDevice
.
swVersion
(),
newDevice
.
swVersion
())
||
!
isAnnotationsEqual
(
oldDevice
.
annotations
(),
newDevice
.
annotations
()))
{
synchronized
(
this
)
{
devices
.
replace
(
newDevice
.
id
(),
oldDevice
,
newDevice
);
...
...
@@ -203,7 +210,7 @@ public class SimpleDeviceStore
PortNumber
number
=
portDescription
.
portNumber
();
Port
oldPort
=
ports
.
get
(
number
);
// update description
descs
.
putPortDesc
(
number
,
portDescription
);
descs
.
putPortDesc
(
portDescription
);
Port
newPort
=
composePort
(
device
,
number
,
descsMap
);
events
.
add
(
oldPort
==
null
?
...
...
@@ -225,12 +232,14 @@ public class SimpleDeviceStore
return
new
DeviceEvent
(
PORT_ADDED
,
device
,
newPort
);
}
// C
H
ecks if the specified port requires update and if so, it replaces the
// C
h
ecks if the specified port requires update and if so, it replaces the
// existing entry in the map and returns corresponding event.
private
DeviceEvent
updatePort
(
Device
device
,
Port
oldPort
,
Port
newPort
,
ConcurrentMap
<
PortNumber
,
Port
>
ports
)
{
if
(
oldPort
.
isEnabled
()
!=
newPort
.
isEnabled
())
{
if
(
oldPort
.
isEnabled
()
!=
newPort
.
isEnabled
()
||
!
isAnnotationsEqual
(
oldPort
.
annotations
(),
newPort
.
annotations
()))
{
ports
.
put
(
oldPort
.
number
(),
newPort
);
return
new
DeviceEvent
(
PORT_UPDATED
,
device
,
newPort
);
}
...
...
@@ -272,17 +281,17 @@ public class SimpleDeviceStore
checkArgument
(
descsMap
!=
null
,
DEVICE_NOT_FOUND
,
deviceId
);
DeviceDescriptions
descs
=
descsMap
.
get
(
providerId
);
// assuming all providers must to give DeviceDescription
checkArgument
(
descs
!=
null
,
"Device description for Device ID %s from Provider %s was not found"
,
deviceId
,
providerId
);
// TODO: implement multi-provider
synchronized
(
this
)
{
ConcurrentMap
<
PortNumber
,
Port
>
ports
=
getPortMap
(
deviceId
);
final
PortNumber
number
=
portDescription
.
portNumber
();
Port
oldPort
=
ports
.
get
(
number
);
// update description
descs
.
putPortDesc
(
number
,
portDescription
);
descs
.
putPortDesc
(
portDescription
);
Port
newPort
=
composePort
(
device
,
number
,
descsMap
);
if
(
oldPort
==
null
)
{
return
createPort
(
device
,
newPort
,
ports
);
...
...
@@ -321,6 +330,26 @@ public class SimpleDeviceStore
}
}
private
static
boolean
isAnnotationsEqual
(
Annotations
lhs
,
Annotations
rhs
)
{
if
(
lhs
==
rhs
)
{
return
true
;
}
if
(
lhs
==
null
||
rhs
==
null
)
{
return
false
;
}
if
(!
lhs
.
keys
().
equals
(
rhs
.
keys
()))
{
return
false
;
}
for
(
String
key
:
lhs
.
keys
())
{
if
(!
lhs
.
value
(
key
).
equals
(
rhs
.
value
(
key
)))
{
return
false
;
}
}
return
true
;
}
/**
* Returns a Device, merging description given from multiple Providers.
*
...
...
@@ -336,46 +365,67 @@ public class SimpleDeviceStore
ProviderId
primary
=
pickPrimaryPID
(
providerDescs
);
DeviceDescriptions
desc
=
providerDescs
.
get
(
primary
);
// base
Type
type
=
desc
.
getDeviceDesc
().
type
();
String
manufacturer
=
desc
.
getDeviceDesc
().
manufacturer
();
String
hwVersion
=
desc
.
getDeviceDesc
().
hwVersion
();
String
swVersion
=
desc
.
getDeviceDesc
().
swVersion
();
String
serialNumber
=
desc
.
getDeviceDesc
().
serialNumber
();
DefaultAnnotations
annotations
=
DefaultAnnotations
.
builder
().
build
();
annotations
=
merge
(
annotations
,
desc
.
getDeviceDesc
().
annotations
());
for
(
Entry
<
ProviderId
,
DeviceDescriptions
>
e
:
providerDescs
.
entrySet
())
{
if
(
e
.
getKey
().
equals
(
primary
))
{
continue
;
}
// FIXME: implement attribute merging once we have K-V attributes
// TODO: should keep track of Description timestamp
// and only merge conflicting keys when timestamp is newer
// Currently assuming there will never be a key conflict between
// providers
// annotation merging. not so efficient, should revisit later
annotations
=
merge
(
annotations
,
e
.
getValue
().
getDeviceDesc
().
annotations
());
}
return
new
DefaultDevice
(
primary
,
deviceId
,
type
,
manufacturer
,
hwVersion
,
swVersion
,
serialNumber
);
return
new
DefaultDevice
(
primary
,
deviceId
,
type
,
manufacturer
,
hwVersion
,
swVersion
,
serialNumber
,
annotations
);
}
// probably want composePort
s
// probably want composePort
"s" also
private
Port
composePort
(
Device
device
,
PortNumber
number
,
ConcurrentMap
<
ProviderId
,
DeviceDescriptions
>
providerDescs
)
{
ProviderId
primary
=
pickPrimaryPID
(
providerDescs
);
DeviceDescriptions
primDescs
=
providerDescs
.
get
(
primary
);
// if no primary, assume not enabled
// TODO: revisit this default port enabled/disabled behavior
boolean
isEnabled
=
false
;
DefaultAnnotations
annotations
=
DefaultAnnotations
.
builder
().
build
();
final
PortDescription
portDesc
=
primDescs
.
getPortDesc
(
number
);
boolean
isEnabled
;
if
(
portDesc
!=
null
)
{
isEnabled
=
portDesc
.
isEnabled
();
}
else
{
// if no primary, assume not enabled
// TODO: revisit this port enabled/disabled behavior
isEnabled
=
false
;
annotations
=
merge
(
annotations
,
portDesc
.
annotations
());
}
for
(
Entry
<
ProviderId
,
DeviceDescriptions
>
e
:
providerDescs
.
entrySet
())
{
if
(
e
.
getKey
().
equals
(
primary
))
{
continue
;
}
// FIXME: implement attribute merging once we have K-V attributes
// TODO: should keep track of Description timestamp
// and only merge conflicting keys when timestamp is newer
// Currently assuming there will never be a key conflict between
// providers
// annotation merging. not so efficient, should revisit later
final
PortDescription
otherPortDesc
=
e
.
getValue
().
getPortDesc
(
number
);
if
(
otherPortDesc
!=
null
)
{
annotations
=
merge
(
annotations
,
otherPortDesc
.
annotations
());
}
}
return
new
DefaultPort
(
device
,
number
,
isEnabled
);
return
new
DefaultPort
(
device
,
number
,
isEnabled
,
annotations
);
}
/**
...
...
@@ -428,7 +478,7 @@ public class SimpleDeviceStore
private
final
ConcurrentMap
<
PortNumber
,
PortDescription
>
portDescs
;
public
DeviceDescriptions
(
DeviceDescription
desc
)
{
this
.
deviceDesc
=
new
AtomicReference
<>(
desc
);
this
.
deviceDesc
=
new
AtomicReference
<>(
checkNotNull
(
desc
)
);
this
.
portDescs
=
new
ConcurrentHashMap
<>();
}
...
...
@@ -444,12 +494,38 @@ public class SimpleDeviceStore
return
Collections
.
unmodifiableCollection
(
portDescs
.
values
());
}
public
DeviceDescription
putDeviceDesc
(
DeviceDescription
newDesc
)
{
return
deviceDesc
.
getAndSet
(
newDesc
);
/**
* Puts DeviceDescription, merging annotations as necessary.
*
* @param newDesc new DeviceDescription
* @return previous DeviceDescription
*/
public
synchronized
DeviceDescription
putDeviceDesc
(
DeviceDescription
newDesc
)
{
DeviceDescription
oldOne
=
deviceDesc
.
get
();
DeviceDescription
newOne
=
newDesc
;
if
(
oldOne
!=
null
)
{
SparseAnnotations
merged
=
merge
(
oldOne
.
annotations
(),
newDesc
.
annotations
());
newOne
=
new
DefaultDeviceDescription
(
newOne
,
merged
);
}
return
deviceDesc
.
getAndSet
(
newOne
);
}
public
PortDescription
putPortDesc
(
PortNumber
number
,
PortDescription
newDesc
)
{
return
portDescs
.
put
(
number
,
newDesc
);
/**
* Puts PortDescription, merging annotations as necessary.
*
* @param newDesc new PortDescription
* @return previous PortDescription
*/
public
synchronized
PortDescription
putPortDesc
(
PortDescription
newDesc
)
{
PortDescription
oldOne
=
portDescs
.
get
(
newDesc
.
portNumber
());
PortDescription
newOne
=
newDesc
;
if
(
oldOne
!=
null
)
{
SparseAnnotations
merged
=
merge
(
oldOne
.
annotations
(),
newDesc
.
annotations
());
newOne
=
new
DefaultPortDescription
(
newOne
,
merged
);
}
return
portDescs
.
put
(
newOne
.
portNumber
(),
newOne
);
}
}
}
...
...
core/store/trivial/src/test/java/org/onlab/onos/store/trivial/impl/SimpleDeviceStoreTest.java
View file @
48e54c3
...
...
@@ -22,10 +22,13 @@ import org.junit.Before;
import
org.junit.BeforeClass
;
import
org.junit.Ignore
;
import
org.junit.Test
;
import
org.onlab.onos.net.Annotations
;
import
org.onlab.onos.net.DefaultAnnotations
;
import
org.onlab.onos.net.Device
;
import
org.onlab.onos.net.DeviceId
;
import
org.onlab.onos.net.Port
;
import
org.onlab.onos.net.PortNumber
;
import
org.onlab.onos.net.SparseAnnotations
;
import
org.onlab.onos.net.device.DefaultDeviceDescription
;
import
org.onlab.onos.net.device.DefaultPortDescription
;
import
org.onlab.onos.net.device.DeviceDescription
;
...
...
@@ -57,6 +60,23 @@ public class SimpleDeviceStoreTest {
private
static
final
PortNumber
P2
=
PortNumber
.
portNumber
(
2
);
private
static
final
PortNumber
P3
=
PortNumber
.
portNumber
(
3
);
private
static
final
SparseAnnotations
A1
=
DefaultAnnotations
.
builder
()
.
set
(
"A1"
,
"a1"
)
.
set
(
"B1"
,
"b1"
)
.
build
();
private
static
final
SparseAnnotations
A1_2
=
DefaultAnnotations
.
builder
()
.
remove
(
"A1"
)
.
set
(
"B3"
,
"b3"
)
.
build
();
private
static
final
SparseAnnotations
A2
=
DefaultAnnotations
.
builder
()
.
set
(
"A2"
,
"a2"
)
.
set
(
"B2"
,
"b2"
)
.
build
();
private
static
final
SparseAnnotations
A2_2
=
DefaultAnnotations
.
builder
()
.
remove
(
"A2"
)
.
set
(
"B4"
,
"b4"
)
.
build
();
private
SimpleDeviceStore
simpleDeviceStore
;
private
DeviceStore
deviceStore
;
...
...
@@ -106,6 +126,24 @@ public class SimpleDeviceStoreTest {
assertEquals
(
SN
,
device
.
serialNumber
());
}
/**
* Verifies that Annotations created by merging {@code annotations} is
* equal to actual Annotations.
*
* @param actual Annotations to check
* @param annotations
*/
private
static
void
assertAnnotationsEquals
(
Annotations
actual
,
SparseAnnotations
...
annotations
)
{
DefaultAnnotations
expected
=
DefaultAnnotations
.
builder
().
build
();
for
(
SparseAnnotations
a
:
annotations
)
{
expected
=
DefaultAnnotations
.
merge
(
expected
,
a
);
}
assertEquals
(
expected
.
keys
(),
actual
.
keys
());
for
(
String
key
:
expected
.
keys
())
{
assertEquals
(
expected
.
value
(
key
),
actual
.
value
(
key
));
}
}
@Test
public
final
void
testGetDeviceCount
()
{
assertEquals
(
"initialy empty"
,
0
,
deviceStore
.
getDeviceCount
());
...
...
@@ -171,26 +209,41 @@ public class SimpleDeviceStoreTest {
public
final
void
testCreateOrUpdateDeviceAncillary
()
{
DeviceDescription
description
=
new
DefaultDeviceDescription
(
DID1
.
uri
(),
SWITCH
,
MFR
,
HW
,
SW1
,
SN
);
HW
,
SW1
,
SN
,
A2
);
DeviceEvent
event
=
deviceStore
.
createOrUpdateDevice
(
PIDA
,
DID1
,
description
);
assertEquals
(
DEVICE_ADDED
,
event
.
type
());
assertDevice
(
DID1
,
SW1
,
event
.
subject
());
assertEquals
(
PIDA
,
event
.
subject
().
providerId
());
assertAnnotationsEquals
(
event
.
subject
().
annotations
(),
A2
);
assertFalse
(
"Ancillary will not bring device up"
,
deviceStore
.
isAvailable
(
DID1
));
DeviceDescription
description2
=
new
DefaultDeviceDescription
(
DID1
.
uri
(),
SWITCH
,
MFR
,
HW
,
SW2
,
SN
);
HW
,
SW2
,
SN
,
A1
);
DeviceEvent
event2
=
deviceStore
.
createOrUpdateDevice
(
PID
,
DID1
,
description2
);
assertEquals
(
DEVICE_UPDATED
,
event2
.
type
());
assertDevice
(
DID1
,
SW2
,
event2
.
subject
());
assertEquals
(
PID
,
event2
.
subject
().
providerId
());
assertAnnotationsEquals
(
event2
.
subject
().
annotations
(),
A1
,
A2
);
assertTrue
(
deviceStore
.
isAvailable
(
DID1
));
assertNull
(
"No change expected"
,
deviceStore
.
createOrUpdateDevice
(
PID
,
DID1
,
description2
));
// For now, Ancillary is ignored once primary appears
assertNull
(
"No change expected"
,
deviceStore
.
createOrUpdateDevice
(
PIDA
,
DID1
,
description
));
// But, Ancillary annotations will be in effect
DeviceDescription
description3
=
new
DefaultDeviceDescription
(
DID1
.
uri
(),
SWITCH
,
MFR
,
HW
,
SW1
,
SN
,
A2_2
);
DeviceEvent
event3
=
deviceStore
.
createOrUpdateDevice
(
PIDA
,
DID1
,
description3
);
assertEquals
(
DEVICE_UPDATED
,
event3
.
type
());
// basic information will be the one from Primary
assertDevice
(
DID1
,
SW2
,
event3
.
subject
());
assertEquals
(
PID
,
event3
.
subject
().
providerId
());
// but annotation from Ancillary will be merged
assertAnnotationsEquals
(
event3
.
subject
().
annotations
(),
A1
,
A2
,
A2_2
);
assertTrue
(
deviceStore
.
isAvailable
(
DID1
));
}
...
...
@@ -299,27 +352,40 @@ public class SimpleDeviceStoreTest {
putDeviceAncillary
(
DID1
,
SW1
);
putDevice
(
DID1
,
SW1
);
List
<
PortDescription
>
pds
=
Arrays
.<
PortDescription
>
asList
(
new
DefaultPortDescription
(
P1
,
true
)
new
DefaultPortDescription
(
P1
,
true
,
A1
)
);
deviceStore
.
updatePorts
(
PID
,
DID1
,
pds
);
DeviceEvent
event
=
deviceStore
.
updatePortStatus
(
PID
,
DID1
,
new
DefaultPortDescription
(
P1
,
false
));
new
DefaultPortDescription
(
P1
,
false
,
A1_2
));
assertEquals
(
PORT_UPDATED
,
event
.
type
());
assertDevice
(
DID1
,
SW1
,
event
.
subject
());
assertEquals
(
P1
,
event
.
port
().
number
());
assertAnnotationsEquals
(
event
.
port
().
annotations
(),
A1
,
A1_2
);
assertFalse
(
"Port is disabled"
,
event
.
port
().
isEnabled
());
DeviceEvent
event2
=
deviceStore
.
updatePortStatus
(
PIDA
,
DID1
,
new
DefaultPortDescription
(
P1
,
true
));
assertNull
(
"Ancillary is ignored if primary exists"
,
event2
);
// but, Ancillary annotation update will be notified
DeviceEvent
event3
=
deviceStore
.
updatePortStatus
(
PIDA
,
DID1
,
new
DefaultPortDescription
(
P
2
,
true
));
assertEquals
(
PORT_
ADD
ED
,
event3
.
type
());
new
DefaultPortDescription
(
P
1
,
true
,
A2
));
assertEquals
(
PORT_
UPDAT
ED
,
event3
.
type
());
assertDevice
(
DID1
,
SW1
,
event3
.
subject
());
assertEquals
(
P2
,
event3
.
port
().
number
());
assertFalse
(
"Port is disabled if not given from provider"
,
event3
.
port
().
isEnabled
());
assertEquals
(
P1
,
event3
.
port
().
number
());
assertAnnotationsEquals
(
event3
.
port
().
annotations
(),
A1
,
A1_2
,
A2
);
assertFalse
(
"Port is disabled"
,
event3
.
port
().
isEnabled
());
// port only reported from Ancillary will be notified as down
DeviceEvent
event4
=
deviceStore
.
updatePortStatus
(
PIDA
,
DID1
,
new
DefaultPortDescription
(
P2
,
true
));
assertEquals
(
PORT_ADDED
,
event4
.
type
());
assertDevice
(
DID1
,
SW1
,
event4
.
subject
());
assertEquals
(
P2
,
event4
.
port
().
number
());
assertAnnotationsEquals
(
event4
.
port
().
annotations
());
assertFalse
(
"Port is disabled if not given from primary provider"
,
event4
.
port
().
isEnabled
());
}
@Test
...
...
Please
register
or
login
to post a comment