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
Marc De Leenheer
2014-10-23 13:13:10 -0700
Browse Files
Options
Browse Files
Download
Plain Diff
Commit
922760bec971178a8f205eb9ceecfde0c3c2641d
922760be
2 parents
8d9d38f3
868def0f
Merge branch 'master' into optical-integration
Show whitespace changes
Inline
Side-by-side
Showing
30 changed files
with
488 additions
and
220 deletions
apps/sdnip/src/main/resources/config-examples/sdnip.json
core/api/src/main/java/org/onlab/onos/net/flow/BatchOperationResult.java
core/api/src/main/java/org/onlab/onos/net/flow/CompletedBatchOperation.java
core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleBatchEvent.java
core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleBatchRequest.java
core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleProvider.java
core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleStore.java
core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleStoreDelegate.java
core/net/src/main/java/org/onlab/onos/net/flow/impl/FlowRuleManager.java
core/net/src/main/java/org/onlab/onos/net/link/impl/LinkManager.java
core/net/src/main/java/org/onlab/onos/net/statistic/impl/StatisticManager.java
core/net/src/test/java/org/onlab/onos/net/flow/impl/FlowRuleManagerTest.java
core/store/dist/src/main/java/org/onlab/onos/store/flow/impl/DistributedFlowRuleStore.java
core/store/dist/src/main/java/org/onlab/onos/store/flow/impl/FlowStoreMessageSubjects.java
core/store/dist/src/main/java/org/onlab/onos/store/host/impl/GossipHostStore.java
core/store/hz/cluster/src/main/java/org/onlab/onos/store/mastership/impl/RoleValue.java
core/store/hz/cluster/src/main/java/org/onlab/onos/store/mastership/impl/RoleValueSerializer.java
core/store/hz/common/src/main/java/org/onlab/onos/store/common/SMap.java
core/store/serializers/src/main/java/org/onlab/onos/store/serializers/KryoNamespaces.java
core/store/trivial/src/main/java/org/onlab/onos/store/trivial/impl/SimpleFlowRuleStore.java
core/store/trivial/src/main/java/org/onlab/onos/store/trivial/impl/SimpleHostStore.java
openflow/ctl/src/main/java/org/onlab/onos/openflow/controller/impl/OFChannelHandler.java
openflow/ctl/src/main/java/org/onlab/onos/openflow/drivers/impl/OFSwitchImplCPqD13.java
providers/lldp/src/main/java/org/onlab/onos/provider/lldp/impl/LinkDiscovery.java
providers/openflow/flow/src/main/java/org/onlab/onos/provider/of/flow/impl/OpenFlowRuleProvider.java
utils/misc/src/main/java/org/onlab/packet/ChassisId.java
utils/misc/src/main/java/org/onlab/packet/DHCP.java
utils/misc/src/main/java/org/onlab/packet/IPv4.java
utils/misc/src/main/java/org/onlab/util/HexString.java
utils/netty/src/main/java/org/onlab/netty/NettyMessagingService.java
apps/sdnip/src/main/resources/config-examples/sdnip.json
View file @
922760b
...
...
@@ -14,6 +14,16 @@
"attachmentDpid"
:
"00:00:00:00:00:00:00:a2"
,
"attachmentPort"
:
"1"
,
"ipAddress"
:
"192.168.30.1"
},
{
"attachmentDpid"
:
"00:00:00:00:00:00:00:a6"
,
"attachmentPort"
:
"1"
,
"ipAddress"
:
"192.168.40.1"
},
{
"attachmentDpid"
:
"00:00:00:00:00:00:00:a4"
,
"attachmentPort"
:
"4"
,
"ipAddress"
:
"192.168.60.1"
}
],
"bgpSpeakers"
:
[
...
...
core/api/src/main/java/org/onlab/onos/net/flow/BatchOperationResult.java
View file @
922760b
...
...
@@ -18,7 +18,7 @@
*/
package
org
.
onlab
.
onos
.
net
.
flow
;
import
java.util.
Lis
t
;
import
java.util.
Se
t
;
/**
* Interface capturing the result of a batch operation.
...
...
@@ -33,9 +33,9 @@ public interface BatchOperationResult<T> {
boolean
isSuccess
();
/**
* Obtains a
lis
t of items which failed.
* @return a
lis
t of failures
* Obtains a
se
t of items which failed.
* @return a
se
t of failures
*/
Lis
t
<
T
>
failedItems
();
Se
t
<
T
>
failedItems
();
}
...
...
core/api/src/main/java/org/onlab/onos/net/flow/CompletedBatchOperation.java
View file @
922760b
...
...
@@ -18,19 +18,19 @@
*/
package
org
.
onlab
.
onos
.
net
.
flow
;
import
java.util.
Lis
t
;
import
java.util.
Se
t
;
import
com.google.common.collect.Immutable
Lis
t
;
import
com.google.common.collect.Immutable
Se
t
;
public
class
CompletedBatchOperation
implements
BatchOperationResult
<
FlowEntry
>
{
private
final
boolean
success
;
private
final
Lis
t
<
FlowEntry
>
failures
;
private
final
Se
t
<
FlowEntry
>
failures
;
public
CompletedBatchOperation
(
boolean
success
,
Lis
t
<
FlowEntry
>
failures
)
{
public
CompletedBatchOperation
(
boolean
success
,
Se
t
<
FlowEntry
>
failures
)
{
this
.
success
=
success
;
this
.
failures
=
Immutable
Lis
t
.
copyOf
(
failures
);
this
.
failures
=
Immutable
Se
t
.
copyOf
(
failures
);
}
@Override
...
...
@@ -39,7 +39,7 @@ public class CompletedBatchOperation implements BatchOperationResult<FlowEntry>
}
@Override
public
Lis
t
<
FlowEntry
>
failedItems
()
{
public
Se
t
<
FlowEntry
>
failedItems
()
{
return
failures
;
}
...
...
core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleBatchEvent.java
0 → 100644
View file @
922760b
package
org
.
onlab
.
onos
.
net
.
flow
;
import
org.onlab.onos.event.AbstractEvent
;
/**
* Describes flow rule batch event.
*/
public
final
class
FlowRuleBatchEvent
extends
AbstractEvent
<
FlowRuleBatchEvent
.
Type
,
FlowRuleBatchRequest
>
{
/**
* Type of flow rule events.
*/
public
enum
Type
{
/**
* Signifies that a batch operation has been initiated.
*/
BATCH_OPERATION_REQUESTED
,
/**
* Signifies that a batch operation has completed.
*/
BATCH_OPERATION_COMPLETED
,
}
private
final
CompletedBatchOperation
result
;
/**
* Constructs a new FlowRuleBatchEvent.
* @param request batch operation request.
* @return event.
*/
public
static
FlowRuleBatchEvent
create
(
FlowRuleBatchRequest
request
)
{
FlowRuleBatchEvent
event
=
new
FlowRuleBatchEvent
(
Type
.
BATCH_OPERATION_REQUESTED
,
request
,
null
);
return
event
;
}
/**
* Constructs a new FlowRuleBatchEvent.
* @param request batch operation request.
* @param result completed batch operation result.
* @return event.
*/
public
static
FlowRuleBatchEvent
create
(
FlowRuleBatchRequest
request
,
CompletedBatchOperation
result
)
{
FlowRuleBatchEvent
event
=
new
FlowRuleBatchEvent
(
Type
.
BATCH_OPERATION_COMPLETED
,
request
,
result
);
return
event
;
}
/**
* Returns the result of this batch operation.
* @return batch operation result.
*/
public
CompletedBatchOperation
result
()
{
return
result
;
}
/**
* Creates an event of a given type and for the specified flow rule batch.
*
* @param type flow rule batch event type
* @param batch event flow rule batch subject
*/
private
FlowRuleBatchEvent
(
Type
type
,
FlowRuleBatchRequest
request
,
CompletedBatchOperation
result
)
{
super
(
type
,
request
);
this
.
result
=
result
;
}
}
core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleBatchRequest.java
0 → 100644
View file @
922760b
package
org
.
onlab
.
onos
.
net
.
flow
;
import
java.util.Collections
;
import
java.util.List
;
import
org.onlab.onos.net.flow.FlowRuleBatchEntry.FlowRuleOperation
;
import
com.google.common.collect.Lists
;
public
class
FlowRuleBatchRequest
{
private
final
List
<
FlowEntry
>
toAdd
;
private
final
List
<
FlowEntry
>
toRemove
;
public
FlowRuleBatchRequest
(
List
<
FlowEntry
>
toAdd
,
List
<
FlowEntry
>
toRemove
)
{
this
.
toAdd
=
Collections
.
unmodifiableList
(
toAdd
);
this
.
toRemove
=
Collections
.
unmodifiableList
(
toRemove
);
}
public
List
<
FlowEntry
>
toAdd
()
{
return
toAdd
;
}
public
List
<
FlowEntry
>
toRemove
()
{
return
toRemove
;
}
public
FlowRuleBatchOperation
asBatchOperation
()
{
List
<
FlowRuleBatchEntry
>
entries
=
Lists
.
newArrayList
();
for
(
FlowEntry
e
:
toAdd
)
{
entries
.
add
(
new
FlowRuleBatchEntry
(
FlowRuleOperation
.
ADD
,
e
));
}
for
(
FlowEntry
e
:
toRemove
)
{
entries
.
add
(
new
FlowRuleBatchEntry
(
FlowRuleOperation
.
REMOVE
,
e
));
}
return
new
FlowRuleBatchOperation
(
entries
);
}
}
core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleProvider.java
View file @
922760b
...
...
@@ -18,11 +18,11 @@
*/
package
org
.
onlab
.
onos
.
net
.
flow
;
import
java.util.concurrent.Future
;
import
org.onlab.onos.ApplicationId
;
import
org.onlab.onos.net.provider.Provider
;
import
com.google.common.util.concurrent.ListenableFuture
;
/**
* Abstraction of a flow rule provider.
*/
...
...
@@ -60,6 +60,6 @@ public interface FlowRuleProvider extends Provider {
* @param batch a batch of flow rules
* @return a future indicating the status of this execution
*/
Future
<
CompletedBatchOperation
>
executeBatch
(
BatchOperation
<
FlowRuleBatchEntry
>
batch
);
Listenable
Future
<
CompletedBatchOperation
>
executeBatch
(
BatchOperation
<
FlowRuleBatchEntry
>
batch
);
}
...
...
core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleStore.java
View file @
922760b
...
...
@@ -18,6 +18,8 @@
*/
package
org
.
onlab
.
onos
.
net
.
flow
;
import
java.util.concurrent.Future
;
import
org.onlab.onos.ApplicationId
;
import
org.onlab.onos.net.DeviceId
;
import
org.onlab.onos.store.Store
;
...
...
@@ -25,7 +27,7 @@ import org.onlab.onos.store.Store;
/**
* Manages inventory of flow rules; not intended for direct use.
*/
public
interface
FlowRuleStore
extends
Store
<
FlowRuleEvent
,
FlowRuleStoreDelegate
>
{
public
interface
FlowRuleStore
extends
Store
<
FlowRule
Batch
Event
,
FlowRuleStoreDelegate
>
{
/**
* Returns the number of flow rule in the store.
...
...
@@ -59,12 +61,26 @@ public interface FlowRuleStore extends Store<FlowRuleEvent, FlowRuleStoreDelegat
Iterable
<
FlowRule
>
getFlowRulesByAppId
(
ApplicationId
appId
);
/**
// TODO: Better description of method behavior.
* Stores a new flow rule without generating events.
*
* @param rule the flow rule to add
* @return true if the rule should be handled locally
*/
boolean
storeFlowRule
(
FlowRule
rule
);
void
storeFlowRule
(
FlowRule
rule
);
/**
* Stores a batch of flow rules.
* @param batchOperation batch of flow rules.
* @return Future response indicating success/failure of the batch operation
* all the way down to the device.
*/
Future
<
CompletedBatchOperation
>
storeBatch
(
FlowRuleBatchOperation
batchOperation
);
/**
* Invoked on the completion of a storeBatch operation.
* @param result
*/
void
batchOperationComplete
(
FlowRuleBatchEvent
event
);
/**
* Marks a flow rule for deletion. Actual deletion will occur
...
...
@@ -73,7 +89,7 @@ public interface FlowRuleStore extends Store<FlowRuleEvent, FlowRuleStoreDelegat
* @param rule the flow rule to delete
* @return true if the rule should be handled locally
*/
boolean
deleteFlowRule
(
FlowRule
rule
);
void
deleteFlowRule
(
FlowRule
rule
);
/**
* Stores a new flow rule, or updates an existing entry.
...
...
core/api/src/main/java/org/onlab/onos/net/flow/FlowRuleStoreDelegate.java
View file @
922760b
...
...
@@ -23,5 +23,5 @@ import org.onlab.onos.store.StoreDelegate;
/**
* Flow rule store delegate abstraction.
*/
public
interface
FlowRuleStoreDelegate
extends
StoreDelegate
<
FlowRuleEvent
>
{
public
interface
FlowRuleStoreDelegate
extends
StoreDelegate
<
FlowRule
Batch
Event
>
{
}
...
...
core/net/src/main/java/org/onlab/onos/net/flow/impl/FlowRuleManager.java
View file @
922760b
...
...
@@ -5,8 +5,10 @@ import static org.slf4j.LoggerFactory.getLogger;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Set
;
import
java.util.concurrent.CancellationException
;
import
java.util.concurrent.ExecutionException
;
import
java.util.concurrent.Executors
;
import
java.util.concurrent.Future
;
import
java.util.concurrent.TimeUnit
;
import
java.util.concurrent.TimeoutException
;
...
...
@@ -30,7 +32,9 @@ import org.onlab.onos.net.flow.FlowEntry;
import
org.onlab.onos.net.flow.FlowRule
;
import
org.onlab.onos.net.flow.FlowRuleBatchEntry
;
import
org.onlab.onos.net.flow.FlowRuleBatchEntry.FlowRuleOperation
;
import
org.onlab.onos.net.flow.FlowRuleBatchEvent
;
import
org.onlab.onos.net.flow.FlowRuleBatchOperation
;
import
org.onlab.onos.net.flow.FlowRuleBatchRequest
;
import
org.onlab.onos.net.flow.FlowRuleEvent
;
import
org.onlab.onos.net.flow.FlowRuleListener
;
import
org.onlab.onos.net.flow.FlowRuleProvider
;
...
...
@@ -47,6 +51,9 @@ import com.google.common.collect.ArrayListMultimap;
import
com.google.common.collect.Lists
;
import
com.google.common.collect.Maps
;
import
com.google.common.collect.Multimap
;
import
com.google.common.collect.Sets
;
import
com.google.common.util.concurrent.Futures
;
import
com.google.common.util.concurrent.ListenableFuture
;
/**
* Provides implementation of the flow NB & SB APIs.
...
...
@@ -104,14 +111,7 @@ public class FlowRuleManager
public
void
applyFlowRules
(
FlowRule
...
flowRules
)
{
for
(
int
i
=
0
;
i
<
flowRules
.
length
;
i
++)
{
FlowRule
f
=
flowRules
[
i
];
boolean
local
=
store
.
storeFlowRule
(
f
);
if
(
local
)
{
// TODO: aggregate all local rules and push down once?
applyFlowRulesToProviders
(
f
);
eventDispatcher
.
post
(
new
FlowRuleEvent
(
FlowRuleEvent
.
Type
.
RULE_ADD_REQUESTED
,
f
));
}
store
.
storeFlowRule
(
f
);
}
}
...
...
@@ -135,13 +135,7 @@ public class FlowRuleManager
FlowRule
f
;
for
(
int
i
=
0
;
i
<
flowRules
.
length
;
i
++)
{
f
=
flowRules
[
i
];
boolean
local
=
store
.
deleteFlowRule
(
f
);
if
(
local
)
{
// TODO: aggregate all local rules and push down once?
removeFlowRulesFromProviders
(
f
);
eventDispatcher
.
post
(
new
FlowRuleEvent
(
FlowRuleEvent
.
Type
.
RULE_REMOVE_REQUESTED
,
f
));
}
store
.
deleteFlowRule
(
f
);
}
}
...
...
@@ -185,33 +179,21 @@ public class FlowRuleManager
@Override
public
Future
<
CompletedBatchOperation
>
applyBatch
(
FlowRuleBatchOperation
batch
)
{
Multimap
<
FlowRuleProvider
,
FlowRuleBatchEntry
>
b
atches
=
Multimap
<
DeviceId
,
FlowRuleBatchEntry
>
perDeviceB
atches
=
ArrayListMultimap
.
create
();
List
<
Future
<
CompletedBatchOperation
>>
futures
=
Lists
.
newArrayList
();
for
(
FlowRuleBatchEntry
fbe
:
batch
.
getOperations
())
{
final
FlowRule
f
=
fbe
.
getTarget
();
final
Device
device
=
deviceService
.
getDevice
(
f
.
deviceId
());
final
FlowRuleProvider
frp
=
getProvider
(
device
.
providerId
());
batches
.
put
(
frp
,
fbe
);
switch
(
fbe
.
getOperator
())
{
case
ADD:
store
.
storeFlowRule
(
f
);
break
;
case
REMOVE:
store
.
deleteFlowRule
(
f
);
break
;
case
MODIFY:
default
:
log
.
error
(
"Batch operation type {} unsupported."
,
fbe
.
getOperator
());
}
perDeviceBatches
.
put
(
f
.
deviceId
(),
fbe
);
}
for
(
FlowRuleProvider
provider
:
batches
.
keySet
())
{
for
(
DeviceId
deviceId
:
perDeviceBatches
.
keySet
())
{
FlowRuleBatchOperation
b
=
new
FlowRuleBatchOperation
(
batches
.
get
(
provider
));
Future
<
CompletedBatchOperation
>
future
=
provider
.
execut
eBatch
(
b
);
new
FlowRuleBatchOperation
(
perDeviceBatches
.
get
(
deviceId
));
Future
<
CompletedBatchOperation
>
future
=
store
.
stor
eBatch
(
b
);
futures
.
add
(
future
);
}
return
new
FlowRuleBatchFuture
(
futures
,
b
atches
);
return
new
FlowRuleBatchFuture
(
futures
,
perDeviceB
atches
);
}
@Override
...
...
@@ -324,6 +306,7 @@ public class FlowRuleManager
post
(
event
);
}
}
else
{
log
.
info
(
"Removing flow rules...."
);
removeFlowRules
(
flowEntry
);
}
...
...
@@ -391,21 +374,47 @@ public class FlowRuleManager
// Store delegate to re-post events emitted from the store.
private
class
InternalStoreDelegate
implements
FlowRuleStoreDelegate
{
// TODO: Right now we only dispatch events at individual flowEntry level.
// It may be more efficient for also dispatch events as a batch.
@Override
public
void
notify
(
FlowRuleEvent
event
)
{
public
void
notify
(
FlowRuleBatchEvent
event
)
{
final
FlowRuleBatchRequest
request
=
event
.
subject
();
switch
(
event
.
type
())
{
case
RULE_ADD_REQUESTED:
applyFlowRulesToProviders
(
event
.
subject
());
break
;
case
RULE_REMOVE_REQUESTED:
removeFlowRulesFromProviders
(
event
.
subject
());
break
;
case
BATCH_OPERATION_REQUESTED:
for
(
FlowEntry
entry
:
request
.
toAdd
())
{
eventDispatcher
.
post
(
new
FlowRuleEvent
(
FlowRuleEvent
.
Type
.
RULE_ADD_REQUESTED
,
entry
));
}
for
(
FlowEntry
entry
:
request
.
toRemove
())
{
eventDispatcher
.
post
(
new
FlowRuleEvent
(
FlowRuleEvent
.
Type
.
RULE_REMOVE_REQUESTED
,
entry
));
}
// FIXME: what about op.equals(FlowRuleOperation.MODIFY) ?
case
RULE_ADDED:
case
RULE_REMOVED:
case
RULE_UPDATED:
// only dispatch events related to switch
eventDispatcher
.
post
(
event
);
FlowRuleBatchOperation
batchOperation
=
request
.
asBatchOperation
();
FlowRuleProvider
flowRuleProvider
=
getProvider
(
batchOperation
.
getOperations
().
get
(
0
).
getTarget
().
deviceId
());
final
ListenableFuture
<
CompletedBatchOperation
>
result
=
flowRuleProvider
.
executeBatch
(
batchOperation
);
result
.
addListener
(
new
Runnable
()
{
@Override
public
void
run
()
{
store
.
batchOperationComplete
(
FlowRuleBatchEvent
.
create
(
request
,
Futures
.
getUnchecked
(
result
)));
}
},
Executors
.
newCachedThreadPool
());
break
;
case
BATCH_OPERATION_COMPLETED:
Set
<
FlowEntry
>
failedItems
=
event
.
result
().
failedItems
();
for
(
FlowEntry
entry
:
request
.
toAdd
())
{
if
(!
failedItems
.
contains
(
entry
))
{
eventDispatcher
.
post
(
new
FlowRuleEvent
(
FlowRuleEvent
.
Type
.
RULE_ADDED
,
entry
));
}
}
for
(
FlowEntry
entry
:
request
.
toRemove
())
{
if
(!
failedItems
.
contains
(
entry
))
{
eventDispatcher
.
post
(
new
FlowRuleEvent
(
FlowRuleEvent
.
Type
.
RULE_REMOVED
,
entry
));
}
}
break
;
default
:
break
;
...
...
@@ -413,18 +422,15 @@ public class FlowRuleManager
}
}
private
class
FlowRuleBatchFuture
implements
Future
<
CompletedBatchOperation
>
{
private
class
FlowRuleBatchFuture
implements
Future
<
CompletedBatchOperation
>
{
private
final
List
<
Future
<
CompletedBatchOperation
>>
futures
;
private
final
Multimap
<
FlowRuleProvider
,
FlowRuleBatchEntry
>
batches
;
private
final
Multimap
<
DeviceId
,
FlowRuleBatchEntry
>
batches
;
private
final
AtomicReference
<
BatchState
>
state
;
private
CompletedBatchOperation
overall
;
public
FlowRuleBatchFuture
(
List
<
Future
<
CompletedBatchOperation
>>
futures
,
Multimap
<
FlowRuleProvider
,
FlowRuleBatchEntry
>
batches
)
{
Multimap
<
DeviceId
,
FlowRuleBatchEntry
>
batches
)
{
this
.
futures
=
futures
;
this
.
batches
=
batches
;
state
=
new
AtomicReference
<
FlowRuleManager
.
BatchState
>();
...
...
@@ -466,7 +472,7 @@ public class FlowRuleManager
}
boolean
success
=
true
;
List
<
FlowEntry
>
failed
=
Lists
.
newLinkedLis
t
();
Set
<
FlowEntry
>
failed
=
Sets
.
newHashSe
t
();
CompletedBatchOperation
completed
;
for
(
Future
<
CompletedBatchOperation
>
future
:
futures
)
{
completed
=
future
.
get
();
...
...
@@ -486,7 +492,7 @@ public class FlowRuleManager
return
overall
;
}
boolean
success
=
true
;
List
<
FlowEntry
>
failed
=
Lists
.
newLinkedLis
t
();
Set
<
FlowEntry
>
failed
=
Sets
.
newHashSe
t
();
CompletedBatchOperation
completed
;
long
start
=
System
.
nanoTime
();
long
end
=
start
+
unit
.
toNanos
(
timeout
);
...
...
@@ -500,7 +506,7 @@ public class FlowRuleManager
return
finalizeBatchOperation
(
success
,
failed
);
}
private
boolean
validateBatchOperation
(
Lis
t
<
FlowEntry
>
failed
,
private
boolean
validateBatchOperation
(
Se
t
<
FlowEntry
>
failed
,
CompletedBatchOperation
completed
)
{
if
(
isCancelled
())
{
...
...
@@ -522,7 +528,7 @@ public class FlowRuleManager
}
private
CompletedBatchOperation
finalizeBatchOperation
(
boolean
success
,
Lis
t
<
FlowEntry
>
failed
)
{
Se
t
<
FlowEntry
>
failed
)
{
synchronized
(
this
)
{
if
(!
state
.
compareAndSet
(
BatchState
.
STARTED
,
BatchState
.
FINISHED
))
{
if
(
state
.
get
()
==
BatchState
.
FINISHED
)
{
...
...
@@ -545,11 +551,6 @@ public class FlowRuleManager
store
.
storeFlowRule
(
fbe
.
getTarget
());
}
}
}
}
}
...
...
core/net/src/main/java/org/onlab/onos/net/link/impl/LinkManager.java
View file @
922760b
...
...
@@ -197,14 +197,7 @@ public class LinkManager
checkNotNull
(
linkDescription
,
LINK_DESC_NULL
);
checkValidity
();
ConnectPoint
src
=
linkDescription
.
src
();
ConnectPoint
dst
=
linkDescription
.
dst
();
// if we aren't master for the device associated with the ConnectPoint
// we probably shouldn't be doing this.
// if (deviceService.getRole(dst.deviceId()) != MastershipRole.MASTER) {
// return;
// }
LinkEvent
event
=
store
.
createOrUpdateLink
(
provider
().
id
(),
linkDescription
);
if
(
event
!=
null
)
{
...
...
@@ -232,11 +225,7 @@ public class LinkManager
public
void
linksVanished
(
ConnectPoint
connectPoint
)
{
checkNotNull
(
connectPoint
,
"Connect point cannot be null"
);
checkValidity
();
// if we aren't master for the device associated with the ConnectPoint
// we probably shouldn't be doing this.
if
(
deviceService
.
getRole
(
connectPoint
.
deviceId
())
!=
MastershipRole
.
MASTER
)
{
return
;
}
log
.
info
(
"Links for connection point {} vanished"
,
connectPoint
);
// FIXME: This will remove links registered by other providers
removeLinks
(
getLinks
(
connectPoint
));
...
...
@@ -246,11 +235,7 @@ public class LinkManager
public
void
linksVanished
(
DeviceId
deviceId
)
{
checkNotNull
(
deviceId
,
DEVICE_ID_NULL
);
checkValidity
();
// if we aren't master for the device associated with the ConnectPoint
// we probably shouldn't be doing this.
if
(
deviceService
.
getRole
(
deviceId
)
!=
MastershipRole
.
MASTER
)
{
return
;
}
log
.
info
(
"Links for device {} vanished"
,
deviceId
);
removeLinks
(
getDeviceLinks
(
deviceId
));
}
...
...
core/net/src/main/java/org/onlab/onos/net/statistic/impl/StatisticManager.java
View file @
922760b
...
...
@@ -20,7 +20,6 @@ import org.onlab.onos.net.statistic.Load;
import
org.onlab.onos.net.statistic.StatisticService
;
import
org.onlab.onos.net.statistic.StatisticStore
;
import
org.slf4j.Logger
;
import
java.util.Set
;
import
static
org
.
slf4j
.
LoggerFactory
.
getLogger
;
...
...
@@ -68,19 +67,54 @@ public class StatisticManager implements StatisticService {
@Override
public
Link
max
(
Path
path
)
{
if
(
path
.
links
().
isEmpty
())
{
return
null
;
}
Load
maxLoad
=
new
DefaultLoad
();
Link
maxLink
=
null
;
for
(
Link
link
:
path
.
links
())
{
Load
load
=
loadInternal
(
link
.
src
());
if
(
load
.
rate
()
>
maxLoad
.
rate
())
{
maxLoad
=
load
;
maxLink
=
link
;
}
}
return
maxLink
;
}
@Override
public
Link
min
(
Path
path
)
{
if
(
path
.
links
().
isEmpty
())
{
return
null
;
}
Load
minLoad
=
new
DefaultLoad
();
Link
minLink
=
null
;
for
(
Link
link
:
path
.
links
())
{
Load
load
=
loadInternal
(
link
.
src
());
if
(
load
.
rate
()
<
minLoad
.
rate
())
{
minLoad
=
load
;
minLink
=
link
;
}
}
return
minLink
;
}
@Override
public
FlowRule
highestHitter
(
ConnectPoint
connectPoint
)
{
Set
<
FlowEntry
>
hitters
=
statisticStore
.
getCurrentStatistic
(
connectPoint
);
if
(
hitters
.
isEmpty
())
{
return
null
;
}
FlowEntry
max
=
hitters
.
iterator
().
next
();
for
(
FlowEntry
entry
:
hitters
)
{
if
(
entry
.
bytes
()
>
max
.
bytes
())
{
max
=
entry
;
}
}
return
max
;
}
private
Load
loadInternal
(
ConnectPoint
connectPoint
)
{
Set
<
FlowEntry
>
current
;
Set
<
FlowEntry
>
previous
;
...
...
@@ -123,16 +157,12 @@ public class StatisticManager implements StatisticService {
case
RULE_UPDATED:
if
(
rule
instanceof
FlowEntry
)
{
statisticStore
.
addOrUpdateStatistic
((
FlowEntry
)
rule
);
}
else
{
log
.
warn
(
"IT AIN'T A FLOWENTRY"
);
}
break
;
case
RULE_ADD_REQUESTED:
log
.
info
(
"Preparing for stats"
);
statisticStore
.
prepareForStatistics
(
rule
);
break
;
case
RULE_REMOVE_REQUESTED:
log
.
info
(
"Removing stats"
);
statisticStore
.
removeFromStatistics
(
rule
);
break
;
case
RULE_REMOVED:
...
...
core/net/src/test/java/org/onlab/onos/net/flow/impl/FlowRuleManagerTest.java
View file @
922760b
package
org
.
onlab
.
onos
.
net
.
flow
.
impl
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
junit
.
Assert
.
assertFalse
;
import
static
org
.
junit
.
Assert
.
assertNotNull
;
import
static
org
.
junit
.
Assert
.
assertTrue
;
import
static
org
.
junit
.
Assert
.
fail
;
import
static
org
.
onlab
.
onos
.
net
.
flow
.
FlowRuleEvent
.
Type
.
RULE_ADDED
;
import
static
org
.
onlab
.
onos
.
net
.
flow
.
FlowRuleEvent
.
Type
.
RULE_REMOVED
;
import
static
org
.
onlab
.
onos
.
net
.
flow
.
FlowRuleEvent
.
Type
.
RULE_UPDATED
;
import
static
org
.
onlab
.
onos
.
net
.
flow
.
FlowRuleEvent
.
Type
.*;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.HashMap
;
...
...
@@ -12,6 +19,7 @@ import java.util.List;
import
java.util.Map
;
import
java.util.Set
;
import
java.util.concurrent.ExecutionException
;
import
java.util.concurrent.Executor
;
import
java.util.concurrent.Future
;
import
java.util.concurrent.TimeUnit
;
import
java.util.concurrent.TimeoutException
;
...
...
@@ -59,16 +67,7 @@ import com.google.common.collect.ImmutableList;
import
com.google.common.collect.ImmutableMap
;
import
com.google.common.collect.Lists
;
import
com.google.common.collect.Sets
;
import
static
java
.
util
.
Collections
.
EMPTY_LIST
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
junit
.
Assert
.
assertFalse
;
import
static
org
.
junit
.
Assert
.
assertNotNull
;
import
static
org
.
junit
.
Assert
.
assertTrue
;
import
static
org
.
junit
.
Assert
.
fail
;
import
static
org
.
onlab
.
onos
.
net
.
flow
.
FlowRuleEvent
.
Type
.
RULE_ADDED
;
import
static
org
.
onlab
.
onos
.
net
.
flow
.
FlowRuleEvent
.
Type
.
RULE_REMOVED
;
import
static
org
.
onlab
.
onos
.
net
.
flow
.
FlowRuleEvent
.
Type
.
RULE_UPDATED
;
import
com.google.common.util.concurrent.ListenableFuture
;
/**
* Test codifying the flow rule service & flow rule provider service contracts.
...
...
@@ -182,7 +181,6 @@ public class FlowRuleManagerTest {
// TODO: If preserving iteration order is a requirement, redo FlowRuleStore.
//backing store is sensitive to the order of additions/removals
@SuppressWarnings
(
"unchecked"
)
private
boolean
validateState
(
Map
<
FlowRule
,
FlowEntryState
>
expected
)
{
Map
<
FlowRule
,
FlowEntryState
>
expectedToCheck
=
new
HashMap
<>(
expected
);
Iterable
<
FlowEntry
>
rules
=
service
.
getFlowEntries
(
DID
);
...
...
@@ -526,13 +524,13 @@ public class FlowRuleManagerTest {
}
@Override
public
Future
<
CompletedBatchOperation
>
executeBatch
(
public
Listenable
Future
<
CompletedBatchOperation
>
executeBatch
(
BatchOperation
<
FlowRuleBatchEntry
>
batch
)
{
return
new
TestInstallationFuture
();
}
private
class
TestInstallationFuture
implements
Future
<
CompletedBatchOperation
>
{
implements
Listenable
Future
<
CompletedBatchOperation
>
{
@Override
public
boolean
cancel
(
boolean
mayInterruptIfRunning
)
{
...
...
@@ -550,10 +548,9 @@ public class FlowRuleManagerTest {
}
@Override
@SuppressWarnings
(
"unchecked"
)
public
CompletedBatchOperation
get
()
throws
InterruptedException
,
ExecutionException
{
return
new
CompletedBatchOperation
(
true
,
EMPTY_LIST
);
return
new
CompletedBatchOperation
(
true
,
Collections
.<
FlowEntry
>
emptySet
()
);
}
@Override
...
...
@@ -562,6 +559,11 @@ public class FlowRuleManagerTest {
ExecutionException
,
TimeoutException
{
return
null
;
}
@Override
public
void
addListener
(
Runnable
task
,
Executor
executor
)
{
// TODO: add stuff.
}
}
}
...
...
core/store/dist/src/main/java/org/onlab/onos/store/flow/impl/DistributedFlowRuleStore.java
View file @
922760b
...
...
@@ -5,10 +5,14 @@ import static org.slf4j.LoggerFactory.getLogger;
import
static
org
.
onlab
.
onos
.
store
.
flow
.
impl
.
FlowStoreMessageSubjects
.*;
import
java.io.IOException
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.Collection
;
import
java.util.Collections
;
import
java.util.concurrent.Future
;
import
java.util.concurrent.TimeUnit
;
import
java.util.concurrent.TimeoutException
;
import
java.util.List
;
import
org.apache.felix.scr.annotations.Activate
;
import
org.apache.felix.scr.annotations.Component
;
...
...
@@ -19,11 +23,17 @@ import org.apache.felix.scr.annotations.Service;
import
org.onlab.onos.ApplicationId
;
import
org.onlab.onos.cluster.ClusterService
;
import
org.onlab.onos.net.DeviceId
;
import
org.onlab.onos.net.flow.CompletedBatchOperation
;
import
org.onlab.onos.net.flow.DefaultFlowEntry
;
import
org.onlab.onos.net.flow.FlowEntry
;
import
org.onlab.onos.net.flow.FlowEntry.FlowEntryState
;
import
org.onlab.onos.net.flow.FlowRule
;
import
org.onlab.onos.net.flow.FlowRuleBatchEntry
;
import
org.onlab.onos.net.flow.FlowRuleBatchEvent
;
import
org.onlab.onos.net.flow.FlowRuleBatchOperation
;
import
org.onlab.onos.net.flow.FlowRuleBatchRequest
;
import
org.onlab.onos.net.flow.FlowRuleEvent
;
import
org.onlab.onos.net.flow.FlowRuleBatchEntry.FlowRuleOperation
;
import
org.onlab.onos.net.flow.FlowRuleEvent.Type
;
import
org.onlab.onos.net.flow.FlowRuleStore
;
import
org.onlab.onos.net.flow.FlowRuleStoreDelegate
;
...
...
@@ -43,6 +53,7 @@ import org.slf4j.Logger;
import
com.google.common.collect.ArrayListMultimap
;
import
com.google.common.collect.ImmutableSet
;
import
com.google.common.collect.Multimap
;
import
com.google.common.util.concurrent.Futures
;
/**
* Manages inventory of flow rules using a distributed state management protocol.
...
...
@@ -50,7 +61,7 @@ import com.google.common.collect.Multimap;
@Component
(
immediate
=
true
)
@Service
public
class
DistributedFlowRuleStore
extends
AbstractStore
<
FlowRuleEvent
,
FlowRuleStoreDelegate
>
extends
AbstractStore
<
FlowRule
Batch
Event
,
FlowRuleStoreDelegate
>
implements
FlowRuleStore
{
private
final
Logger
log
=
getLogger
(
getClass
());
...
...
@@ -92,7 +103,7 @@ public class DistributedFlowRuleStore
public
void
handle
(
ClusterMessage
message
)
{
FlowRule
rule
=
SERIALIZER
.
decode
(
message
.
payload
());
log
.
info
(
"received add request for {}"
,
rule
);
storeFlow
EntryInternal
(
rule
);
storeFlow
Rule
(
rule
);
// FIXME what to respond.
try
{
message
.
respond
(
SERIALIZER
.
encode
(
"ACK"
));
...
...
@@ -108,7 +119,7 @@ public class DistributedFlowRuleStore
public
void
handle
(
ClusterMessage
message
)
{
FlowRule
rule
=
SERIALIZER
.
decode
(
message
.
payload
());
log
.
info
(
"received delete request for {}"
,
rule
);
deleteFlowRule
Internal
(
rule
);
deleteFlowRule
(
rule
);
// FIXME what to respond.
try
{
message
.
respond
(
SERIALIZER
.
encode
(
"ACK"
));
...
...
@@ -118,6 +129,22 @@ public class DistributedFlowRuleStore
}
});
clusterCommunicator
.
addSubscriber
(
GET_FLOW_ENTRY
,
new
ClusterMessageHandler
()
{
@Override
public
void
handle
(
ClusterMessage
message
)
{
FlowRule
rule
=
SERIALIZER
.
decode
(
message
.
payload
());
log
.
info
(
"received get flow entry request for {}"
,
rule
);
FlowEntry
flowEntry
=
getFlowEntryInternal
(
rule
);
try
{
message
.
respond
(
SERIALIZER
.
encode
(
flowEntry
));
}
catch
(
IOException
e
)
{
log
.
error
(
"Failed to respond back"
,
e
);
}
}
});
log
.
info
(
"Started"
);
}
...
...
@@ -127,6 +154,9 @@ public class DistributedFlowRuleStore
}
// TODO: This is not a efficient operation on a distributed sharded
// flow store. We need to revisit the need for this operation or at least
// make it device specific.
@Override
public
int
getFlowRuleCount
()
{
return
flowEntries
.
size
();
...
...
@@ -134,9 +164,28 @@ public class DistributedFlowRuleStore
@Override
public
synchronized
FlowEntry
getFlowEntry
(
FlowRule
rule
)
{
ReplicaInfo
replicaInfo
=
replicaInfoManager
.
getReplicaInfoFor
(
rule
.
deviceId
());
if
(
replicaInfo
.
master
().
get
().
equals
(
clusterService
.
getLocalNode
().
id
()))
{
return
getFlowEntryInternal
(
rule
);
}
log
.
info
(
"Forwarding getFlowEntry to {}, which is the primary (master) for device {}"
,
replicaInfo
.
master
().
orNull
(),
rule
.
deviceId
());
ClusterMessage
message
=
new
ClusterMessage
(
clusterService
.
getLocalNode
().
id
(),
FlowStoreMessageSubjects
.
GET_FLOW_ENTRY
,
SERIALIZER
.
encode
(
rule
));
try
{
ClusterMessageResponse
response
=
clusterCommunicator
.
sendAndReceive
(
message
,
replicaInfo
.
master
().
get
());
return
SERIALIZER
.
decode
(
response
.
get
(
FLOW_RULE_STORE_TIMEOUT_MILLIS
,
TimeUnit
.
MILLISECONDS
));
}
catch
(
IOException
|
TimeoutException
e
)
{
// FIXME: throw a FlowStoreException
throw
new
RuntimeException
(
e
);
}
}
private
synchronized
StoredFlowEntry
getFlowEntryInternal
(
FlowRule
rule
)
{
for
(
StoredFlowEntry
f
:
flowEntries
.
get
(
rule
.
deviceId
()))
{
if
(
f
.
equals
(
rule
))
{
...
...
@@ -165,19 +214,30 @@ public class DistributedFlowRuleStore
}
@Override
public
boolean
storeFlowRule
(
FlowRule
rule
)
{
ReplicaInfo
replicaInfo
=
replicaInfoManager
.
getReplicaInfoFor
(
rule
.
deviceId
());
public
void
storeFlowRule
(
FlowRule
rule
)
{
storeBatch
(
new
FlowRuleBatchOperation
(
Arrays
.
asList
(
new
FlowRuleBatchEntry
(
FlowRuleOperation
.
ADD
,
rule
))));
}
public
Future
<
CompletedBatchOperation
>
storeBatch
(
FlowRuleBatchOperation
operation
)
{
if
(
operation
.
getOperations
().
isEmpty
())
{
return
Futures
.
immediateFuture
(
new
CompletedBatchOperation
(
true
,
Collections
.<
FlowEntry
>
emptySet
()));
}
DeviceId
deviceId
=
operation
.
getOperations
().
get
(
0
).
getTarget
().
deviceId
();
ReplicaInfo
replicaInfo
=
replicaInfoManager
.
getReplicaInfoFor
(
deviceId
);
if
(
replicaInfo
.
master
().
get
().
equals
(
clusterService
.
getLocalNode
().
id
()))
{
return
store
FlowEntryInternal
(
rule
);
return
store
BatchInternal
(
operation
);
}
log
.
info
(
"Forwarding store
FlowRule
to {}, which is the primary (master) for device {}"
,
replicaInfo
.
master
().
orNull
(),
rule
.
deviceId
()
);
log
.
info
(
"Forwarding store
Batch
to {}, which is the primary (master) for device {}"
,
replicaInfo
.
master
().
orNull
(),
deviceId
);
ClusterMessage
message
=
new
ClusterMessage
(
clusterService
.
getLocalNode
().
id
(),
FlowStoreMessageSubjects
.
STORE_FLOW_RULE
,
SERIALIZER
.
encode
(
rule
));
SERIALIZER
.
encode
(
operation
));
try
{
ClusterMessageResponse
response
=
clusterCommunicator
.
sendAndReceive
(
message
,
replicaInfo
.
master
().
get
());
...
...
@@ -186,58 +246,44 @@ public class DistributedFlowRuleStore
// FIXME: throw a FlowStoreException
throw
new
RuntimeException
(
e
);
}
return
false
;
return
null
;
}
private
synchronized
boolean
storeFlowEntryInternal
(
FlowRule
flowRule
)
{
private
Future
<
CompletedBatchOperation
>
storeBatchInternal
(
FlowRuleBatchOperation
operation
)
{
List
<
FlowEntry
>
toRemove
=
new
ArrayList
<>();
List
<
FlowEntry
>
toAdd
=
new
ArrayList
<>();
// TODO: backup changes to hazelcast map
for
(
FlowRuleBatchEntry
batchEntry
:
operation
.
getOperations
())
{
FlowRule
flowRule
=
batchEntry
.
getTarget
();
FlowRuleOperation
op
=
batchEntry
.
getOperator
();
if
(
op
.
equals
(
FlowRuleOperation
.
REMOVE
))
{
StoredFlowEntry
entry
=
getFlowEntryInternal
(
flowRule
);
if
(
entry
!=
null
)
{
entry
.
setState
(
FlowEntryState
.
PENDING_REMOVE
);
}
toRemove
.
add
(
entry
);
}
else
if
(
op
.
equals
(
FlowRuleOperation
.
ADD
))
{
StoredFlowEntry
flowEntry
=
new
DefaultFlowEntry
(
flowRule
);
DeviceId
deviceId
=
flowRule
.
deviceId
();
// write to local copy.
if
(!
flowEntries
.
containsEntry
(
deviceId
,
flowEntry
))
{
flowEntries
.
put
(
deviceId
,
flowEntry
);
flowEntriesById
.
put
(
flowRule
.
appId
(),
flowEntry
);
notifyDelegate
(
new
FlowRuleEvent
(
Type
.
RULE_ADD_REQUESTED
,
flowRule
));
return
true
;
toAdd
.
add
(
flowEntry
);
}
// write to backup.
// TODO: write to a hazelcast map.
return
false
;
}
@Override
public
synchronized
boolean
deleteFlowRule
(
FlowRule
rule
)
{
ReplicaInfo
replicaInfo
=
replicaInfoManager
.
getReplicaInfoFor
(
rule
.
deviceId
());
if
(
replicaInfo
.
master
().
get
().
equals
(
clusterService
.
getLocalNode
().
id
()))
{
return
deleteFlowRuleInternal
(
rule
);
}
ClusterMessage
message
=
new
ClusterMessage
(
clusterService
.
getLocalNode
().
id
(),
FlowStoreMessageSubjects
.
DELETE_FLOW_RULE
,
SERIALIZER
.
encode
(
rule
));
try
{
ClusterMessageResponse
response
=
clusterCommunicator
.
sendAndReceive
(
message
,
replicaInfo
.
master
().
get
());
response
.
get
(
FLOW_RULE_STORE_TIMEOUT_MILLIS
,
TimeUnit
.
MILLISECONDS
);
}
catch
(
IOException
|
TimeoutException
e
)
{
// FIXME: throw a FlowStoreException
throw
new
RuntimeException
(
e
);
}
return
false
;
if
(
toAdd
.
isEmpty
()
&&
toRemove
.
isEmpty
())
{
return
Futures
.
immediateFuture
(
new
CompletedBatchOperation
(
true
,
Collections
.<
FlowEntry
>
emptySet
()));
}
private
synchronized
boolean
deleteFlowRuleInternal
(
FlowRule
flowRule
)
{
StoredFlowEntry
entry
=
getFlowEntryInternal
(
flowRule
);
if
(
entry
==
null
)
{
return
false
;
notifyDelegate
(
FlowRuleBatchEvent
.
create
(
new
FlowRuleBatchRequest
(
toAdd
,
toRemove
)));
// TODO: imlpement this.
return
Futures
.
immediateFailedFuture
(
new
RuntimeException
(
"Implement this."
));
}
entry
.
setState
(
FlowEntryState
.
PENDING_REMOVE
);
// TODO: also update backup.
notifyDelegate
(
new
FlowRuleEvent
(
Type
.
RULE_REMOVE_REQUESTED
,
flowRule
));
return
true
;
@Override
public
void
deleteFlowRule
(
FlowRule
rule
)
{
storeBatch
(
new
FlowRuleBatchOperation
(
Arrays
.
asList
(
new
FlowRuleBatchEntry
(
FlowRuleOperation
.
REMOVE
,
rule
))));
}
@Override
...
...
@@ -315,4 +361,9 @@ public class DistributedFlowRuleStore
}
// TODO: also update backup.
}
@Override
public
void
batchOperationComplete
(
FlowRuleBatchEvent
event
)
{
notifyDelegate
(
event
);
}
}
...
...
core/store/dist/src/main/java/org/onlab/onos/store/flow/impl/FlowStoreMessageSubjects.java
View file @
922760b
...
...
@@ -12,4 +12,5 @@ public final class FlowStoreMessageSubjects {
public
static
final
MessageSubject
ADD_OR_UPDATE_FLOW_RULE
=
new
MessageSubject
(
"peer-forward-add-or-update-flow-rule"
);
public
static
final
MessageSubject
REMOVE_FLOW_RULE
=
new
MessageSubject
(
"peer-forward-remove-flow-rule"
);
public
static
final
MessageSubject
GET_FLOW_ENTRY
=
new
MessageSubject
(
"peer-forward-get-flow-entry"
);
}
...
...
core/store/dist/src/main/java/org/onlab/onos/store/host/impl/GossipHostStore.java
View file @
922760b
...
...
@@ -399,7 +399,7 @@ public class GossipHostStore
}
// Auxiliary extension to allow location to mutate.
private
class
StoredHost
extends
DefaultHost
{
private
static
final
class
StoredHost
extends
DefaultHost
{
private
Timestamped
<
HostLocation
>
location
;
/**
...
...
core/store/hz/cluster/src/main/java/org/onlab/onos/store/mastership/impl/RoleValue.java
View file @
922760b
package
org
.
onlab
.
onos
.
store
.
mastership
.
impl
;
import
java.util.Collections
;
import
java.util.
Hash
Map
;
import
java.util.
Enum
Map
;
import
java.util.LinkedList
;
import
java.util.List
;
import
java.util.Map
;
...
...
@@ -17,9 +17,9 @@ import com.google.common.base.MoreObjects.ToStringHelper;
* A structure that holds node mastership roles associated with a
* {@link DeviceId}. This structure needs to be locked through IMap.
*/
public
class
RoleValue
{
final
class
RoleValue
{
protected
Map
<
MastershipRole
,
List
<
NodeId
>>
value
=
new
HashMap
<>(
);
protected
final
Map
<
MastershipRole
,
List
<
NodeId
>>
value
=
new
EnumMap
<>(
MastershipRole
.
class
);
public
RoleValue
()
{
value
.
put
(
MastershipRole
.
MASTER
,
new
LinkedList
<
NodeId
>());
...
...
@@ -27,7 +27,8 @@ public class RoleValue {
value
.
put
(
MastershipRole
.
NONE
,
new
LinkedList
<
NodeId
>());
}
public
Map
<
MastershipRole
,
List
<
NodeId
>>
value
()
{
// exposing internals for serialization purpose only
Map
<
MastershipRole
,
List
<
NodeId
>>
value
()
{
return
Collections
.
unmodifiableMap
(
value
);
}
...
...
core/store/hz/cluster/src/main/java/org/onlab/onos/store/mastership/impl/RoleValueSerializer.java
View file @
922760b
...
...
@@ -35,10 +35,10 @@ public class RoleValueSerializer extends Serializer<RoleValue> {
@Override
public
void
write
(
Kryo
kryo
,
Output
output
,
RoleValue
type
)
{
output
.
writeInt
(
type
.
value
().
size
());
final
Map
<
MastershipRole
,
List
<
NodeId
>>
map
=
type
.
value
();
output
.
writeInt
(
map
.
size
());
for
(
Map
.
Entry
<
MastershipRole
,
List
<
NodeId
>>
el
:
type
.
value
().
entrySet
())
{
for
(
Map
.
Entry
<
MastershipRole
,
List
<
NodeId
>>
el
:
map
.
entrySet
())
{
output
.
writeInt
(
el
.
getKey
().
ordinal
());
List
<
NodeId
>
nodes
=
el
.
getValue
();
...
...
core/store/hz/common/src/main/java/org/onlab/onos/store/common/SMap.java
View file @
922760b
...
...
@@ -492,7 +492,10 @@ public class SMap<K, V> implements IMap<K, V> {
}
private
V
deserializeVal
(
byte
[]
val
)
{
return
serializer
.
decode
(
val
);
if
(
val
==
null
)
{
return
null
;
}
return
serializer
.
decode
(
val
.
clone
());
}
private
Set
<
byte
[]>
serializeKeySet
(
Set
<
K
>
keys
)
{
...
...
core/store/serializers/src/main/java/org/onlab/onos/store/serializers/KryoNamespaces.java
View file @
922760b
...
...
@@ -33,6 +33,7 @@ import org.onlab.onos.net.flow.DefaultTrafficSelector;
import
org.onlab.onos.net.flow.DefaultTrafficTreatment
;
import
org.onlab.onos.net.flow.FlowEntry
;
import
org.onlab.onos.net.flow.FlowId
;
import
org.onlab.onos.net.flow.StoredFlowEntry
;
import
org.onlab.onos.net.flow.criteria.Criteria
;
import
org.onlab.onos.net.flow.criteria.Criterion
;
import
org.onlab.onos.net.flow.instructions.Instructions
;
...
...
@@ -97,6 +98,8 @@ public final class KryoNamespaces {
HostId
.
class
,
HostDescription
.
class
,
DefaultHostDescription
.
class
,
DefaultFlowEntry
.
class
,
StoredFlowEntry
.
class
,
DefaultFlowRule
.
class
,
DefaultFlowEntry
.
class
,
FlowEntry
.
FlowEntryState
.
class
,
...
...
core/store/trivial/src/main/java/org/onlab/onos/store/trivial/impl/SimpleFlowRuleStore.java
View file @
922760b
...
...
@@ -3,6 +3,8 @@ package org.onlab.onos.store.trivial.impl;
import
static
org
.
onlab
.
onos
.
net
.
flow
.
FlowRuleEvent
.
Type
.
RULE_REMOVED
;
import
static
org
.
slf4j
.
LoggerFactory
.
getLogger
;
import
static
org
.
apache
.
commons
.
lang3
.
concurrent
.
ConcurrentUtils
.
createIfAbsentUnchecked
;
import
java.util.Arrays
;
import
java.util.Collections
;
import
java.util.HashSet
;
import
java.util.List
;
...
...
@@ -10,6 +12,7 @@ import java.util.Set;
import
java.util.concurrent.ConcurrentHashMap
;
import
java.util.concurrent.ConcurrentMap
;
import
java.util.concurrent.CopyOnWriteArrayList
;
import
java.util.concurrent.Future
;
import
org.apache.felix.scr.annotations.Activate
;
import
org.apache.felix.scr.annotations.Component
;
...
...
@@ -17,11 +20,17 @@ import org.apache.felix.scr.annotations.Deactivate;
import
org.apache.felix.scr.annotations.Service
;
import
org.onlab.onos.ApplicationId
;
import
org.onlab.onos.net.DeviceId
;
import
org.onlab.onos.net.flow.CompletedBatchOperation
;
import
org.onlab.onos.net.flow.DefaultFlowEntry
;
import
org.onlab.onos.net.flow.FlowEntry
;
import
org.onlab.onos.net.flow.FlowEntry.FlowEntryState
;
import
org.onlab.onos.net.flow.FlowId
;
import
org.onlab.onos.net.flow.FlowRule
;
import
org.onlab.onos.net.flow.FlowRuleBatchEntry
;
import
org.onlab.onos.net.flow.FlowRuleBatchEntry.FlowRuleOperation
;
import
org.onlab.onos.net.flow.FlowRuleBatchEvent
;
import
org.onlab.onos.net.flow.FlowRuleBatchOperation
;
import
org.onlab.onos.net.flow.FlowRuleBatchRequest
;
import
org.onlab.onos.net.flow.FlowRuleEvent
;
import
org.onlab.onos.net.flow.FlowRuleEvent.Type
;
import
org.onlab.onos.net.flow.FlowRuleStore
;
...
...
@@ -33,6 +42,7 @@ import org.slf4j.Logger;
import
com.google.common.base.Function
;
import
com.google.common.collect.FluentIterable
;
import
com.google.common.util.concurrent.Futures
;
/**
* Manages inventory of flow rules using trivial in-memory implementation.
...
...
@@ -40,7 +50,7 @@ import com.google.common.collect.FluentIterable;
@Component
(
immediate
=
true
)
@Service
public
class
SimpleFlowRuleStore
extends
AbstractStore
<
FlowRuleEvent
,
FlowRuleStoreDelegate
>
extends
AbstractStore
<
FlowRule
Batch
Event
,
FlowRuleStoreDelegate
>
implements
FlowRuleStore
{
private
final
Logger
log
=
getLogger
(
getClass
());
...
...
@@ -148,12 +158,11 @@ public class SimpleFlowRuleStore
}
@Override
public
boolean
storeFlowRule
(
FlowRule
rule
)
{
final
boolean
added
=
storeFlowRuleInternal
(
rule
);
return
added
;
public
void
storeFlowRule
(
FlowRule
rule
)
{
storeFlowRuleInternal
(
rule
);
}
private
boolean
storeFlowRuleInternal
(
FlowRule
rule
)
{
private
void
storeFlowRuleInternal
(
FlowRule
rule
)
{
StoredFlowEntry
f
=
new
DefaultFlowEntry
(
rule
);
final
DeviceId
did
=
f
.
deviceId
();
final
FlowId
fid
=
f
.
id
();
...
...
@@ -162,19 +171,20 @@ public class SimpleFlowRuleStore
for
(
StoredFlowEntry
fe
:
existing
)
{
if
(
fe
.
equals
(
rule
))
{
// was already there? ignore
return
false
;
return
;
}
}
// new flow rule added
existing
.
add
(
f
);
// TODO: Should we notify only if it's "remote" event?
//notifyDelegate(new FlowRuleEvent(Type.RULE_ADD_REQUESTED, rule));
return
true
;
notifyDelegate
(
FlowRuleBatchEvent
.
create
(
new
FlowRuleBatchRequest
(
Arrays
.<
FlowEntry
>
asList
(
f
),
Collections
.<
FlowEntry
>
emptyList
())));
}
}
@Override
public
boolean
deleteFlowRule
(
FlowRule
rule
)
{
public
void
deleteFlowRule
(
FlowRule
rule
)
{
List
<
StoredFlowEntry
>
entries
=
getFlowEntries
(
rule
.
deviceId
(),
rule
.
id
());
...
...
@@ -184,14 +194,17 @@ public class SimpleFlowRuleStore
synchronized
(
entry
)
{
entry
.
setState
(
FlowEntryState
.
PENDING_REMOVE
);
// TODO: Should we notify only if it's "remote" event?
//notifyDelegate(new FlowRuleEvent(Type.RULE_REMOVE_REQUESTED, rule));
return
true
;
notifyDelegate
(
FlowRuleBatchEvent
.
create
(
new
FlowRuleBatchRequest
(
Collections
.<
FlowEntry
>
emptyList
(),
Arrays
.<
FlowEntry
>
asList
(
entry
))));
}
}
}
}
//log.warn("Cannot find rule {}", rule);
return
false
;
}
@Override
...
...
@@ -237,4 +250,24 @@ public class SimpleFlowRuleStore
}
return
null
;
}
@Override
public
Future
<
CompletedBatchOperation
>
storeBatch
(
FlowRuleBatchOperation
batchOperation
)
{
for
(
FlowRuleBatchEntry
entry
:
batchOperation
.
getOperations
())
{
if
(
entry
.
getOperator
().
equals
(
FlowRuleOperation
.
ADD
))
{
storeFlowRule
(
entry
.
getTarget
());
}
else
if
(
entry
.
getOperator
().
equals
(
FlowRuleOperation
.
REMOVE
))
{
deleteFlowRule
(
entry
.
getTarget
());
}
else
{
throw
new
UnsupportedOperationException
(
"Unsupported operation type"
);
}
}
return
Futures
.
immediateFuture
(
new
CompletedBatchOperation
(
true
,
Collections
.<
FlowEntry
>
emptySet
()));
}
@Override
public
void
batchOperationComplete
(
FlowRuleBatchEvent
event
)
{
notifyDelegate
(
event
);
}
}
...
...
core/store/trivial/src/main/java/org/onlab/onos/store/trivial/impl/SimpleHostStore.java
View file @
922760b
...
...
@@ -269,7 +269,7 @@ public class SimpleHostStore
}
// Auxiliary extension to allow location to mutate.
private
class
StoredHost
extends
DefaultHost
{
private
static
final
class
StoredHost
extends
DefaultHost
{
private
HostLocation
location
;
/**
...
...
openflow/ctl/src/main/java/org/onlab/onos/openflow/controller/impl/OFChannelHandler.java
View file @
922760b
...
...
@@ -41,7 +41,6 @@ import org.projectfloodlight.openflow.protocol.OFHello;
import
org.projectfloodlight.openflow.protocol.OFHelloElem
;
import
org.projectfloodlight.openflow.protocol.OFMessage
;
import
org.projectfloodlight.openflow.protocol.OFPacketIn
;
import
org.projectfloodlight.openflow.protocol.OFPacketOut
;
import
org.projectfloodlight.openflow.protocol.OFPortDescStatsReply
;
import
org.projectfloodlight.openflow.protocol.OFPortDescStatsRequest
;
import
org.projectfloodlight.openflow.protocol.OFPortStatus
;
...
...
@@ -661,10 +660,9 @@ class OFChannelHandler extends IdleStateAwareChannelHandler {
* However, we could be more forgiving
* @param h the channel handler that received the message
* @param m the message
* @throws SwitchStateException
* @throws SwitchStateExeption we always through the execption
* @throws SwitchStateException we always throw the exception
*/
// needs to be protected because enum members are ac
ut
ally subclasses
// needs to be protected because enum members are ac
tu
ally subclasses
protected
void
illegalMessageReceived
(
OFChannelHandler
h
,
OFMessage
m
)
throws
SwitchStateException
{
String
msg
=
getSwitchStateMessage
(
h
,
m
,
...
...
@@ -1025,7 +1023,9 @@ class OFChannelHandler extends IdleStateAwareChannelHandler {
// all state for the original switch (with the same dpid),
// which we obviously don't want.
log
.
info
(
"{}:removal called"
,
getSwitchInfoString
());
if
(
sw
!=
null
)
{
sw
.
removeConnectedSwitch
();
}
}
else
{
// A duplicate was disconnected on this ChannelHandler,
// this is the same switch reconnecting, but the original state was
...
...
openflow/ctl/src/main/java/org/onlab/onos/openflow/drivers/impl/OFSwitchImplCPqD13.java
View file @
922760b
...
...
@@ -1188,7 +1188,8 @@ public class OFSwitchImplCPqD13 extends AbstractOpenFlowSwitch {
.
setHardTimeout
(
0
)
.
setXid
(
getNextTransactionId
())
.
build
();
sendMsg
(
tableMissEntry
);
write
(
tableMissEntry
);
}
private
void
sendBarrier
(
boolean
finalBarrier
)
{
...
...
@@ -1200,7 +1201,8 @@ public class OFSwitchImplCPqD13 extends AbstractOpenFlowSwitch {
.
buildBarrierRequest
()
.
setXid
(
xid
)
.
build
();
sendMsg
(
br
);
write
(
br
);
}
@Override
...
...
@@ -1210,7 +1212,7 @@ public class OFSwitchImplCPqD13 extends AbstractOpenFlowSwitch {
@Override
public
void
write
(
OFMessage
msg
)
{
this
.
channel
.
write
(
msg
);
this
.
channel
.
write
(
Collections
.
singletonList
(
msg
)
);
}
...
...
providers/lldp/src/main/java/org/onlab/onos/provider/lldp/impl/LinkDiscovery.java
View file @
922760b
...
...
@@ -217,7 +217,7 @@ public class LinkDiscovery implements TimerTask {
final
PortNumber
srcPort
=
PortNumber
.
portNumber
(
onoslldp
.
getPort
());
final
DeviceId
srcDeviceId
=
DeviceId
.
deviceId
(
onoslldp
.
getDeviceString
());
final
DeviceId
dstDeviceId
=
context
.
inPacket
().
receivedFrom
().
deviceId
();
this
.
ackProbe
(
src
Port
.
toLong
());
this
.
ackProbe
(
dst
Port
.
toLong
());
ConnectPoint
src
=
new
ConnectPoint
(
srcDeviceId
,
srcPort
);
ConnectPoint
dst
=
new
ConnectPoint
(
dstDeviceId
,
dstPort
);
...
...
@@ -245,7 +245,7 @@ public class LinkDiscovery implements TimerTask {
*/
@Override
public
void
run
(
final
Timeout
t
)
{
this
.
log
.
debug
(
"sending probes"
);
this
.
log
.
trace
(
"sending probes"
);
synchronized
(
this
)
{
final
Iterator
<
Long
>
fastIterator
=
this
.
fastPorts
.
iterator
();
Long
portNumber
;
...
...
@@ -256,7 +256,7 @@ public class LinkDiscovery implements TimerTask {
.
getAndIncrement
();
if
(
probeCount
<
LinkDiscovery
.
MAX_PROBE_COUNT
)
{
this
.
log
.
debug
(
"sending fast probe to port"
);
this
.
log
.
trace
(
"sending fast probe to port"
);
sendProbes
(
portNumber
);
}
else
{
// Update fast and slow ports
...
...
@@ -278,7 +278,7 @@ public class LinkDiscovery implements TimerTask {
Iterator
<
Long
>
slowIterator
=
this
.
slowPorts
.
iterator
();
while
(
slowIterator
.
hasNext
())
{
portNumber
=
slowIterator
.
next
();
this
.
log
.
debug
(
"sending slow probe to port {}"
,
portNumber
);
this
.
log
.
trace
(
"sending slow probe to port {}"
,
portNumber
);
sendProbes
(
portNumber
);
...
...
providers/openflow/flow/src/main/java/org/onlab/onos/provider/of/flow/impl/OpenFlowRuleProvider.java
View file @
922760b
...
...
@@ -10,7 +10,7 @@ import java.util.Set;
import
java.util.concurrent.ConcurrentHashMap
;
import
java.util.concurrent.CountDownLatch
;
import
java.util.concurrent.ExecutionException
;
import
java.util.concurrent.
Future
;
import
java.util.concurrent.
Executor
;
import
java.util.concurrent.TimeUnit
;
import
java.util.concurrent.TimeoutException
;
import
java.util.concurrent.atomic.AtomicBoolean
;
...
...
@@ -69,9 +69,11 @@ import org.projectfloodlight.openflow.types.U32;
import
org.slf4j.Logger
;
import
com.google.common.collect.ArrayListMultimap
;
import
com.google.common.collect.Lists
;
import
com.google.common.collect.Maps
;
import
com.google.common.collect.Multimap
;
import
com.google.common.collect.Sets
;
import
com.google.common.util.concurrent.ExecutionList
;
import
com.google.common.util.concurrent.ListenableFuture
;
/**
* Provider which uses an OpenFlow controller to detect network
...
...
@@ -97,6 +99,8 @@ public class OpenFlowRuleProvider extends AbstractProvider implements FlowRulePr
private
final
InternalFlowProvider
listener
=
new
InternalFlowProvider
();
// FIXME: This should be an expiring map to ensure futures that don't have
// a future eventually get garbage collected.
private
final
Map
<
Long
,
InstallationFuture
>
pendingFutures
=
new
ConcurrentHashMap
<
Long
,
InstallationFuture
>();
...
...
@@ -169,7 +173,7 @@ public class OpenFlowRuleProvider extends AbstractProvider implements FlowRulePr
}
@Override
public
Future
<
CompletedBatchOperation
>
executeBatch
(
BatchOperation
<
FlowRuleBatchEntry
>
batch
)
{
public
Listenable
Future
<
CompletedBatchOperation
>
executeBatch
(
BatchOperation
<
FlowRuleBatchEntry
>
batch
)
{
final
Set
<
Dpid
>
sws
=
Collections
.
newSetFromMap
(
new
ConcurrentHashMap
<
Dpid
,
Boolean
>());
final
Map
<
Long
,
FlowRuleBatchEntry
>
fmXids
=
new
HashMap
<
Long
,
FlowRuleBatchEntry
>();
...
...
@@ -330,18 +334,20 @@ public class OpenFlowRuleProvider extends AbstractProvider implements FlowRulePr
}
private
class
InstallationFuture
implements
Future
<
CompletedBatchOperation
>
{
private
class
InstallationFuture
implements
Listenable
Future
<
CompletedBatchOperation
>
{
private
final
Set
<
Dpid
>
sws
;
private
final
AtomicBoolean
ok
=
new
AtomicBoolean
(
true
);
private
final
Map
<
Long
,
FlowRuleBatchEntry
>
fms
;
private
final
List
<
FlowEntry
>
offendingFlowMods
=
Lists
.
newLinkedLis
t
();
private
final
Set
<
FlowEntry
>
offendingFlowMods
=
Sets
.
newHashSe
t
();
private
final
CountDownLatch
countDownLatch
;
private
Long
pendingXid
;
private
BatchState
state
;
private
final
ExecutionList
executionList
=
new
ExecutionList
();
public
InstallationFuture
(
Set
<
Dpid
>
sws
,
Map
<
Long
,
FlowRuleBatchEntry
>
fmXids
)
{
this
.
state
=
BatchState
.
STARTED
;
this
.
sws
=
sws
;
...
...
@@ -350,6 +356,7 @@ public class OpenFlowRuleProvider extends AbstractProvider implements FlowRulePr
}
public
void
fail
(
OFErrorMsg
msg
,
Dpid
dpid
)
{
ok
.
set
(
false
);
removeRequirement
(
dpid
);
FlowEntry
fe
=
null
;
...
...
@@ -422,6 +429,9 @@ public class OpenFlowRuleProvider extends AbstractProvider implements FlowRulePr
@Override
public
boolean
cancel
(
boolean
mayInterruptIfRunning
)
{
if
(
isDone
())
{
return
false
;
}
ok
.
set
(
false
);
this
.
state
=
BatchState
.
CANCELLED
;
cleanUp
();
...
...
@@ -434,7 +444,8 @@ public class OpenFlowRuleProvider extends AbstractProvider implements FlowRulePr
}
}
return
isCancelled
();
invokeCallbacks
();
return
true
;
}
@Override
...
...
@@ -444,14 +455,15 @@ public class OpenFlowRuleProvider extends AbstractProvider implements FlowRulePr
@Override
public
boolean
isDone
()
{
return
this
.
state
==
BatchState
.
FINISHED
;
return
this
.
state
==
BatchState
.
FINISHED
||
isCancelled
()
;
}
@Override
public
CompletedBatchOperation
get
()
throws
InterruptedException
,
ExecutionException
{
countDownLatch
.
await
();
this
.
state
=
BatchState
.
FINISHED
;
return
new
CompletedBatchOperation
(
ok
.
get
(),
offendingFlowMods
);
CompletedBatchOperation
result
=
new
CompletedBatchOperation
(
ok
.
get
(),
offendingFlowMods
);
return
result
;
}
@Override
...
...
@@ -460,7 +472,8 @@ public class OpenFlowRuleProvider extends AbstractProvider implements FlowRulePr
TimeoutException
{
if
(
countDownLatch
.
await
(
timeout
,
unit
))
{
this
.
state
=
BatchState
.
FINISHED
;
return
new
CompletedBatchOperation
(
ok
.
get
(),
offendingFlowMods
);
CompletedBatchOperation
result
=
new
CompletedBatchOperation
(
ok
.
get
(),
offendingFlowMods
);
return
result
;
}
throw
new
TimeoutException
();
}
...
...
@@ -478,10 +491,21 @@ public class OpenFlowRuleProvider extends AbstractProvider implements FlowRulePr
private
void
removeRequirement
(
Dpid
dpid
)
{
countDownLatch
.
countDown
();
if
(
countDownLatch
.
getCount
()
==
0
)
{
invokeCallbacks
();
}
sws
.
remove
(
dpid
);
cleanUp
();
}
@Override
public
void
addListener
(
Runnable
runnable
,
Executor
executor
)
{
executionList
.
add
(
runnable
,
executor
);
}
private
void
invokeCallbacks
()
{
executionList
.
execute
();
}
}
}
...
...
utils/misc/src/main/java/org/onlab/packet/ChassisId.java
View file @
922760b
...
...
@@ -32,7 +32,7 @@ public final class ChassisId {
* @param value the value to use.
*/
public
ChassisId
(
String
value
)
{
this
.
value
=
Long
.
valueOf
(
value
,
16
);
this
.
value
=
Long
.
parseLong
(
value
,
16
);
}
/**
...
...
utils/misc/src/main/java/org/onlab/packet/DHCP.java
View file @
922760b
...
...
@@ -379,7 +379,7 @@ public class DHCP extends BasePacket {
// 300
int
optionsLength
=
0
;
for
(
final
DHCPOption
option
:
this
.
options
)
{
if
(
option
.
getCode
()
==
0
||
option
.
getCode
()
==
255
)
{
if
(
option
.
getCode
()
==
0
||
option
.
getCode
()
==
((
byte
)
255
)
)
{
optionsLength
+=
1
;
}
else
{
optionsLength
+=
2
+
(
0xff
&
option
.
getLength
());
...
...
utils/misc/src/main/java/org/onlab/packet/IPv4.java
View file @
922760b
...
...
@@ -438,7 +438,7 @@ public class IPv4 extends BasePacket {
int
result
=
0
;
for
(
int
i
=
0
;
i
<
4
;
++
i
)
{
result
|=
Integer
.
valueOf
(
octets
[
i
])
<<
(
3
-
i
)
*
8
;
result
|=
Integer
.
parseInt
(
octets
[
i
])
<<
(
3
-
i
)
*
8
;
}
return
result
;
}
...
...
@@ -471,7 +471,7 @@ public class IPv4 extends BasePacket {
int
result
=
0
;
for
(
int
i
=
0
;
i
<
4
;
++
i
)
{
result
=
ipAddress
>>
(
3
-
i
)
*
8
&
0xff
;
sb
.
append
(
Integer
.
valueOf
(
result
).
toString
()
);
sb
.
append
(
result
);
if
(
i
!=
3
)
{
sb
.
append
(
"."
);
}
...
...
utils/misc/src/main/java/org/onlab/util/HexString.java
View file @
922760b
...
...
@@ -14,7 +14,7 @@ public final class HexString {
*/
public
static
String
toHexString
(
final
byte
[]
bytes
)
{
int
i
;
StringBuilder
ret
=
new
StringBuilder
();
StringBuilder
ret
=
new
StringBuilder
(
bytes
.
length
*
3
-
1
);
String
tmp
;
for
(
i
=
0
;
i
<
bytes
.
length
;
i
++)
{
if
(
i
>
0
)
{
...
...
@@ -31,22 +31,22 @@ public final class HexString {
public
static
String
toHexString
(
final
long
val
,
final
int
padTo
)
{
char
[]
arr
=
Long
.
toHexString
(
val
).
toCharArray
();
String
ret
=
""
;
String
Builder
ret
=
new
StringBuilder
(
padTo
*
3
-
1
)
;
// prepend the right number of leading zeros
int
i
=
0
;
for
(;
i
<
(
padTo
*
2
-
arr
.
length
);
i
++)
{
ret
+=
"0"
;
ret
.
append
(
'0'
)
;
if
((
i
%
2
)
!=
0
)
{
ret
+=
":"
;
ret
.
append
(
':'
)
;
}
}
for
(
int
j
=
0
;
j
<
arr
.
length
;
j
++)
{
ret
+=
arr
[
j
]
;
ret
.
append
(
arr
[
j
])
;
if
((((
i
+
j
)
%
2
)
!=
0
)
&&
(
j
<
(
arr
.
length
-
1
)))
{
ret
+=
":"
;
ret
.
append
(
':'
)
;
}
}
return
ret
;
return
ret
.
toString
()
;
}
public
static
String
toHexString
(
final
long
val
)
{
...
...
utils/netty/src/main/java/org/onlab/netty/NettyMessagingService.java
View file @
922760b
...
...
@@ -163,6 +163,7 @@ public class NettyMessagingService implements MessagingService {
handlers
.
putIfAbsent
(
type
,
handler
);
}
@Override
public
void
unregisterHandler
(
String
type
)
{
handlers
.
remove
(
type
);
}
...
...
@@ -242,7 +243,7 @@ public class NettyMessagingService implements MessagingService {
}
}
private
class
WriteTask
implements
Runnable
{
private
static
class
WriteTask
implements
Runnable
{
private
final
InternalMessage
message
;
private
final
Channel
channel
;
...
...
Please
register
or
login
to post a comment