Committed by
Ray Milkey
Initial sketch of codecs and REST API approach.
FIxed typos and defects. ONOS-81 Change-Id: I789444a181abea509c354966545c927e305710d1
Showing
28 changed files
with
985 additions
and
22 deletions
1 | +/* | ||
2 | + * Copyright 2014 Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.onlab.onos.codec; | ||
17 | + | ||
18 | +import com.fasterxml.jackson.databind.ObjectMapper; | ||
19 | + | ||
20 | +/** | ||
21 | + * Context for codecs to use while encoding/decoding. | ||
22 | + */ | ||
23 | +public interface CodecContext { | ||
24 | + | ||
25 | + /** | ||
26 | + * Returns the JSON object mapper. | ||
27 | + * | ||
28 | + * @return object mapper | ||
29 | + */ | ||
30 | + ObjectMapper mapper(); | ||
31 | + | ||
32 | + /** | ||
33 | + * Returns the JSON codec for the specified entity class. | ||
34 | + * | ||
35 | + * @param entityClass entity class | ||
36 | + * @param <T> entity type | ||
37 | + * @return JSON codec; null if no codec available for the class | ||
38 | + */ | ||
39 | + <T> JsonCodec<T> codec(Class<T> entityClass); | ||
40 | + | ||
41 | + /** | ||
42 | + * Returns reference to the specified service implementation. | ||
43 | + * | ||
44 | + * @param serviceClass service class | ||
45 | + * @param <T> service type | ||
46 | + * @return JSON codec; null if no codec available for the class | ||
47 | + */ | ||
48 | + <T> T get(Class<T> serviceClass); | ||
49 | + | ||
50 | +} |
... | @@ -33,9 +33,10 @@ public interface CodecService { | ... | @@ -33,9 +33,10 @@ public interface CodecService { |
33 | * Returns the JSON codec for the specified entity class. | 33 | * Returns the JSON codec for the specified entity class. |
34 | * | 34 | * |
35 | * @param entityClass entity class | 35 | * @param entityClass entity class |
36 | + * @param <T> entity type | ||
36 | * @return JSON codec; null if no codec available for the class | 37 | * @return JSON codec; null if no codec available for the class |
37 | */ | 38 | */ |
38 | - JsonCodec getCodec(Class<?> entityClass); | 39 | + <T> JsonCodec<T> getCodec(Class<T> entityClass); |
39 | 40 | ||
40 | /** | 41 | /** |
41 | * Registers the specified JSON codec for the given entity class. | 42 | * Registers the specified JSON codec for the given entity class. |
... | @@ -43,7 +44,7 @@ public interface CodecService { | ... | @@ -43,7 +44,7 @@ public interface CodecService { |
43 | * @param entityClass entity class | 44 | * @param entityClass entity class |
44 | * @param codec JSON codec | 45 | * @param codec JSON codec |
45 | */ | 46 | */ |
46 | - void registerCodec(Class<?> entityClass, JsonCodec codec); | 47 | + <T> void registerCodec(Class<T> entityClass, JsonCodec<T> codec); |
47 | 48 | ||
48 | /** | 49 | /** |
49 | * Unregisters the JSON codec for the specified entity class. | 50 | * Unregisters the JSON codec for the specified entity class. | ... | ... |
... | @@ -16,7 +16,6 @@ | ... | @@ -16,7 +16,6 @@ |
16 | package org.onlab.onos.codec; | 16 | package org.onlab.onos.codec; |
17 | 17 | ||
18 | import com.fasterxml.jackson.databind.JsonNode; | 18 | import com.fasterxml.jackson.databind.JsonNode; |
19 | -import com.fasterxml.jackson.databind.ObjectMapper; | ||
20 | import com.fasterxml.jackson.databind.node.ArrayNode; | 19 | import com.fasterxml.jackson.databind.node.ArrayNode; |
21 | import com.fasterxml.jackson.databind.node.ObjectNode; | 20 | import com.fasterxml.jackson.databind.node.ObjectNode; |
22 | 21 | ||
... | @@ -32,36 +31,41 @@ public abstract class JsonCodec<T> { | ... | @@ -32,36 +31,41 @@ public abstract class JsonCodec<T> { |
32 | * Encodes the specified entity into JSON. | 31 | * Encodes the specified entity into JSON. |
33 | * | 32 | * |
34 | * @param entity entity to encode | 33 | * @param entity entity to encode |
35 | - * @param mapper object mapper | 34 | + * @param context encoding context |
36 | * @return JSON node | 35 | * @return JSON node |
37 | * @throws java.lang.UnsupportedOperationException if the codec does not | 36 | * @throws java.lang.UnsupportedOperationException if the codec does not |
38 | * support encode operations | 37 | * support encode operations |
39 | */ | 38 | */ |
40 | - public abstract ObjectNode encode(T entity, ObjectMapper mapper); | 39 | + public ObjectNode encode(T entity, CodecContext context) { |
40 | + throw new UnsupportedOperationException("encode() not supported"); | ||
41 | + } | ||
41 | 42 | ||
42 | /** | 43 | /** |
43 | * Decodes the specified entity from JSON. | 44 | * Decodes the specified entity from JSON. |
44 | * | 45 | * |
45 | * @param json JSON to decode | 46 | * @param json JSON to decode |
47 | + * @param context decoding context | ||
46 | * @return decoded entity | 48 | * @return decoded entity |
47 | * @throws java.lang.UnsupportedOperationException if the codec does not | 49 | * @throws java.lang.UnsupportedOperationException if the codec does not |
48 | * support decode operations | 50 | * support decode operations |
49 | */ | 51 | */ |
50 | - public abstract T decode(ObjectNode json); | 52 | + public T decode(ObjectNode json, CodecContext context) { |
53 | + throw new UnsupportedOperationException("decode() not supported"); | ||
54 | + } | ||
51 | 55 | ||
52 | /** | 56 | /** |
53 | * Encodes the collection of the specified entities. | 57 | * Encodes the collection of the specified entities. |
54 | * | 58 | * |
55 | * @param entities collection of entities to encode | 59 | * @param entities collection of entities to encode |
56 | - * @param mapper object mapper | 60 | + * @param context encoding context |
57 | * @return JSON array | 61 | * @return JSON array |
58 | * @throws java.lang.UnsupportedOperationException if the codec does not | 62 | * @throws java.lang.UnsupportedOperationException if the codec does not |
59 | * support encode operations | 63 | * support encode operations |
60 | */ | 64 | */ |
61 | - public ArrayNode encode(Iterable<T> entities, ObjectMapper mapper) { | 65 | + public ArrayNode encode(Iterable<T> entities, CodecContext context) { |
62 | - ArrayNode result = mapper.createArrayNode(); | 66 | + ArrayNode result = context.mapper().createArrayNode(); |
63 | for (T entity : entities) { | 67 | for (T entity : entities) { |
64 | - result.add(encode(entity, mapper)); | 68 | + result.add(encode(entity, context)); |
65 | } | 69 | } |
66 | return result; | 70 | return result; |
67 | } | 71 | } |
... | @@ -70,14 +74,15 @@ public abstract class JsonCodec<T> { | ... | @@ -70,14 +74,15 @@ public abstract class JsonCodec<T> { |
70 | * Decodes the specified JSON array into a collection of entities. | 74 | * Decodes the specified JSON array into a collection of entities. |
71 | * | 75 | * |
72 | * @param json JSON array to decode | 76 | * @param json JSON array to decode |
77 | + * @param context decoding context | ||
73 | * @return collection of decoded entities | 78 | * @return collection of decoded entities |
74 | * @throws java.lang.UnsupportedOperationException if the codec does not | 79 | * @throws java.lang.UnsupportedOperationException if the codec does not |
75 | * support decode operations | 80 | * support decode operations |
76 | */ | 81 | */ |
77 | - public List<T> decode(ArrayNode json) { | 82 | + public List<T> decode(ArrayNode json, CodecContext context) { |
78 | List<T> result = new ArrayList<>(); | 83 | List<T> result = new ArrayList<>(); |
79 | for (JsonNode node : json) { | 84 | for (JsonNode node : json) { |
80 | - result.add(decode((ObjectNode) node)); | 85 | + result.add(decode((ObjectNode) node, context)); |
81 | } | 86 | } |
82 | return result; | 87 | return result; |
83 | } | 88 | } | ... | ... |
... | @@ -92,6 +92,8 @@ public interface LinkService { | ... | @@ -92,6 +92,8 @@ public interface LinkService { |
92 | */ | 92 | */ |
93 | Set<Link> getIngressLinks(ConnectPoint connectPoint); | 93 | Set<Link> getIngressLinks(ConnectPoint connectPoint); |
94 | 94 | ||
95 | + // FIXME: I don't think this makes sense; discuss and remove or adjust return | ||
96 | + // to be a Set<Link> or add Link.Type parameter | ||
95 | /** | 97 | /** |
96 | * Returns the infrastructure links between the specified source | 98 | * Returns the infrastructure links between the specified source |
97 | * and destination connection points. | 99 | * and destination connection points. | ... | ... |
... | @@ -58,12 +58,12 @@ public class JsonCodecTest { | ... | @@ -58,12 +58,12 @@ public class JsonCodecTest { |
58 | 58 | ||
59 | private static class FooCodec extends JsonCodec<Foo> { | 59 | private static class FooCodec extends JsonCodec<Foo> { |
60 | @Override | 60 | @Override |
61 | - public ObjectNode encode(Foo entity, ObjectMapper mapper) { | 61 | + public ObjectNode encode(Foo entity, CodecContext context) { |
62 | - return mapper.createObjectNode().put("name", entity.name); | 62 | + return context.mapper().createObjectNode().put("name", entity.name); |
63 | } | 63 | } |
64 | 64 | ||
65 | @Override | 65 | @Override |
66 | - public Foo decode(ObjectNode json) { | 66 | + public Foo decode(ObjectNode json, CodecContext context) { |
67 | return new Foo(json.get("name").asText()); | 67 | return new Foo(json.get("name").asText()); |
68 | } | 68 | } |
69 | } | 69 | } |
... | @@ -74,9 +74,26 @@ public class JsonCodecTest { | ... | @@ -74,9 +74,26 @@ public class JsonCodecTest { |
74 | Foo f2 = new Foo("bar"); | 74 | Foo f2 = new Foo("bar"); |
75 | FooCodec codec = new FooCodec(); | 75 | FooCodec codec = new FooCodec(); |
76 | ImmutableList<Foo> entities = ImmutableList.of(f1, f2); | 76 | ImmutableList<Foo> entities = ImmutableList.of(f1, f2); |
77 | - ArrayNode json = codec.encode(entities, new ObjectMapper()); | 77 | + ArrayNode json = codec.encode(entities, new TestContext()); |
78 | - List<Foo> foos = codec.decode(json); | 78 | + List<Foo> foos = codec.decode(json, new TestContext()); |
79 | assertEquals("incorrect encode/decode", entities, foos); | 79 | assertEquals("incorrect encode/decode", entities, foos); |
80 | } | 80 | } |
81 | 81 | ||
82 | + private class TestContext implements CodecContext { | ||
83 | + private ObjectMapper mapper = new ObjectMapper(); | ||
84 | + @Override | ||
85 | + public ObjectMapper mapper() { | ||
86 | + return mapper; | ||
87 | + } | ||
88 | + | ||
89 | + @Override | ||
90 | + public <T> JsonCodec<T> codec(Class<T> entityClass) { | ||
91 | + return null; | ||
92 | + } | ||
93 | + | ||
94 | + @Override | ||
95 | + public <T> T get(Class<T> serviceClass) { | ||
96 | + return null; | ||
97 | + } | ||
98 | + } | ||
82 | } | 99 | } |
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
... | @@ -80,7 +80,7 @@ | ... | @@ -80,7 +80,7 @@ |
80 | <group> | 80 | <group> |
81 | <title>GUI, REST & Command-Line</title> | 81 | <title>GUI, REST & Command-Line</title> |
82 | <packages> | 82 | <packages> |
83 | - org.onlab.onos.gui:org.onlab.onos.rest:org.onlab.onos.cli:org.onlab.onos.gui.*:org.onlab.onos.rest.*:org.onlab.onos.cli.* | 83 | + org.onlab.onos.gui:org.onlab.onos.rest:org.onlab.onos.cli:org.onlab.onos.gui.*:org.onlab.onos.rest.*:org.onlab.onos.cli.*:org.onlab.onos.codec.impl |
84 | </packages> | 84 | </packages> |
85 | </group> | 85 | </group> |
86 | <group> | 86 | <group> | ... | ... |
1 | +/* | ||
2 | + * Copyright 2014 Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.onlab.api; | ||
17 | + | ||
18 | +/** | ||
19 | + * Represents condition where an item is not found or not available. | ||
20 | + */ | ||
21 | +public class ItemNotFoundException extends RuntimeException { | ||
22 | + | ||
23 | + /** | ||
24 | + * Creates a new exception with no message. | ||
25 | + */ | ||
26 | + public ItemNotFoundException() { | ||
27 | + } | ||
28 | + | ||
29 | + /** | ||
30 | + * Creates a new exception with the supplied message. | ||
31 | + * @param message error message | ||
32 | + */ | ||
33 | + public ItemNotFoundException(String message) { | ||
34 | + super(message); | ||
35 | + } | ||
36 | + | ||
37 | + /** | ||
38 | + * Creates a new exception with the supplied message and cause. | ||
39 | + * @param message error message | ||
40 | + * @param cause cause of the error | ||
41 | + */ | ||
42 | + public ItemNotFoundException(String message, Throwable cause) { | ||
43 | + super(message, cause); | ||
44 | + } | ||
45 | + | ||
46 | +} |
... | @@ -18,6 +18,8 @@ package org.onlab.rest; | ... | @@ -18,6 +18,8 @@ package org.onlab.rest; |
18 | import org.onlab.osgi.DefaultServiceDirectory; | 18 | import org.onlab.osgi.DefaultServiceDirectory; |
19 | import org.onlab.osgi.ServiceDirectory; | 19 | import org.onlab.osgi.ServiceDirectory; |
20 | 20 | ||
21 | +import javax.ws.rs.core.Response; | ||
22 | + | ||
21 | /** | 23 | /** |
22 | * Base abstraction of a JAX-RS resource. | 24 | * Base abstraction of a JAX-RS resource. |
23 | */ | 25 | */ |
... | @@ -44,8 +46,12 @@ public abstract class BaseResource { | ... | @@ -44,8 +46,12 @@ public abstract class BaseResource { |
44 | * @param <T> type of service | 46 | * @param <T> type of service |
45 | * @return service implementation | 47 | * @return service implementation |
46 | */ | 48 | */ |
47 | - protected static <T> T get(Class<T> service) { | 49 | + public <T> T get(Class<T> service) { |
48 | return services.get(service); | 50 | return services.get(service); |
49 | } | 51 | } |
50 | 52 | ||
53 | + protected static Response.ResponseBuilder ok(Object obj) { | ||
54 | + return Response.ok(obj); | ||
55 | + } | ||
56 | + | ||
51 | } | 57 | } | ... | ... |
1 | +/* | ||
2 | + * Copyright 2014 Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.onlab.onos.codec.impl; | ||
17 | + | ||
18 | +import com.fasterxml.jackson.databind.node.ObjectNode; | ||
19 | +import org.onlab.onos.codec.CodecContext; | ||
20 | +import org.onlab.onos.codec.JsonCodec; | ||
21 | +import org.onlab.onos.net.Annotated; | ||
22 | +import org.onlab.onos.net.Annotations; | ||
23 | + | ||
24 | +/** | ||
25 | + * Base JSON codec for annotated entities. | ||
26 | + */ | ||
27 | +public abstract class AnnotatedCodec<T extends Annotated> extends JsonCodec<T> { | ||
28 | + | ||
29 | + /** | ||
30 | + * Adds JSON encoding of the given item annotations to the specified node. | ||
31 | + * | ||
32 | + * @param node node to add annotations to | ||
33 | + * @param entity annotated entity | ||
34 | + * @param context encode context | ||
35 | + * @return the given node | ||
36 | + */ | ||
37 | + protected ObjectNode annotate(ObjectNode node, T entity, CodecContext context) { | ||
38 | + if (!entity.annotations().keys().isEmpty()) { | ||
39 | + JsonCodec<Annotations> codec = context.codec(Annotations.class); | ||
40 | + node.set("annotations", codec.encode(entity.annotations(), context)); | ||
41 | + } | ||
42 | + return node; | ||
43 | + } | ||
44 | + | ||
45 | +} |
1 | +/* | ||
2 | + * Copyright 2014 Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.onlab.onos.codec.impl; | ||
17 | + | ||
18 | +import com.fasterxml.jackson.databind.node.ObjectNode; | ||
19 | +import org.onlab.onos.codec.CodecContext; | ||
20 | +import org.onlab.onos.codec.JsonCodec; | ||
21 | +import org.onlab.onos.net.Annotations; | ||
22 | + | ||
23 | +/** | ||
24 | + * Annotations JSON codec. | ||
25 | + */ | ||
26 | +public class AnnotationsCodec extends JsonCodec<Annotations> { | ||
27 | + | ||
28 | + @Override | ||
29 | + public ObjectNode encode(Annotations annotations, CodecContext context) { | ||
30 | + ObjectNode result = context.mapper().createObjectNode(); | ||
31 | + for (String key : annotations.keys()) { | ||
32 | + result.put(key, annotations.value(key)); | ||
33 | + } | ||
34 | + return result; | ||
35 | + } | ||
36 | + | ||
37 | +} |
1 | +/* | ||
2 | + * Copyright 2014 Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.onlab.onos.codec.impl; | ||
17 | + | ||
18 | +import com.google.common.collect.ImmutableSet; | ||
19 | +import org.apache.felix.scr.annotations.Activate; | ||
20 | +import org.apache.felix.scr.annotations.Component; | ||
21 | +import org.apache.felix.scr.annotations.Deactivate; | ||
22 | +import org.apache.felix.scr.annotations.Service; | ||
23 | +import org.onlab.onos.codec.CodecService; | ||
24 | +import org.onlab.onos.codec.JsonCodec; | ||
25 | +import org.onlab.onos.net.Annotations; | ||
26 | +import org.onlab.onos.net.ConnectPoint; | ||
27 | +import org.onlab.onos.net.Device; | ||
28 | +import org.onlab.onos.net.Link; | ||
29 | +import org.onlab.onos.net.Port; | ||
30 | +import org.slf4j.Logger; | ||
31 | +import org.slf4j.LoggerFactory; | ||
32 | + | ||
33 | +import java.util.Map; | ||
34 | +import java.util.Set; | ||
35 | +import java.util.concurrent.ConcurrentHashMap; | ||
36 | + | ||
37 | +/** | ||
38 | + * Implementation of the JSON codec brokering service. | ||
39 | + */ | ||
40 | +@Component(immediate = true) | ||
41 | +@Service | ||
42 | +public class CodecManager implements CodecService { | ||
43 | + | ||
44 | + private static Logger log = LoggerFactory.getLogger(CodecManager.class); | ||
45 | + | ||
46 | + private final Map<Class<?>, JsonCodec> codecs = new ConcurrentHashMap<>(); | ||
47 | + | ||
48 | + @Activate | ||
49 | + public void activate() { | ||
50 | + codecs.clear(); | ||
51 | + registerCodec(Annotations.class, new AnnotationsCodec()); | ||
52 | + registerCodec(Device.class, new DeviceCodec()); | ||
53 | + registerCodec(Port.class, new PortCodec()); | ||
54 | + registerCodec(ConnectPoint.class, new ConnectPointCodec()); | ||
55 | + registerCodec(Link.class, new LinkCodec()); | ||
56 | + log.info("Started"); | ||
57 | + } | ||
58 | + | ||
59 | + @Deactivate | ||
60 | + public void deativate() { | ||
61 | + codecs.clear(); | ||
62 | + log.info("Stopped"); | ||
63 | + } | ||
64 | + | ||
65 | + @Override | ||
66 | + public Set<Class<?>> getCodecs() { | ||
67 | + return ImmutableSet.copyOf(codecs.keySet()); | ||
68 | + } | ||
69 | + | ||
70 | + @Override | ||
71 | + @SuppressWarnings("unchecked") | ||
72 | + public <T> JsonCodec<T> getCodec(Class<T> entityClass) { | ||
73 | + return codecs.get(entityClass); | ||
74 | + } | ||
75 | + | ||
76 | + @Override | ||
77 | + public <T> void registerCodec(Class<T> entityClass, JsonCodec<T> codec) { | ||
78 | + codecs.putIfAbsent(entityClass, codec); | ||
79 | + } | ||
80 | + | ||
81 | + @Override | ||
82 | + public void unregisterCodec(Class<?> entityClass) { | ||
83 | + codecs.remove(entityClass); | ||
84 | + } | ||
85 | + | ||
86 | +} |
1 | +/* | ||
2 | + * Copyright 2014 Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.onlab.onos.codec.impl; | ||
17 | + | ||
18 | +import com.fasterxml.jackson.databind.node.ObjectNode; | ||
19 | +import org.onlab.onos.codec.CodecContext; | ||
20 | +import org.onlab.onos.codec.JsonCodec; | ||
21 | +import org.onlab.onos.net.ConnectPoint; | ||
22 | + | ||
23 | +import static com.google.common.base.Preconditions.checkNotNull; | ||
24 | + | ||
25 | +/** | ||
26 | + * Connection point JSON codec. | ||
27 | + */ | ||
28 | +public class ConnectPointCodec extends JsonCodec<ConnectPoint> { | ||
29 | + | ||
30 | + @Override | ||
31 | + public ObjectNode encode(ConnectPoint point, CodecContext context) { | ||
32 | + checkNotNull(point, "Connect point cannot be null"); | ||
33 | + return context.mapper().createObjectNode() | ||
34 | + .put("device", point.deviceId().toString()) | ||
35 | + .put("port", point.port().toString()); | ||
36 | + } | ||
37 | + | ||
38 | +} |
1 | +/* | ||
2 | + * Copyright 2014 Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.onlab.onos.codec.impl; | ||
17 | + | ||
18 | +import com.fasterxml.jackson.databind.node.ObjectNode; | ||
19 | +import org.onlab.onos.codec.CodecContext; | ||
20 | +import org.onlab.onos.net.Device; | ||
21 | +import org.onlab.onos.net.device.DeviceService; | ||
22 | + | ||
23 | +import static com.google.common.base.Preconditions.checkNotNull; | ||
24 | + | ||
25 | +/** | ||
26 | + * Device JSON codec. | ||
27 | + */ | ||
28 | +public class DeviceCodec extends AnnotatedCodec<Device> { | ||
29 | + | ||
30 | + @Override | ||
31 | + public ObjectNode encode(Device device, CodecContext context) { | ||
32 | + checkNotNull(device, "Device cannot be null"); | ||
33 | + DeviceService service = context.get(DeviceService.class); | ||
34 | + ObjectNode result = context.mapper().createObjectNode() | ||
35 | + .put("id", device.id().toString()) | ||
36 | + .put("available", service.isAvailable(device.id())) | ||
37 | + .put("role", service.getRole(device.id()).toString()) | ||
38 | + .put("mfr", device.manufacturer()) | ||
39 | + .put("hw", device.hwVersion()) | ||
40 | + .put("sw", device.swVersion()) | ||
41 | + .put("serial", device.serialNumber()); | ||
42 | + return annotate(result, device, context); | ||
43 | + } | ||
44 | + | ||
45 | +} |
1 | +/* | ||
2 | + * Copyright 2014 Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.onlab.onos.codec.impl; | ||
17 | + | ||
18 | +import com.fasterxml.jackson.databind.node.ObjectNode; | ||
19 | +import org.onlab.onos.codec.CodecContext; | ||
20 | +import org.onlab.onos.codec.JsonCodec; | ||
21 | +import org.onlab.onos.net.ConnectPoint; | ||
22 | +import org.onlab.onos.net.Link; | ||
23 | +import org.onlab.onos.net.device.DeviceService; | ||
24 | + | ||
25 | +import static com.google.common.base.Preconditions.checkNotNull; | ||
26 | + | ||
27 | +/** | ||
28 | + * Link JSON codec. | ||
29 | + */ | ||
30 | +public class LinkCodec extends AnnotatedCodec<Link> { | ||
31 | + | ||
32 | + @Override | ||
33 | + public ObjectNode encode(Link link, CodecContext context) { | ||
34 | + checkNotNull(link, "Link cannot be null"); | ||
35 | + DeviceService service = context.get(DeviceService.class); | ||
36 | + JsonCodec<ConnectPoint> codec = context.codec(ConnectPoint.class); | ||
37 | + ObjectNode result = context.mapper().createObjectNode(); | ||
38 | + result.set("src", codec.encode(link.src(), context)); | ||
39 | + result.set("dst", codec.encode(link.dst(), context)); | ||
40 | + return annotate(result, link, context); | ||
41 | + } | ||
42 | + | ||
43 | +} |
1 | +/* | ||
2 | + * Copyright 2014 Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.onlab.onos.codec.impl; | ||
17 | + | ||
18 | +import com.fasterxml.jackson.databind.node.ObjectNode; | ||
19 | +import org.onlab.onos.codec.CodecContext; | ||
20 | +import org.onlab.onos.net.Port; | ||
21 | +import org.onlab.onos.net.PortNumber; | ||
22 | + | ||
23 | +import static com.google.common.base.Preconditions.checkNotNull; | ||
24 | + | ||
25 | +/** | ||
26 | + * Device port JSON codec. | ||
27 | + */ | ||
28 | +public class PortCodec extends AnnotatedCodec<Port> { | ||
29 | + | ||
30 | + @Override | ||
31 | + public ObjectNode encode(Port port, CodecContext context) { | ||
32 | + checkNotNull(port, "Port cannot be null"); | ||
33 | + ObjectNode result = context.mapper().createObjectNode() | ||
34 | + .put("port", portName(port.number())) | ||
35 | + .put("isEnabled", port.isEnabled()) | ||
36 | + .put("type", port.type().toString().toLowerCase()) | ||
37 | + .put("portSpeed", port.portSpeed()); | ||
38 | + return annotate(result, port, context); | ||
39 | + } | ||
40 | + | ||
41 | + private String portName(PortNumber port) { | ||
42 | + return port.equals(PortNumber.LOCAL) ? "local" : port.toString(); | ||
43 | + } | ||
44 | + | ||
45 | +} |
1 | +/* | ||
2 | + * Copyright 2014 Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +/** | ||
18 | + * Implementations of the codec broker and built-in entity JSON codecs. | ||
19 | + */ | ||
20 | +package org.onlab.onos.codec.impl; | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | +/* | ||
2 | + * Copyright 2014 Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.onlab.onos.rest; | ||
17 | + | ||
18 | +import com.fasterxml.jackson.databind.ObjectMapper; | ||
19 | +import com.fasterxml.jackson.databind.node.ObjectNode; | ||
20 | +import org.onlab.api.ItemNotFoundException; | ||
21 | +import org.onlab.onos.codec.CodecContext; | ||
22 | +import org.onlab.onos.codec.CodecService; | ||
23 | +import org.onlab.onos.codec.JsonCodec; | ||
24 | +import org.onlab.rest.BaseResource; | ||
25 | + | ||
26 | +/** | ||
27 | + * Abstract REST resource. | ||
28 | + */ | ||
29 | +public class AbstractWebResource extends BaseResource implements CodecContext { | ||
30 | + | ||
31 | + @Override | ||
32 | + public ObjectMapper mapper() { | ||
33 | + return new ObjectMapper(); | ||
34 | + } | ||
35 | + | ||
36 | + /** | ||
37 | + * Returns the JSON codec for the specified entity class. | ||
38 | + * | ||
39 | + * @param entityClass entity class | ||
40 | + * @param <T> entity type | ||
41 | + * @return JSON codec | ||
42 | + */ | ||
43 | + public <T> JsonCodec<T> codec(Class<T> entityClass) { | ||
44 | + return get(CodecService.class).getCodec(entityClass); | ||
45 | + } | ||
46 | + | ||
47 | + /** | ||
48 | + * Returns JSON object wrapping the array encoding of the specified | ||
49 | + * collection of items. | ||
50 | + * | ||
51 | + * @param codecClass codec item class | ||
52 | + * @param field field holding the array | ||
53 | + * @param items collection of items to be encoded into array | ||
54 | + * @param <T> item type | ||
55 | + * @return JSON object | ||
56 | + */ | ||
57 | + protected <T> ObjectNode encodeArray(Class<T> codecClass, String field, | ||
58 | + Iterable<T> items) { | ||
59 | + ObjectNode result = mapper().createObjectNode(); | ||
60 | + result.set(field, codec(codecClass).encode(items, this)); | ||
61 | + return result; | ||
62 | + } | ||
63 | + | ||
64 | + /** | ||
65 | + * Returns the specified item if that items is null; otherwise throws | ||
66 | + * not found exception. | ||
67 | + * | ||
68 | + * @param item item to check | ||
69 | + * @param message not found message | ||
70 | + * @param <T> item type | ||
71 | + * @return item if not null | ||
72 | + * @throws org.onlab.api.ItemNotFoundException if item is null | ||
73 | + */ | ||
74 | + protected <T> T nullIsNotFound(T item, String message) { | ||
75 | + if (item == null) { | ||
76 | + throw new ItemNotFoundException(message); | ||
77 | + } | ||
78 | + return item; | ||
79 | + } | ||
80 | + | ||
81 | +} |
1 | +/* | ||
2 | + * Copyright 2014 Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.onlab.onos.rest; | ||
17 | + | ||
18 | +import com.fasterxml.jackson.databind.node.ObjectNode; | ||
19 | +import org.onlab.onos.net.Device; | ||
20 | +import org.onlab.onos.net.Port; | ||
21 | +import org.onlab.onos.net.device.DeviceService; | ||
22 | + | ||
23 | +import javax.ws.rs.GET; | ||
24 | +import javax.ws.rs.Path; | ||
25 | +import javax.ws.rs.PathParam; | ||
26 | +import javax.ws.rs.core.Response; | ||
27 | +import java.util.List; | ||
28 | + | ||
29 | +import static com.google.common.base.Preconditions.checkNotNull; | ||
30 | +import static org.onlab.onos.net.DeviceId.deviceId; | ||
31 | + | ||
32 | +/** | ||
33 | + * REST resource for interacting with the inventory of infrastructure devices. | ||
34 | + */ | ||
35 | +@Path("devices") | ||
36 | +public class DevicesWebResource extends AbstractWebResource { | ||
37 | + | ||
38 | + public static final String DEVICE_NOT_FOUND = "Device is not found"; | ||
39 | + | ||
40 | + @GET | ||
41 | + public Response getDevices() { | ||
42 | + Iterable<Device> devices = get(DeviceService.class).getDevices(); | ||
43 | + return ok(encodeArray(Device.class, "devices", devices)).build(); | ||
44 | + } | ||
45 | + | ||
46 | + @GET | ||
47 | + @Path("{id}") | ||
48 | + public Response getDevice(@PathParam("id") String id) { | ||
49 | + Device device = nullIsNotFound(get(DeviceService.class).getDevice(deviceId(id)), | ||
50 | + DEVICE_NOT_FOUND); | ||
51 | + return ok(codec(Device.class).encode(device, this)).build(); | ||
52 | + } | ||
53 | + | ||
54 | + @GET | ||
55 | + @Path("{id}/ports") | ||
56 | + public Response getDevicePorts(@PathParam("id") String id) { | ||
57 | + DeviceService service = get(DeviceService.class); | ||
58 | + Device device = nullIsNotFound(service.getDevice(deviceId(id)), DEVICE_NOT_FOUND); | ||
59 | + List<Port> ports = checkNotNull(service.getPorts(deviceId(id)), "Ports could not be retrieved"); | ||
60 | + ObjectNode result = codec(Device.class).encode(device, this); | ||
61 | + result.set("ports", codec(Port.class).encode(ports, this)); | ||
62 | + return ok(result).build(); | ||
63 | + } | ||
64 | + | ||
65 | +} |
1 | +/* | ||
2 | + * Copyright 2014 Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.onlab.onos.rest; | ||
17 | + | ||
18 | +import com.fasterxml.jackson.databind.ObjectMapper; | ||
19 | +import com.fasterxml.jackson.databind.node.ObjectNode; | ||
20 | + | ||
21 | +import javax.ws.rs.Produces; | ||
22 | +import javax.ws.rs.core.MediaType; | ||
23 | +import javax.ws.rs.core.MultivaluedMap; | ||
24 | +import javax.ws.rs.ext.MessageBodyWriter; | ||
25 | +import java.io.IOException; | ||
26 | +import java.io.OutputStream; | ||
27 | +import java.lang.annotation.Annotation; | ||
28 | +import java.lang.reflect.Type; | ||
29 | + | ||
30 | +/** | ||
31 | + * JAX-RS Response message body writer. | ||
32 | + */ | ||
33 | +@Produces("application/json") | ||
34 | +public class JsonBodyWriter implements MessageBodyWriter<ObjectNode> { | ||
35 | + | ||
36 | + private ObjectMapper mapper = new ObjectMapper(); | ||
37 | + | ||
38 | + @Override | ||
39 | + public boolean isWriteable(Class<?> type, Type genericType, | ||
40 | + Annotation[] annotations, MediaType mediaType) { | ||
41 | + return type == ObjectNode.class; | ||
42 | + } | ||
43 | + | ||
44 | + @Override | ||
45 | + public long getSize(ObjectNode node, Class<?> type, Type genericType, | ||
46 | + Annotation[] annotations, MediaType mediaType) { | ||
47 | + return -1; | ||
48 | + } | ||
49 | + | ||
50 | + @Override | ||
51 | + public void writeTo(ObjectNode node, Class<?> type, Type genericType, | ||
52 | + Annotation[] annotations, MediaType mediaType, | ||
53 | + MultivaluedMap<String, Object> httpHeaders, | ||
54 | + OutputStream entityStream) throws IOException { | ||
55 | + mapper.writer().writeValue(entityStream, node); | ||
56 | + entityStream.flush(); | ||
57 | + } | ||
58 | +} |
1 | +/* | ||
2 | + * Copyright 2014 Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.onlab.onos.rest; | ||
17 | + | ||
18 | +import org.onlab.onos.net.ConnectPoint; | ||
19 | +import org.onlab.onos.net.DeviceId; | ||
20 | +import org.onlab.onos.net.Link; | ||
21 | +import org.onlab.onos.net.link.LinkService; | ||
22 | + | ||
23 | +import javax.ws.rs.GET; | ||
24 | +import javax.ws.rs.Path; | ||
25 | +import javax.ws.rs.QueryParam; | ||
26 | +import javax.ws.rs.core.Response; | ||
27 | + | ||
28 | +import static org.onlab.onos.net.DeviceId.deviceId; | ||
29 | +import static org.onlab.onos.net.PortNumber.portNumber; | ||
30 | +import static org.onlab.onos.rest.LinksWebResource.Direction.valueOf; | ||
31 | + | ||
32 | +/** | ||
33 | + * REST resource for interacting with the inventory of infrastructure links. | ||
34 | + */ | ||
35 | +@Path("links") | ||
36 | +public class LinksWebResource extends AbstractWebResource { | ||
37 | + | ||
38 | + enum Direction { ALL, INGRESS, EGRESS } | ||
39 | + | ||
40 | + @GET | ||
41 | + public Response getLinks(@QueryParam("device") String deviceId, | ||
42 | + @QueryParam("port") String port, | ||
43 | + @QueryParam("direction") String direction) { | ||
44 | + LinkService service = get(LinkService.class); | ||
45 | + Iterable<Link> links; | ||
46 | + | ||
47 | + if (deviceId != null && port != null) { | ||
48 | + links = getConnectPointLinks(new ConnectPoint(deviceId(deviceId), | ||
49 | + portNumber(port)), | ||
50 | + direction, service); | ||
51 | + } else if (deviceId != null) { | ||
52 | + links = getDeviceLinks(deviceId(deviceId), direction, service); | ||
53 | + } else { | ||
54 | + links = service.getLinks(); | ||
55 | + } | ||
56 | + return ok(encodeArray(Link.class, "links", links)).build(); | ||
57 | + } | ||
58 | + | ||
59 | + private Iterable<Link> getConnectPointLinks(ConnectPoint point, | ||
60 | + String direction, | ||
61 | + LinkService service) { | ||
62 | + Direction dir = direction != null ? | ||
63 | + valueOf(direction.toUpperCase()) : Direction.ALL; | ||
64 | + switch (dir) { | ||
65 | + case INGRESS: | ||
66 | + return service.getIngressLinks(point); | ||
67 | + case EGRESS: | ||
68 | + return service.getEgressLinks(point); | ||
69 | + default: | ||
70 | + return service.getLinks(point); | ||
71 | + } | ||
72 | + } | ||
73 | + | ||
74 | + private Iterable<Link> getDeviceLinks(DeviceId deviceId, | ||
75 | + String direction, | ||
76 | + LinkService service) { | ||
77 | + Direction dir = direction != null ? | ||
78 | + valueOf(direction.toUpperCase()) : Direction.ALL; | ||
79 | + switch (dir) { | ||
80 | + case INGRESS: | ||
81 | + return service.getDeviceIngressLinks(deviceId); | ||
82 | + case EGRESS: | ||
83 | + return service.getDeviceEgressLinks(deviceId); | ||
84 | + default: | ||
85 | + return service.getDeviceLinks(deviceId); | ||
86 | + } | ||
87 | + } | ||
88 | + | ||
89 | +} |
1 | +/* | ||
2 | + * Copyright 2014 Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.onlab.onos.rest.exceptions; | ||
17 | + | ||
18 | +import com.fasterxml.jackson.databind.ObjectMapper; | ||
19 | +import com.fasterxml.jackson.databind.node.ObjectNode; | ||
20 | + | ||
21 | +import javax.ws.rs.core.Response; | ||
22 | +import javax.ws.rs.ext.ExceptionMapper; | ||
23 | + | ||
24 | +/** | ||
25 | + * Base exception mapper implementation. | ||
26 | + */ | ||
27 | +public abstract class AbstractMapper<E extends Throwable> implements ExceptionMapper<E> { | ||
28 | + | ||
29 | + /** | ||
30 | + * Returns the response status to be given when the exception occurs. | ||
31 | + * | ||
32 | + * @return response status | ||
33 | + */ | ||
34 | + protected abstract Response.Status responseStatus(); | ||
35 | + | ||
36 | + @Override | ||
37 | + public Response toResponse(E exception) { | ||
38 | + return response(responseStatus(), exception).build(); | ||
39 | + } | ||
40 | + | ||
41 | + /** | ||
42 | + * Produces a response builder primed with the supplied status code | ||
43 | + * and JSON entity with the status code and exception message. | ||
44 | + * | ||
45 | + * @param status response status | ||
46 | + * @param exception exception to encode | ||
47 | + * @return response builder | ||
48 | + */ | ||
49 | + protected Response.ResponseBuilder response(Response.Status status, | ||
50 | + Throwable exception) { | ||
51 | + ObjectMapper mapper = new ObjectMapper(); | ||
52 | + ObjectNode result = mapper.createObjectNode() | ||
53 | + .put("code", status.getStatusCode()) | ||
54 | + .put("message", exception.getMessage()); | ||
55 | + return Response.status(status).entity(result.toString()); | ||
56 | + } | ||
57 | +} |
1 | +/* | ||
2 | + * Copyright 2014 Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.onlab.onos.rest.exceptions; | ||
17 | + | ||
18 | +import org.onlab.api.ItemNotFoundException; | ||
19 | + | ||
20 | +import javax.ws.rs.core.Response; | ||
21 | + | ||
22 | +/** | ||
23 | + * Mapper for service not found exceptions to the NOT_FOUND response code. | ||
24 | + */ | ||
25 | +public class EntityNotFoundMapper extends AbstractMapper<ItemNotFoundException> { | ||
26 | + @Override | ||
27 | + protected Response.Status responseStatus() { | ||
28 | + return Response.Status.NOT_FOUND; | ||
29 | + } | ||
30 | +} |
1 | +/* | ||
2 | + * Copyright 2014 Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.onlab.onos.rest.exceptions; | ||
17 | + | ||
18 | +import javax.ws.rs.core.Response; | ||
19 | + | ||
20 | +/** | ||
21 | + * Mapper for service not found exceptions to the NOT_FOUND response code. | ||
22 | + */ | ||
23 | +public class ServerErrorMapper extends AbstractMapper<RuntimeException> { | ||
24 | + @Override | ||
25 | + protected Response.Status responseStatus() { | ||
26 | + return Response.Status.INTERNAL_SERVER_ERROR; | ||
27 | + } | ||
28 | +} |
1 | +/* | ||
2 | + * Copyright 2014 Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.onlab.onos.rest.exceptions; | ||
17 | + | ||
18 | +import org.onlab.osgi.ServiceNotFoundException; | ||
19 | + | ||
20 | +import javax.ws.rs.core.Response; | ||
21 | + | ||
22 | +/** | ||
23 | + * Mapper for service not found exceptions to the SERVICE_UNAVAILABLE response code. | ||
24 | + */ | ||
25 | +public class ServiceNotFoundMapper extends AbstractMapper<ServiceNotFoundException> { | ||
26 | + @Override | ||
27 | + protected Response.Status responseStatus() { | ||
28 | + return Response.Status.SERVICE_UNAVAILABLE; | ||
29 | + } | ||
30 | +} |
1 | +/* | ||
2 | + * Copyright 2014 Open Networking Laboratory | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +/** | ||
18 | + * Various exception mappers to map errors to proper response status codes. | ||
19 | + */ | ||
20 | +package org.onlab.onos.rest.exceptions; | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
... | @@ -24,8 +24,21 @@ | ... | @@ -24,8 +24,21 @@ |
24 | <servlet-name>JAX-RS Service</servlet-name> | 24 | <servlet-name>JAX-RS Service</servlet-name> |
25 | <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class> | 25 | <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class> |
26 | <init-param> | 26 | <init-param> |
27 | - <param-name>com.sun.jersey.config.property.packages</param-name> | 27 | + <param-name>com.sun.jersey.config.property.resourceConfigClass</param-name> |
28 | - <param-value>org.onlab.onos.rest</param-value> | 28 | + <param-value>com.sun.jersey.api.core.ClassNamesResourceConfig</param-value> |
29 | + </init-param> | ||
30 | + <init-param> | ||
31 | + <param-name>com.sun.jersey.config.property.classnames</param-name> | ||
32 | + <param-value> | ||
33 | + org.onlab.onos.rest.exceptions.EntityNotFoundMapper, | ||
34 | + org.onlab.onos.rest.exceptions.ServiceNotFoundMapper, | ||
35 | + org.onlab.onos.rest.exceptions.ServerErrorMapper, | ||
36 | + org.onlab.onos.rest.JsonBodyWriter, | ||
37 | + | ||
38 | + org.onlab.onos.rest.DevicesWebResource, | ||
39 | + org.onlab.onos.rest.LinksWebResource, | ||
40 | + org.onlab.onos.rest.ConfigResource | ||
41 | + </param-value> | ||
29 | </init-param> | 42 | </init-param> |
30 | <load-on-startup>1</load-on-startup> | 43 | <load-on-startup>1</load-on-startup> |
31 | </servlet> | 44 | </servlet> | ... | ... |
... | @@ -109,6 +109,10 @@ | ... | @@ -109,6 +109,10 @@ |
109 | <plugins> | 109 | <plugins> |
110 | <plugin> | 110 | <plugin> |
111 | <groupId>org.apache.felix</groupId> | 111 | <groupId>org.apache.felix</groupId> |
112 | + <artifactId>maven-scr-plugin</artifactId> | ||
113 | + </plugin> | ||
114 | + <plugin> | ||
115 | + <groupId>org.apache.felix</groupId> | ||
112 | <artifactId>maven-bundle-plugin</artifactId> | 116 | <artifactId>maven-bundle-plugin</artifactId> |
113 | <extensions>true</extensions> | 117 | <extensions>true</extensions> |
114 | <configuration> | 118 | <configuration> |
... | @@ -120,13 +124,15 @@ | ... | @@ -120,13 +124,15 @@ |
120 | <Import-Package> | 124 | <Import-Package> |
121 | org.slf4j, | 125 | org.slf4j, |
122 | org.osgi.framework, | 126 | org.osgi.framework, |
123 | - javax.ws.rs,javax.ws.rs.core, | 127 | + javax.ws.rs,javax.ws.rs.core,javax.ws.rs.ext, |
124 | com.sun.jersey.api.core, | 128 | com.sun.jersey.api.core, |
125 | com.sun.jersey.spi.container.servlet, | 129 | com.sun.jersey.spi.container.servlet, |
126 | com.sun.jersey.server.impl.container.servlet, | 130 | com.sun.jersey.server.impl.container.servlet, |
127 | com.fasterxml.jackson.databind, | 131 | com.fasterxml.jackson.databind, |
128 | com.fasterxml.jackson.databind.node, | 132 | com.fasterxml.jackson.databind.node, |
129 | com.google.common.base.*, | 133 | com.google.common.base.*, |
134 | + org.onlab.api.*, | ||
135 | + org.onlab.osgi.*, | ||
130 | org.onlab.packet.*, | 136 | org.onlab.packet.*, |
131 | org.onlab.rest.*, | 137 | org.onlab.rest.*, |
132 | org.onlab.onos.* | 138 | org.onlab.onos.* | ... | ... |
-
Please register or login to post a comment