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
Ray Milkey
2015-01-28 10:03:06 -0800
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
19ffea35f82041e8160e0de0c88e26278ec8b40b
19ffea35
1 parent
1dc32e64
ONOS-790 - REST APIs for paths
Change-Id: I5e08778e75c98c1156df7972af9897b52677d371
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
394 additions
and
3 deletions
web/api/src/main/java/org/onosproject/codec/impl/CodecManager.java
web/api/src/main/java/org/onosproject/codec/impl/ConnectPointCodec.java
web/api/src/main/java/org/onosproject/codec/impl/PathCodec.java
web/api/src/main/java/org/onosproject/rest/PathsWebResource.java
web/api/src/main/webapp/WEB-INF/web.xml
web/api/src/test/java/org/onosproject/rest/PathsResourceTest.java
web/api/src/main/java/org/onosproject/codec/impl/CodecManager.java
View file @
19ffea3
...
...
@@ -33,6 +33,7 @@ import org.onosproject.net.Device;
import
org.onosproject.net.Host
;
import
org.onosproject.net.HostLocation
;
import
org.onosproject.net.Link
;
import
org.onosproject.net.Path
;
import
org.onosproject.net.Port
;
import
org.onosproject.net.flow.FlowEntry
;
import
org.onosproject.net.flow.TrafficSelector
;
...
...
@@ -86,6 +87,7 @@ public class CodecManager implements CodecService {
registerCodec
(
Constraint
.
class
,
new
ConstraintCodec
());
registerCodec
(
Topology
.
class
,
new
TopologyCodec
());
registerCodec
(
TopologyCluster
.
class
,
new
TopologyClusterCodec
());
registerCodec
(
Path
.
class
,
new
PathCodec
());
log
.
info
(
"Started"
);
}
...
...
web/api/src/main/java/org/onosproject/codec/impl/ConnectPointCodec.java
View file @
19ffea3
...
...
@@ -19,6 +19,8 @@ import com.fasterxml.jackson.databind.node.ObjectNode;
import
org.onosproject.codec.CodecContext
;
import
org.onosproject.codec.JsonCodec
;
import
org.onosproject.net.ConnectPoint
;
import
org.onosproject.net.DeviceId
;
import
org.onosproject.net.HostId
;
import
static
com
.
google
.
common
.
base
.
Preconditions
.
checkNotNull
;
...
...
@@ -30,9 +32,16 @@ public class ConnectPointCodec extends JsonCodec<ConnectPoint> {
@Override
public
ObjectNode
encode
(
ConnectPoint
point
,
CodecContext
context
)
{
checkNotNull
(
point
,
"Connect point cannot be null"
);
return
context
.
mapper
().
createObjectNode
()
.
put
(
"device"
,
point
.
deviceId
().
toString
())
ObjectNode
root
=
context
.
mapper
().
createObjectNode
()
.
put
(
"port"
,
point
.
port
().
toString
());
if
(
point
.
elementId
()
instanceof
DeviceId
)
{
root
.
put
(
"device"
,
point
.
deviceId
().
toString
());
}
else
if
(
point
.
elementId
()
instanceof
HostId
)
{
root
.
put
(
"host"
,
point
.
hostId
().
toString
());
}
return
root
;
}
}
...
...
web/api/src/main/java/org/onosproject/codec/impl/PathCodec.java
0 → 100644
View file @
19ffea3
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
org
.
onosproject
.
codec
.
impl
;
import
org.onosproject.codec.CodecContext
;
import
org.onosproject.codec.JsonCodec
;
import
org.onosproject.net.Link
;
import
org.onosproject.net.Path
;
import
com.fasterxml.jackson.databind.node.ArrayNode
;
import
com.fasterxml.jackson.databind.node.ObjectNode
;
import
static
com
.
google
.
common
.
base
.
Preconditions
.
checkNotNull
;
/**
* Path JSON codec.
*/
public
class
PathCodec
extends
AnnotatedCodec
<
Path
>
{
@Override
public
ObjectNode
encode
(
Path
path
,
CodecContext
context
)
{
checkNotNull
(
path
,
"Path cannot be null"
);
JsonCodec
<
Link
>
codec
=
context
.
codec
(
Link
.
class
);
ObjectNode
result
=
context
.
mapper
()
.
createObjectNode
()
.
put
(
"cost"
,
path
.
cost
());
ArrayNode
jsonLinks
=
result
.
putArray
(
"links"
);
for
(
Link
link
:
path
.
links
())
{
jsonLinks
.
add
(
codec
.
encode
(
link
,
context
));
}
return
annotate
(
result
,
path
,
context
);
}
}
web/api/src/main/java/org/onosproject/rest/PathsWebResource.java
0 → 100644
View file @
19ffea3
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
org
.
onosproject
.
rest
;
import
java.util.Set
;
import
javax.ws.rs.GET
;
import
javax.ws.rs.Path
;
import
javax.ws.rs.PathParam
;
import
javax.ws.rs.Produces
;
import
javax.ws.rs.core.MediaType
;
import
javax.ws.rs.core.Response
;
import
org.onosproject.net.DeviceId
;
import
org.onosproject.net.ElementId
;
import
org.onosproject.net.HostId
;
import
org.onosproject.net.topology.PathService
;
import
com.fasterxml.jackson.databind.node.ObjectNode
;
/**
* REST resource for interacting with path calculations.
*/
@Path
(
"paths"
)
public
class
PathsWebResource
extends
AbstractWebResource
{
// Host id format is 00:00:00:00:00:01/-1
private
static
final
int
VLAN_SEPARATOR_OFFSET
=
17
;
private
static
final
int
FIRST_MAC_ADDRESS_SEPARATOR_OFFSET
=
2
;
private
static
final
int
SECOND_MAC_ADDRESS_SEPARATOR_OFFSET
=
5
;
private
static
final
int
THIRD_MAC_ADDRESS_SEPARATOR_OFFSET
=
8
;
/**
* Determines if the id appears to be the id of a host.
*
* @param id id string
* @return HostId if the id is valid, null otherwise
*/
private
HostId
isHostId
(
String
id
)
{
if
(
id
.
length
()
<
VLAN_SEPARATOR_OFFSET
+
1
||
id
.
charAt
(
FIRST_MAC_ADDRESS_SEPARATOR_OFFSET
)
!=
':'
||
id
.
charAt
(
SECOND_MAC_ADDRESS_SEPARATOR_OFFSET
)
!=
':'
||
id
.
charAt
(
THIRD_MAC_ADDRESS_SEPARATOR_OFFSET
)
!=
':'
||
id
.
charAt
(
VLAN_SEPARATOR_OFFSET
)
!=
'/'
)
{
return
null
;
}
return
HostId
.
hostId
(
id
);
}
/**
* Gets the paths between two elements.
*
* @param src source
* @param dst destination
* @return path data
*/
@GET
@Produces
(
MediaType
.
APPLICATION_JSON
)
@Path
(
"{src}/{dst}"
)
public
Response
getPath
(
@PathParam
(
"src"
)
String
src
,
@PathParam
(
"dst"
)
String
dst
)
{
PathService
pathService
=
get
(
PathService
.
class
);
ElementId
srcElement
=
isHostId
(
src
);
ElementId
dstElement
=
isHostId
(
dst
);
if
(
srcElement
==
null
)
{
// Doesn't look like a host, assume it is a device
srcElement
=
DeviceId
.
deviceId
(
src
);
}
if
(
dstElement
==
null
)
{
// Doesn't look like a host, assume it is a device
dstElement
=
DeviceId
.
deviceId
(
dst
);
}
Set
<
org
.
onosproject
.
net
.
Path
>
paths
=
pathService
.
getPaths
(
srcElement
,
dstElement
);
ObjectNode
root
=
encodeArray
(
org
.
onosproject
.
net
.
Path
.
class
,
"paths"
,
paths
);
return
ok
(
root
).
build
();
}
}
web/api/src/main/webapp/WEB-INF/web.xml
View file @
19ffea3
...
...
@@ -43,7 +43,8 @@
org.onosproject.rest.IntentsWebResource,
org.onosproject.rest.FlowsWebResource,
org.onosproject.rest.TopologyWebResource,
org.onosproject.rest.ConfigResource
org.onosproject.rest.ConfigResource,
org.onosproject.rest.PathsWebResource
</param-value>
</init-param>
<load-on-startup>
1
</load-on-startup>
...
...
web/api/src/test/java/org/onosproject/rest/PathsResourceTest.java
0 → 100644
View file @
19ffea3
/*
* Copyright 2015 Open Networking Laboratory
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
org
.
onosproject
.
rest
;
import
java.io.UnsupportedEncodingException
;
import
java.net.URLEncoder
;
import
java.nio.charset.StandardCharsets
;
import
java.util.Set
;
import
org.hamcrest.Description
;
import
org.hamcrest.TypeSafeDiagnosingMatcher
;
import
org.junit.After
;
import
org.junit.Before
;
import
org.junit.Test
;
import
org.onlab.osgi.ServiceDirectory
;
import
org.onlab.osgi.TestServiceDirectory
;
import
org.onlab.rest.BaseResource
;
import
org.onosproject.codec.CodecService
;
import
org.onosproject.codec.impl.CodecManager
;
import
org.onosproject.net.ElementId
;
import
org.onosproject.net.Link
;
import
org.onosproject.net.Path
;
import
org.onosproject.net.topology.PathService
;
import
com.eclipsesource.json.JsonArray
;
import
com.eclipsesource.json.JsonObject
;
import
com.google.common.collect.ImmutableSet
;
import
com.sun.jersey.api.client.WebResource
;
import
static
org
.
easymock
.
EasyMock
.
createMock
;
import
static
org
.
easymock
.
EasyMock
.
expect
;
import
static
org
.
easymock
.
EasyMock
.
replay
;
import
static
org
.
easymock
.
EasyMock
.
verify
;
import
static
org
.
hamcrest
.
Matchers
.
containsString
;
import
static
org
.
hamcrest
.
Matchers
.
hasSize
;
import
static
org
.
hamcrest
.
Matchers
.
is
;
import
static
org
.
hamcrest
.
Matchers
.
notNullValue
;
import
static
org
.
junit
.
Assert
.
assertThat
;
import
static
org
.
onosproject
.
net
.
NetTestTools
.
createPath
;
import
static
org
.
onosproject
.
net
.
NetTestTools
.
did
;
import
static
org
.
onosproject
.
net
.
NetTestTools
.
hid
;
/**
* Unit tests for paths REST APIs.
*/
public
class
PathsResourceTest
extends
ResourceTest
{
Path
path1
=
createPath
(
"dev1"
,
"dev2"
);
Path
path2
=
createPath
(
"dev2"
,
"dev3"
);
Set
<
Path
>
paths
=
ImmutableSet
.
of
(
path1
,
path2
);
final
PathService
mockPathService
=
createMock
(
PathService
.
class
);
/**
* Hamcrest matcher for a path and its JSON representation.
*/
private
final
class
PathJsonMatcher
extends
TypeSafeDiagnosingMatcher
<
JsonObject
>
{
private
final
Path
path
;
/**
* Creates the matcher.
*
* @param pathValue the path object to match
*/
private
PathJsonMatcher
(
Path
pathValue
)
{
path
=
pathValue
;
}
@Override
public
boolean
matchesSafely
(
JsonObject
pathJson
,
Description
description
)
{
double
jsonCost
=
pathJson
.
get
(
"cost"
).
asDouble
();
if
(
jsonCost
!=
path
.
cost
())
{
description
.
appendText
(
"src device was "
+
jsonCost
);
return
false
;
}
JsonArray
jsonLinks
=
pathJson
.
get
(
"links"
).
asArray
();
assertThat
(
jsonLinks
.
size
(),
is
(
path
.
links
().
size
()));
for
(
int
linkIndex
=
0
;
linkIndex
<
jsonLinks
.
size
();
linkIndex
++)
{
Link
link
=
path
.
links
().
get
(
linkIndex
);
JsonObject
jsonLink
=
jsonLinks
.
get
(
0
).
asObject
();
JsonObject
jsonLinkSrc
=
jsonLink
.
get
(
"src"
).
asObject
();
String
srcDevice
=
jsonLinkSrc
.
get
(
"device"
).
asString
();
if
(!
srcDevice
.
equals
(
link
.
src
().
deviceId
().
toString
()))
{
description
.
appendText
(
"src device was "
+
jsonLinkSrc
);
return
false
;
}
JsonObject
jsonLinkDst
=
jsonLink
.
get
(
"dst"
).
asObject
();
String
dstDevice
=
jsonLinkDst
.
get
(
"device"
).
asString
();
if
(!
dstDevice
.
equals
(
link
.
dst
().
deviceId
().
toString
()))
{
description
.
appendText
(
"dst device was "
+
jsonLinkDst
);
return
false
;
}
}
return
true
;
}
@Override
public
void
describeTo
(
Description
description
)
{
description
.
appendText
(
path
.
toString
());
}
}
/**
* Factory to allocate an connect point matcher.
*
* @param path path object we are looking for
* @return matcher
*/
private
PathJsonMatcher
matchesPath
(
Path
path
)
{
return
new
PathJsonMatcher
(
path
);
}
@Before
public
void
setUp
()
{
// Register the services needed for the test
CodecManager
codecService
=
new
CodecManager
();
codecService
.
activate
();
ServiceDirectory
testDirectory
=
new
TestServiceDirectory
()
.
add
(
PathService
.
class
,
mockPathService
)
.
add
(
CodecService
.
class
,
codecService
);
BaseResource
.
setServiceDirectory
(
testDirectory
);
}
@After
public
void
tearDown
()
throws
Exception
{
super
.
tearDown
();
verify
(
mockPathService
);
}
/**
* Tests a REST path GET for the given endpoints.
*
* @param srcElement source element of the path
* @param dstElement destination element of the path
*
* @throws UnsupportedEncodingException
*/
private
void
runTest
(
ElementId
srcElement
,
ElementId
dstElement
)
throws
UnsupportedEncodingException
{
expect
(
mockPathService
.
getPaths
(
srcElement
,
dstElement
))
.
andReturn
(
paths
)
.
once
();
replay
(
mockPathService
);
String
srcId
=
URLEncoder
.
encode
(
srcElement
.
toString
(),
StandardCharsets
.
UTF_8
.
name
());
String
dstId
=
URLEncoder
.
encode
(
dstElement
.
toString
(),
StandardCharsets
.
UTF_8
.
name
());
String
url
=
"paths/"
+
srcId
+
"/"
+
dstId
;
WebResource
rs
=
resource
();
String
response
=
rs
.
path
(
url
).
get
(
String
.
class
);
assertThat
(
response
,
containsString
(
"{\"paths\":["
));
JsonObject
result
=
JsonObject
.
readFrom
(
response
);
assertThat
(
result
,
notNullValue
());
assertThat
(
result
.
names
(),
hasSize
(
1
));
assertThat
(
result
.
names
().
get
(
0
),
is
(
"paths"
));
JsonArray
jsonPaths
=
result
.
get
(
"paths"
).
asArray
();
assertThat
(
jsonPaths
,
notNullValue
());
assertThat
(
jsonPaths
.
size
(),
is
(
2
));
JsonObject
path1Json
=
jsonPaths
.
get
(
0
).
asObject
();
assertThat
(
path1Json
,
matchesPath
(
path1
));
JsonObject
path2Json
=
jsonPaths
.
get
(
1
).
asObject
();
assertThat
(
path2Json
,
matchesPath
(
path2
));
}
/**
* Tests a path between two hosts.
*
* @throws UnsupportedEncodingException if UTF-8 not found
*/
@Test
public
void
hostToHost
()
throws
UnsupportedEncodingException
{
runTest
(
hid
(
"01:23:45:67:89:AB/2"
),
hid
(
"AB:89:67:45:23:01/4"
));
}
/**
* Tests a path with a host as the source and a switch as the destination.
*
* @throws UnsupportedEncodingException if UTF-8 not found
*/
@Test
public
void
hostToDevice
()
throws
UnsupportedEncodingException
{
runTest
(
hid
(
"01:23:45:67:89:AB/2"
),
did
(
"switch1"
));
}
/**
* Tests a path with a switch as the source and a host as the destination.
*
* @throws UnsupportedEncodingException if UTF-8 not found
*/
@Test
public
void
deviceToHost
()
throws
UnsupportedEncodingException
{
runTest
(
did
(
"switch1"
),
hid
(
"01:23:45:67:89:AB/2"
));
}
/**
* Tests a path between two switches.
*
* @throws UnsupportedEncodingException if UTF-8 not found
*/
@Test
public
void
deviceToDevice
()
throws
UnsupportedEncodingException
{
runTest
(
did
(
"switch1"
),
did
(
"switch2"
));
}
}
Please
register
or
login
to post a comment