xuzhang
Committed by Gerrit Code Review

[ONOS-2247]The implementation of subnet resource service.

Change-Id: I52cbd5c52ce2439122664e8c18b7603e61500d5c
...@@ -14,7 +14,6 @@ ...@@ -14,7 +14,6 @@
14 <artifactId>onos-app-vtnrsc</artifactId> 14 <artifactId>onos-app-vtnrsc</artifactId>
15 <packaging>bundle</packaging> 15 <packaging>bundle</packaging>
16 16
17 -
18 <properties> 17 <properties>
19 <onos.app.name>org.onosproject.vtnrsc</onos.app.name> 18 <onos.app.name>org.onosproject.vtnrsc</onos.app.name>
20 </properties> 19 </properties>
...@@ -41,43 +40,12 @@ ...@@ -41,43 +40,12 @@
41 <groupId>org.apache.karaf.shell</groupId> 40 <groupId>org.apache.karaf.shell</groupId>
42 <artifactId>org.apache.karaf.shell.console</artifactId> 41 <artifactId>org.apache.karaf.shell.console</artifactId>
43 </dependency> 42 </dependency>
43 + <dependency>
44 + <groupId>org.onosproject</groupId>
45 + <artifactId>onlab-junit</artifactId>
46 + <version>${project.version}</version>
47 + </dependency>
44 </dependencies> 48 </dependencies>
45 49
46 - <build>
47 - <plugins>
48 - <plugin>
49 - <groupId>org.apache.felix</groupId>
50 - <artifactId>maven-bundle-plugin</artifactId>
51 - <extensions>true</extensions>
52 - <configuration>
53 - <instructions>
54 - <Bundle-SymbolicName>
55 - ${project.groupId}.${project.artifactId}
56 - </Bundle-SymbolicName>
57 - <Import-Package>
58 - org.slf4j,
59 - org.osgi.framework,
60 - javax.ws.rs,
61 - javax.ws.rs.core,
62 - com.sun.jersey.api.core,
63 - com.sun.jersey.spi.container.servlet,
64 - com.sun.jersey.server.impl.container.servlet,
65 - com.fasterxml.jackson.databind,
66 - com.fasterxml.jackson.databind.node,
67 - com.fasterxml.jackson.core,
68 - org.apache.karaf.shell.commands,
69 - org.apache.commons.lang.math.*,
70 - com.google.common.*,
71 - org.onlab.packet.*,
72 - org.onlab.rest.*,
73 - org.onosproject.*,
74 - org.onlab.util.*,
75 - org.jboss.netty.util.*
76 - </Import-Package>
77 - </instructions>
78 - </configuration>
79 - </plugin>
80 - </plugins>
81 - </build>
82 50
83 </project> 51 </project>
......
...@@ -27,12 +27,12 @@ public interface AllocationPool { ...@@ -27,12 +27,12 @@ public interface AllocationPool {
27 * 27 *
28 * @return startIp 28 * @return startIp
29 */ 29 */
30 - IpAddress startIP(); 30 + IpAddress startIp();
31 31
32 /** 32 /**
33 * The end address for the allocation pool. 33 * The end address for the allocation pool.
34 * 34 *
35 * @return endIp 35 * @return endIp
36 */ 36 */
37 - IpAddress endIP(); 37 + IpAddress endIp();
38 } 38 }
......
1 +/*
2 + * Copyright 2015 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.onosproject.app.vtnrsc;
17 +
18 +import static com.google.common.base.MoreObjects.toStringHelper;
19 +import static com.google.common.base.Preconditions.checkNotNull;
20 +import java.util.Objects;
21 +
22 +import org.onlab.packet.IpAddress;
23 +
24 +/**
25 + * The continuous IP address range between the start address and the end address
26 + * for the allocation pools.
27 + */
28 +public final class DefaultAllocationPool implements AllocationPool {
29 +
30 + private final IpAddress startIp;
31 + private final IpAddress endIp;
32 +
33 + /**
34 + * Creates an AllocationPool by using the start IP address and the end IP
35 + * address.
36 + *
37 + * @param startIp the start IP address of the allocation pool
38 + * @param endIp the end IP address of the allocation pool
39 + */
40 + public DefaultAllocationPool(IpAddress startIp, IpAddress endIp) {
41 + checkNotNull(startIp, "StartIp cannot be null");
42 + checkNotNull(endIp, "EndIp cannot be null");
43 + this.startIp = startIp;
44 + this.endIp = endIp;
45 + }
46 +
47 + @Override
48 + public IpAddress startIp() {
49 + return startIp;
50 + }
51 +
52 + @Override
53 + public IpAddress endIp() {
54 + return endIp;
55 + }
56 +
57 + @Override
58 + public int hashCode() {
59 + return Objects.hash(startIp, endIp);
60 + }
61 +
62 + @Override
63 + public boolean equals(Object obj) {
64 + if (this == obj) {
65 + return true;
66 + }
67 + if (obj instanceof DefaultAllocationPool) {
68 + final DefaultAllocationPool other = (DefaultAllocationPool) obj;
69 + return Objects.equals(this.startIp, other.startIp)
70 + && Objects.equals(this.endIp, other.endIp);
71 + }
72 + return false;
73 + }
74 +
75 + @Override
76 + public String toString() {
77 + return toStringHelper(this).add("startIp", startIp).add("endIp", endIp)
78 + .toString();
79 + }
80 +}
81 +
1 +/*
2 + * Copyright 2015 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.onosproject.app.vtnrsc;
17 +
18 +import static com.google.common.base.MoreObjects.toStringHelper;
19 +
20 +import java.util.Objects;
21 +
22 +import org.onlab.packet.IpAddress;
23 +import org.onlab.packet.IpPrefix;
24 +
25 +/**
26 + * Host route dictionaries for the subnet.
27 + */
28 +public final class DefaultHostRoute implements HostRoute {
29 +
30 + private final IpAddress nexthop;
31 + private final IpPrefix destination;
32 +
33 + /**
34 + *
35 + * Creates a DefaultHostRoute by using the next hop and the destination.
36 + *
37 + * @param nexthop of the DefaultHostRoute
38 + * @param destination of the DefaultHostRoute
39 + */
40 + public DefaultHostRoute(IpAddress nexthop, IpPrefix destination) {
41 + this.nexthop = nexthop;
42 + this.destination = destination;
43 + }
44 +
45 + @Override
46 + public IpAddress nexthop() {
47 + return nexthop;
48 + }
49 +
50 + @Override
51 + public IpPrefix destination() {
52 + return destination;
53 + }
54 +
55 + @Override
56 + public String toString() {
57 + return toStringHelper(this).add("nexthop", nexthop)
58 + .add("destination", destination).toString();
59 + }
60 +
61 + @Override
62 + public int hashCode() {
63 + return Objects.hash(nexthop, destination);
64 + }
65 +
66 + @Override
67 + public boolean equals(Object obj) {
68 + if (this == obj) {
69 + return true;
70 + }
71 + if (obj instanceof DefaultHostRoute) {
72 + final DefaultHostRoute other = (DefaultHostRoute) obj;
73 + return Objects.equals(this.nexthop, other.nexthop)
74 + && Objects.equals(this.destination, other.destination);
75 + }
76 + return false;
77 + }
78 +
79 +}
1 +/*
2 + * Copyright 2015 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.onosproject.app.vtnrsc;
17 +
18 +import static com.google.common.base.MoreObjects.toStringHelper;
19 +
20 +import java.util.Objects;
21 +
22 +import org.onlab.packet.IpAddress;
23 +import org.onlab.packet.IpAddress.Version;
24 +import org.onlab.packet.IpPrefix;
25 +
26 +/**
27 + * Default implementation of Subnet interface .
28 + */
29 +public final class DefaultSubnet implements Subnet {
30 + private final SubnetId id;
31 + private final String subnetName;
32 + private final TenantNetworkId networkId;
33 + private final TenantId tenantId;
34 + private final Version ipVersion;
35 + private final IpPrefix cidr;
36 + private final IpAddress gatewayIp;
37 + private final boolean dhcpEnabled;
38 + private final boolean shared;
39 + private final Mode ipV6AddressMode;
40 + private final Mode ipV6RaMode;
41 + private final Iterable<HostRoute> hostRoutes;
42 + private final Iterable<AllocationPool> allocationPools;
43 +
44 + /**
45 + * Creates a subnet object.
46 + *
47 + * @param id subnet identifier
48 + * @param subnetName the name of subnet
49 + * @param networkId network identifier
50 + * @param tenantId tenant identifier
51 + * @param cidr the cidr
52 + * @param gatewayIp gateway ip
53 + * @param dhcpEnabled dhcp enabled or not
54 + * @param shared indicates whether this network is shared across all
55 + * tenants, By default, only administrative user can change this
56 + * value
57 + * @param hostRoutes a collection of host routes
58 + * @param ipV6AddressMode ipV6AddressMode
59 + * @param ipV6RaMode ipV6RaMode
60 + * @param allocationPoolsIt a collection of allocationPools
61 + */
62 + public DefaultSubnet(SubnetId id, String subnetName,
63 + TenantNetworkId networkId, TenantId tenantId,
64 + Version ipVersion, IpPrefix cidr, IpAddress gatewayIp,
65 + boolean dhcpEnabled, boolean shared,
66 + Iterable<HostRoute> hostRoutes, Mode ipV6AddressMode,
67 + Mode ipV6RaMode,
68 + Iterable<AllocationPool> allocationPoolsIt) {
69 + this.id = id;
70 + this.subnetName = subnetName;
71 + this.networkId = networkId;
72 + this.tenantId = tenantId;
73 + this.ipVersion = ipVersion;
74 + this.cidr = cidr;
75 + this.gatewayIp = gatewayIp;
76 + this.dhcpEnabled = dhcpEnabled;
77 + this.shared = shared;
78 + this.ipV6AddressMode = ipV6AddressMode;
79 + this.ipV6RaMode = ipV6RaMode;
80 + this.hostRoutes = hostRoutes;
81 + this.allocationPools = allocationPoolsIt;
82 + }
83 +
84 + @Override
85 + public SubnetId id() {
86 + return id;
87 + }
88 +
89 + @Override
90 + public String subnetName() {
91 + return subnetName;
92 + }
93 +
94 + @Override
95 + public TenantNetworkId networkId() {
96 + return networkId;
97 + }
98 +
99 + @Override
100 + public TenantId tenantId() {
101 + return tenantId;
102 + }
103 +
104 + @Override
105 + public Version ipVersion() {
106 + return ipVersion;
107 + }
108 +
109 + @Override
110 + public IpPrefix cidr() {
111 + return cidr;
112 + }
113 +
114 + @Override
115 + public IpAddress gatewayIp() {
116 + return gatewayIp;
117 + }
118 +
119 + @Override
120 + public boolean dhcpEnabled() {
121 + return dhcpEnabled;
122 + }
123 +
124 + @Override
125 + public boolean shared() {
126 + return shared;
127 + }
128 +
129 + @Override
130 + public Iterable<HostRoute> hostRoutes() {
131 + return hostRoutes;
132 + }
133 +
134 + @Override
135 + public Mode ipV6AddressMode() {
136 + return ipV6AddressMode;
137 + }
138 +
139 + @Override
140 + public Mode ipV6RaMode() {
141 + return ipV6RaMode;
142 + }
143 +
144 + @Override
145 + public Iterable<AllocationPool> allocationPools() {
146 + return allocationPools;
147 + }
148 +
149 + @Override
150 + public int hashCode() {
151 + return Objects.hash(id, subnetName, ipVersion, cidr, gatewayIp,
152 + dhcpEnabled, shared, tenantId);
153 + }
154 +
155 + @Override
156 + public boolean equals(Object obj) {
157 + if (this == obj) {
158 + return true;
159 + }
160 + if (obj instanceof DefaultSubnet) {
161 + final DefaultSubnet that = (DefaultSubnet) obj;
162 + return Objects.equals(this.id, that.id)
163 + && Objects.equals(this.subnetName, that.subnetName)
164 + && Objects.equals(this.ipVersion, that.ipVersion)
165 + && Objects.equals(this.cidr, that.cidr)
166 + && Objects.equals(this.shared, that.shared)
167 + && Objects.equals(this.gatewayIp, that.gatewayIp)
168 + && Objects.equals(this.dhcpEnabled, that.dhcpEnabled);
169 + }
170 + return false;
171 + }
172 +
173 + @Override
174 + public String toString() {
175 + return toStringHelper(this).add("id", id).add("subnetName", subnetName)
176 + .add("ipVersion", ipVersion).add("cidr", cidr)
177 + .add("shared", shared).add("gatewayIp", gatewayIp)
178 + .add("dhcpEnabled", dhcpEnabled).toString();
179 + }
180 +
181 +}
...@@ -32,9 +32,9 @@ public interface Subnet { ...@@ -32,9 +32,9 @@ public interface Subnet {
32 } 32 }
33 33
34 /** 34 /**
35 - * Returns the ID of the subnet. 35 + * Returns the subnet identifier.
36 * 36 *
37 - * @return id 37 + * @return identifier
38 */ 38 */
39 SubnetId id(); 39 SubnetId id();
40 40
...@@ -46,18 +46,16 @@ public interface Subnet { ...@@ -46,18 +46,16 @@ public interface Subnet {
46 String subnetName(); 46 String subnetName();
47 47
48 /** 48 /**
49 - * Returns the ID of the attached network. 49 + * Returns the network identifier.
50 * 50 *
51 - * @return networkID 51 + * @return the network identifier
52 */ 52 */
53 TenantNetworkId networkId(); 53 TenantNetworkId networkId();
54 54
55 /** 55 /**
56 - * Returns the The ID of the tenant who owns the network. Only 56 + * Returns tenant identifier.
57 - * administrative users can specify a tenant ID other than their own. You
58 - * cannot change this value through authorization policies.
59 * 57 *
60 - * @return tenantID 58 + * @return the tenant identifier
61 */ 59 */
62 TenantId tenantId(); 60 TenantId tenantId();
63 61
...@@ -76,31 +74,31 @@ public interface Subnet { ...@@ -76,31 +74,31 @@ public interface Subnet {
76 IpPrefix cidr(); 74 IpPrefix cidr();
77 75
78 /** 76 /**
79 - * Returns the gateway IP address.. 77 + * Returns the gateway IP address.
80 * 78 *
81 - * @return gatewayIP 79 + * @return gatewayIp
82 */ 80 */
83 IpAddress gatewayIp(); 81 IpAddress gatewayIp();
84 82
85 /** 83 /**
86 * Returns true if DHCP is enabled and return false if DHCP is disabled. 84 * Returns true if DHCP is enabled and return false if DHCP is disabled.
87 * 85 *
88 - * @return dhcpEnabled 86 + * @return true or false
89 */ 87 */
90 boolean dhcpEnabled(); 88 boolean dhcpEnabled();
91 89
92 /** 90 /**
93 * Indicates whether this tenantNetwork is shared across all tenants. By 91 * Indicates whether this tenantNetwork is shared across all tenants. By
94 - * default,only administrative user can change this value. 92 + * default, only administrative user can change this value.
95 * 93 *
96 - * @return shared 94 + * @return true or false
97 */ 95 */
98 boolean shared(); 96 boolean shared();
99 97
100 /** 98 /**
101 - * Returns an iterable collections of hostRoutes. 99 + * Returns a collection of hostRoutes.
102 * 100 *
103 - * @return hostRoutes collection 101 + * @return a collection of hostRoutes
104 */ 102 */
105 Iterable<HostRoute> hostRoutes(); 103 Iterable<HostRoute> hostRoutes();
106 104
...@@ -108,7 +106,8 @@ public interface Subnet { ...@@ -108,7 +106,8 @@ public interface Subnet {
108 * Returns the ipV6AddressMode. A valid value is dhcpv6-stateful, 106 * Returns the ipV6AddressMode. A valid value is dhcpv6-stateful,
109 * dhcpv6-stateless, or slaac. 107 * dhcpv6-stateless, or slaac.
110 * 108 *
111 - * @return ipV6AddressMode 109 + * @return ipV6AddressMode whose value is dhcpv6-stateful, dhcpv6-stateless
110 + * or slaac
112 */ 111 */
113 Mode ipV6AddressMode(); 112 Mode ipV6AddressMode();
114 113
...@@ -116,15 +115,15 @@ public interface Subnet { ...@@ -116,15 +115,15 @@ public interface Subnet {
116 * Returns the ipV6RaMode.A valid value is dhcpv6-stateful, 115 * Returns the ipV6RaMode.A valid value is dhcpv6-stateful,
117 * dhcpv6-stateless, or slaac. 116 * dhcpv6-stateless, or slaac.
118 * 117 *
119 - * @return ipV6RaMode 118 + * @return ipV6RaMode whose value is dhcpv6-stateful, dhcpv6-stateless or
119 + * slaac
120 */ 120 */
121 Mode ipV6RaMode(); 121 Mode ipV6RaMode();
122 122
123 /** 123 /**
124 - * Returns an iterable collection of allocation_pools. 124 + * Returns a collection of allocation_pools.
125 * 125 *
126 - * @return allocationPools collection 126 + * @return a collection of allocationPools
127 */ 127 */
128 -
129 Iterable<AllocationPool> allocationPools(); 128 Iterable<AllocationPool> allocationPools();
130 } 129 }
......
...@@ -20,7 +20,7 @@ import static com.google.common.base.Preconditions.checkNotNull; ...@@ -20,7 +20,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
20 import java.util.Objects; 20 import java.util.Objects;
21 21
22 /** 22 /**
23 - * Immutable representation of a subnet identity. 23 + * Immutable representation of a subnet identifier.
24 */ 24 */
25 public final class SubnetId { 25 public final class SubnetId {
26 26
...@@ -33,15 +33,24 @@ public final class SubnetId { ...@@ -33,15 +33,24 @@ public final class SubnetId {
33 } 33 }
34 34
35 /** 35 /**
36 - * Creates a subnet identifier. 36 + * Creates a Subnet identifier.
37 * 37 *
38 - * @param subnetId subnet identifier 38 + * @param subnetId the subnet identifier
39 - * @return SubnetId SubnetId 39 + * @return the subnet identifier
40 */ 40 */
41 public static SubnetId subnetId(String subnetId) { 41 public static SubnetId subnetId(String subnetId) {
42 return new SubnetId(subnetId); 42 return new SubnetId(subnetId);
43 } 43 }
44 44
45 + /**
46 + * Returns the subnet identifier.
47 + *
48 + * @return the subnet identifier
49 + */
50 + public String subnetId() {
51 + return subnetId;
52 + }
53 +
45 @Override 54 @Override
46 public int hashCode() { 55 public int hashCode() {
47 return Objects.hash(subnetId); 56 return Objects.hash(subnetId);
...@@ -64,5 +73,4 @@ public final class SubnetId { ...@@ -64,5 +73,4 @@ public final class SubnetId {
64 public String toString() { 73 public String toString() {
65 return subnetId; 74 return subnetId;
66 } 75 }
67 -
68 } 76 }
......
1 +/*
2 + * Copyright 2015 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.onosproject.app.vtnrsc.subnet.impl;
17 +
18 +import static com.google.common.base.Preconditions.checkNotNull;
19 +import static org.slf4j.LoggerFactory.getLogger;
20 +
21 +import java.util.Collections;
22 +
23 +import org.apache.felix.scr.annotations.Activate;
24 +import org.apache.felix.scr.annotations.Component;
25 +import org.apache.felix.scr.annotations.Deactivate;
26 +import org.apache.felix.scr.annotations.Reference;
27 +import org.apache.felix.scr.annotations.ReferenceCardinality;
28 +import org.apache.felix.scr.annotations.Service;
29 +import org.onlab.util.KryoNamespace;
30 +import org.onosproject.app.vtnrsc.Subnet;
31 +import org.onosproject.app.vtnrsc.SubnetId;
32 +import org.onosproject.app.vtnrsc.subnet.SubnetService;
33 +import org.onosproject.app.vtnrsc.tenantnetwork.TenantNetworkService;
34 +import org.onosproject.store.service.EventuallyConsistentMap;
35 +import org.onosproject.store.service.MultiValuedTimestamp;
36 +import org.onosproject.store.service.StorageService;
37 +import org.onosproject.store.service.WallClockTimestamp;
38 +import org.slf4j.Logger;
39 +
40 +/**
41 + * Provides implementation of the Subnet service.
42 + */
43 +@Component(immediate = true)
44 +@Service
45 +public class SubnetManager implements SubnetService {
46 +
47 + private static final String SUBNET_ID_NULL = "Subnet ID cannot be null";
48 + private static final String SUBNET_NOT_NULL = "Subnet cannot be null";
49 +
50 + private final Logger log = getLogger(getClass());
51 +
52 + private EventuallyConsistentMap<SubnetId, Subnet> subnetStore;
53 +
54 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
55 + protected StorageService storageService;
56 +
57 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
58 + protected TenantNetworkService tenantNetworkService;
59 +
60 + @Activate
61 + public void activate() {
62 + KryoNamespace.Builder serializer = KryoNamespace.newBuilder()
63 + .register(MultiValuedTimestamp.class);
64 + subnetStore = storageService
65 + .<SubnetId, Subnet>eventuallyConsistentMapBuilder()
66 + .withName("all_subnet").withSerializer(serializer)
67 + .withTimestampProvider((k, v) -> new WallClockTimestamp())
68 + .build();
69 +
70 + log.info("SubnetManager started");
71 + }
72 +
73 + @Deactivate
74 + public void deactivate() {
75 + subnetStore.destroy();
76 + log.info("SubnetManager stopped");
77 + }
78 +
79 + @Override
80 + public Iterable<Subnet> getSubnets() {
81 + return Collections.unmodifiableCollection(subnetStore.values());
82 + }
83 +
84 + @Override
85 + public Subnet getSubnet(SubnetId subnetId) {
86 + checkNotNull(subnetId, SUBNET_ID_NULL);
87 + return subnetStore.get(subnetId);
88 + }
89 +
90 + @Override
91 + public boolean exists(SubnetId subnetId) {
92 + checkNotNull(subnetId, SUBNET_ID_NULL);
93 + return subnetStore.containsKey(subnetId);
94 + }
95 +
96 + @Override
97 + public boolean createSubnets(Iterable<Subnet> subnets) {
98 + checkNotNull(subnets, SUBNET_NOT_NULL);
99 + for (Subnet subnet : subnets) {
100 + if (!tenantNetworkService.exists(subnet.networkId())) {
101 + log.debug("The network identifier that the subnet {} belong to is not exist",
102 + subnet.networkId().toString(), subnet.id().toString());
103 + return false;
104 + }
105 + subnetStore.put(subnet.id(), subnet);
106 + if (!subnetStore.containsKey(subnet.id())) {
107 + log.debug("The identified subnet whose identifier is {} create failed",
108 + subnet.id().toString());
109 + return false;
110 + }
111 + }
112 + return true;
113 + }
114 +
115 + @Override
116 + public boolean updateSubnets(Iterable<Subnet> subnets) {
117 + checkNotNull(subnets, SUBNET_NOT_NULL);
118 + if (subnets != null) {
119 + for (Subnet subnet : subnets) {
120 + if (!subnetStore.containsKey(subnet.id())) {
121 + log.debug("The subnet is not exist whose identifier is {}",
122 + subnet.id().toString());
123 + return false;
124 + }
125 +
126 + subnetStore.put(subnet.id(), subnet);
127 +
128 + if (!subnet.equals(subnetStore.get(subnet.id()))) {
129 + log.debug("The subnet is updated failed whose identifier is {}",
130 + subnet.id().toString());
131 + return false;
132 + }
133 + }
134 + }
135 + return true;
136 + }
137 +
138 + @Override
139 + public boolean removeSubnets(Iterable<SubnetId> subnetIds) {
140 + checkNotNull(subnetIds, SUBNET_ID_NULL);
141 + if (subnetIds != null) {
142 + for (SubnetId subnetId : subnetIds) {
143 + subnetStore.remove(subnetId);
144 + if (subnetStore.containsKey(subnetId)) {
145 + log.debug("The subnet created is failed whose identifier is {}",
146 + subnetId.toString());
147 + return false;
148 + }
149 + }
150 + }
151 + return true;
152 + }
153 +
154 +}
1 +/*
2 + * Copyright 2015 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.onosproject.app.vtnrsc.web;
17 +
18 +import static com.google.common.base.Preconditions.checkNotNull;
19 +
20 +import org.onosproject.app.vtnrsc.AllocationPool;
21 +import org.onosproject.codec.CodecContext;
22 +import org.onosproject.codec.JsonCodec;
23 +
24 +import com.fasterxml.jackson.databind.node.ObjectNode;
25 +
26 +/**
27 + * Subnet AllocationPool codec.
28 + */
29 +public final class AllocationPoolsCodec extends JsonCodec<AllocationPool> {
30 +
31 + @Override
32 + public ObjectNode encode(AllocationPool alocPool, CodecContext context) {
33 + checkNotNull(alocPool, "AllocationPools cannot be null");
34 + ObjectNode result = context.mapper().createObjectNode()
35 + .put("start", alocPool.startIp().toString())
36 + .put("end", alocPool.endIp().toString());
37 + return result;
38 + }
39 +
40 +}
1 +/*
2 + * Copyright 2015 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.onosproject.app.vtnrsc.web;
17 +
18 +import static com.google.common.base.Preconditions.checkNotNull;
19 +
20 +import org.onosproject.codec.CodecContext;
21 +import org.onosproject.codec.JsonCodec;
22 +import org.onosproject.app.vtnrsc.HostRoute;
23 +
24 +import com.fasterxml.jackson.databind.node.ObjectNode;
25 +
26 +/**
27 + * Subnet HostRoute codec.
28 + */
29 +public final class HostRoutesCodec extends JsonCodec<HostRoute> {
30 +
31 + @Override
32 + public ObjectNode encode(HostRoute hostRoute, CodecContext context) {
33 + checkNotNull(hostRoute, "HostRoute cannot be null");
34 + ObjectNode result = context.mapper().createObjectNode()
35 + .put("nexthop", hostRoute.nexthop().toString())
36 + .put("destination", hostRoute.destination().toString());
37 + return result;
38 + }
39 +
40 +}
1 +/*
2 + * Copyright 2015 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.onosproject.app.vtnrsc.web;
17 +
18 +import static com.google.common.base.Preconditions.checkNotNull;
19 +
20 +import org.onosproject.app.vtnrsc.Subnet;
21 +import org.onosproject.codec.CodecContext;
22 +import org.onosproject.codec.JsonCodec;
23 +
24 +import com.fasterxml.jackson.databind.node.ObjectNode;
25 +
26 +/**
27 + * Subnet JSON codec.
28 + */
29 +public final class SubnetCodec extends JsonCodec<Subnet> {
30 + @Override
31 + public ObjectNode encode(Subnet subnet, CodecContext context) {
32 + checkNotNull(subnet, "Subnet cannot be null");
33 + ObjectNode result = context.mapper().createObjectNode()
34 + .put("id", subnet.id().toString())
35 + .put("gate_ip", subnet.gatewayIp().toString())
36 + .put("network_id", subnet.networkId().toString())
37 + .put("name", subnet.subnetName().toString())
38 + .put("ip_version", subnet.ipVersion().toString())
39 + .put("cidr", subnet.cidr().toString())
40 + .put("shared", subnet.shared())
41 + .put("enabled_dchp", subnet.dhcpEnabled())
42 + .put("tenant_id", subnet.tenantId().toString());
43 + result.set("alloction_pools", new AllocationPoolsCodec().encode(subnet
44 + .allocationPools(), context));
45 + result.set("host_routes",
46 + new HostRoutesCodec().encode(subnet.hostRoutes(), context));
47 + return result;
48 + }
49 +}
1 +/*
2 + * Copyright 2015 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.onosproject.vtnweb.resources;
17 +
18 +import static com.google.common.base.Preconditions.checkNotNull;
19 +import static javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR;
20 +
21 +import java.io.IOException;
22 +import java.io.InputStream;
23 +import java.util.Collections;
24 +import java.util.HashMap;
25 +import java.util.HashSet;
26 +import java.util.Map;
27 +import java.util.Set;
28 +import java.util.concurrent.ConcurrentMap;
29 +
30 +import javax.ws.rs.Consumes;
31 +import javax.ws.rs.DELETE;
32 +import javax.ws.rs.GET;
33 +import javax.ws.rs.POST;
34 +import javax.ws.rs.PUT;
35 +import javax.ws.rs.Path;
36 +import javax.ws.rs.PathParam;
37 +import javax.ws.rs.Produces;
38 +import javax.ws.rs.core.MediaType;
39 +import javax.ws.rs.core.Response;
40 +
41 +import org.onlab.packet.IpAddress;
42 +import org.onlab.packet.IpAddress.Version;
43 +import org.onlab.packet.IpPrefix;
44 +import org.onlab.util.ItemNotFoundException;
45 +import org.onosproject.app.vtnrsc.AllocationPool;
46 +import org.onosproject.app.vtnrsc.DefaultAllocationPool;
47 +import org.onosproject.app.vtnrsc.DefaultHostRoute;
48 +import org.onosproject.app.vtnrsc.DefaultSubnet;
49 +import org.onosproject.app.vtnrsc.HostRoute;
50 +import org.onosproject.app.vtnrsc.Subnet;
51 +import org.onosproject.app.vtnrsc.Subnet.Mode;
52 +import org.onosproject.app.vtnrsc.SubnetId;
53 +import org.onosproject.app.vtnrsc.TenantId;
54 +import org.onosproject.app.vtnrsc.TenantNetworkId;
55 +import org.onosproject.app.vtnrsc.subnet.SubnetService;
56 +import org.onosproject.app.vtnrsc.web.SubnetCodec;
57 +import org.onosproject.rest.AbstractWebResource;
58 +import org.slf4j.Logger;
59 +import org.slf4j.LoggerFactory;
60 +
61 +import com.fasterxml.jackson.databind.JsonNode;
62 +import com.fasterxml.jackson.databind.ObjectMapper;
63 +import com.fasterxml.jackson.databind.node.ObjectNode;
64 +import com.google.common.collect.Maps;
65 +
66 +@Path("subnets")
67 +public class SubnetWebResource extends AbstractWebResource {
68 + private final Logger log = LoggerFactory.getLogger(SubnetWebResource.class);
69 + public static final String SUBNET_NOT_CREATE = "Subnets is failed to create!";
70 + public static final String SUBNET_NOT_FOUND = "Subnets is failed to update!";
71 + public static final String JSON_NOT_NULL = "JsonNode can not be null";
72 +
73 + @GET
74 + @Produces(MediaType.APPLICATION_JSON)
75 + public Response listSubnets() {
76 + Iterable<Subnet> subnets = get(SubnetService.class).getSubnets();
77 + ObjectNode result = new ObjectMapper().createObjectNode();
78 + result.set("subnets", new SubnetCodec().encode(subnets, this));
79 + return ok(result.toString()).build();
80 + }
81 +
82 + @GET
83 + @Path("{subnetUUID}")
84 + @Produces(MediaType.APPLICATION_JSON)
85 + public Response getSubnet(@PathParam("subnetUUID") String id) {
86 +
87 + if (!get(SubnetService.class).exists(SubnetId.subnetId(id))) {
88 + return ok("the subnet does not exists").build();
89 + }
90 + Subnet sub = nullIsNotFound(get(SubnetService.class)
91 + .getSubnet(SubnetId.subnetId(id)),
92 + SUBNET_NOT_FOUND);
93 +
94 + ObjectNode result = new ObjectMapper().createObjectNode();
95 + result.set("subnet", new SubnetCodec().encode(sub, this));
96 + return ok(result.toString()).build();
97 + }
98 +
99 + @POST
100 + @Produces(MediaType.APPLICATION_JSON)
101 + @Consumes(MediaType.APPLICATION_JSON)
102 + public Response createSubnet(final InputStream input) {
103 +
104 + try {
105 + ObjectMapper mapper = new ObjectMapper();
106 + JsonNode subnode = mapper.readTree(input);
107 + Iterable<Subnet> subnets = createOrUpdateByInputStream(subnode);
108 + Boolean result = nullIsNotFound((get(SubnetService.class)
109 + .createSubnets(subnets)),
110 + SUBNET_NOT_CREATE);
111 +
112 + if (!result) {
113 + return Response.status(204).entity(SUBNET_NOT_CREATE).build();
114 + }
115 + return Response.status(202).entity(result.toString()).build();
116 + } catch (Exception e) {
117 + return Response.status(INTERNAL_SERVER_ERROR).entity(e.toString())
118 + .build();
119 + }
120 + }
121 +
122 + @PUT
123 + @Path("{subnetUUID}")
124 + @Produces(MediaType.APPLICATION_JSON)
125 + @Consumes(MediaType.APPLICATION_JSON)
126 + public Response updateSubnet(@PathParam("id") String id,
127 + final InputStream input) {
128 + try {
129 + ObjectMapper mapper = new ObjectMapper();
130 + JsonNode subnode = mapper.readTree(input);
131 + Iterable<Subnet> subnets = createOrUpdateByInputStream(subnode);
132 + Boolean result = nullIsNotFound(get(SubnetService.class)
133 + .updateSubnets(subnets), SUBNET_NOT_FOUND);
134 + if (!result) {
135 + return Response.status(204).entity(SUBNET_NOT_FOUND).build();
136 + }
137 + return Response.status(203).entity(result.toString()).build();
138 + } catch (Exception e) {
139 + return Response.status(INTERNAL_SERVER_ERROR).entity(e.toString())
140 + .build();
141 + }
142 + }
143 +
144 + @Path("{subnetUUID}")
145 + @DELETE
146 + public Response deleteSingleSubnet(@PathParam("subnetUUID") String id)
147 + throws IOException {
148 + try {
149 + SubnetId subId = SubnetId.subnetId(id);
150 + Set<SubnetId> subIds = new HashSet<SubnetId>();
151 + subIds.add(subId);
152 + get(SubnetService.class).removeSubnets(subIds);
153 + return Response.status(201).entity("SUCCESS").build();
154 + } catch (Exception e) {
155 + return Response.status(INTERNAL_SERVER_ERROR).entity(e.toString())
156 + .build();
157 + }
158 + }
159 +
160 + private Iterable<Subnet> createOrUpdateByInputStream(JsonNode subnode) {
161 + checkNotNull(subnode, JSON_NOT_NULL);
162 + Iterable<Subnet> subnets = null;
163 + JsonNode subnetNodes = subnode.get("subnets");
164 + if (subnetNodes == null) {
165 + subnetNodes = subnode.get("subnet");
166 + }
167 + log.debug("subnetNodes is {}", subnetNodes.toString());
168 + if (subnetNodes.isArray()) {
169 + subnets = changeJsonToSubs(subnetNodes);
170 + } else {
171 + subnets = changeJsonToSub(subnetNodes);
172 + }
173 + return subnets;
174 + }
175 +
176 + /**
177 + * Returns a collection of subnets from subnetNodes.
178 + *
179 + * @param subnetNodes the subnet json node
180 + * @return subnets a collection of subnets
181 + */
182 + public Iterable<Subnet> changeJsonToSubs(JsonNode subnetNodes) {
183 + checkNotNull(subnetNodes, JSON_NOT_NULL);
184 + Map<SubnetId, Subnet> subMap = new HashMap<SubnetId, Subnet>();
185 + for (JsonNode subnetNode : subnetNodes) {
186 + if (subnetNode.hasNonNull("id")) {
187 + return null;
188 + }
189 + SubnetId id = SubnetId.subnetId(subnetNode.get("id").asText());
190 + String subnetName = subnetNode.get("name").asText();
191 + TenantId tenantId = TenantId.tenantId(subnetNode.get("tenant_id")
192 + .asText());
193 + TenantNetworkId networkId = TenantNetworkId.networkId(subnetNode
194 + .get("network_id").asText());
195 + Version ipVersion = Version.valueOf(subnetNode.get("ip_version")
196 + .asText());
197 + IpPrefix cidr = IpPrefix.valueOf(subnetNode.get("cidr").asText());
198 + IpAddress gatewayIp = IpAddress.valueOf(subnetNode
199 + .get("gateway_ip").asText());
200 + Boolean dhcpEnabled = subnetNode.get("enable_dhcp").asBoolean();
201 + Boolean shared = subnetNode.get("shared").asBoolean();
202 + JsonNode hostRoutes = subnetNode.get("host_routes");
203 + Iterable<HostRoute> hostRoutesIt = jsonNodeToHostRoutes(hostRoutes);
204 + JsonNode allocationPools = subnetNode.get("allocation_pools");
205 + Iterable<AllocationPool> allocationPoolsIt = jsonNodeToAllocationPools(allocationPools);
206 + Mode ipV6AddressMode = Mode.valueOf(subnetNode
207 + .get("ipv6_address_mode").asText());
208 + Mode ipV6RaMode = Mode.valueOf(subnetNode.get("ipv6_ra_mode")
209 + .asText());
210 + Subnet subnet = new DefaultSubnet(id, subnetName, networkId,
211 + tenantId, ipVersion, cidr,
212 + gatewayIp, dhcpEnabled, shared,
213 + hostRoutesIt, ipV6AddressMode,
214 + ipV6RaMode, allocationPoolsIt);
215 + subMap.put(id, subnet);
216 + }
217 + return Collections.unmodifiableCollection(subMap.values());
218 + }
219 +
220 + /**
221 + * Returns a collection of subnets from subnetNodes.
222 + *
223 + * @param subnetNodes the subnet json node
224 + * @return subnets a collection of subnets
225 + */
226 + public Iterable<Subnet> changeJsonToSub(JsonNode subnetNodes) {
227 + checkNotNull(subnetNodes, JSON_NOT_NULL);
228 + Map<SubnetId, Subnet> subMap = new HashMap<SubnetId, Subnet>();
229 + SubnetId id = SubnetId.subnetId(subnetNodes.get("id").asText());
230 + String subnetName = subnetNodes.get("name").asText();
231 + TenantId tenantId = TenantId.tenantId(subnetNodes.get("tenant_id")
232 + .asText());
233 + TenantNetworkId networkId = TenantNetworkId.networkId(subnetNodes
234 + .get("network_id").asText());
235 + Version ipVersion = Version.valueOf(subnetNodes.get("ip_version")
236 + .asText());
237 + IpPrefix cidr = IpPrefix.valueOf(subnetNodes.get("cidr").asText());
238 + IpAddress gatewayIp = IpAddress.valueOf(subnetNodes.get("gateway_ip")
239 + .asText());
240 + Boolean dhcpEnabled = subnetNodes.get("enable_dhcp").asBoolean();
241 + Boolean shared = subnetNodes.get("shared").asBoolean();
242 + JsonNode hostRoutes = subnetNodes.get("host_routes");
243 + Iterable<HostRoute> hostRoutesIt = jsonNodeToHostRoutes(hostRoutes);
244 + JsonNode allocationPools = subnetNodes.get("allocation_pools");
245 + Iterable<AllocationPool> allocationPoolsIt = jsonNodeToAllocationPools(allocationPools);
246 + Mode ipV6AddressMode = Mode.valueOf(subnetNodes
247 + .get("ipv6_address_mode").asText());
248 + Mode ipV6RaMode = Mode
249 + .valueOf(subnetNodes.get("ipv6_ra_mode").asText());
250 + Subnet subnet = new DefaultSubnet(id, subnetName, networkId, tenantId,
251 + ipVersion, cidr, gatewayIp,
252 + dhcpEnabled, shared, hostRoutesIt,
253 + ipV6AddressMode, ipV6RaMode,
254 + allocationPoolsIt);
255 + subMap.put(id, subnet);
256 + return Collections.unmodifiableCollection(subMap.values());
257 + }
258 +
259 + /**
260 + * Changes JsonNode alocPools to a collection of the alocPools.
261 + *
262 + * @param allocationPools the allocationPools JsonNode
263 + * @return a collection of allocationPools
264 + */
265 + public Iterable<AllocationPool> jsonNodeToAllocationPools(JsonNode allocationPools) {
266 + checkNotNull(allocationPools, JSON_NOT_NULL);
267 + ConcurrentMap<Integer, AllocationPool> alocplMaps = Maps
268 + .newConcurrentMap();
269 + Integer i = 0;
270 + for (JsonNode node : allocationPools) {
271 + IpAddress startIp = IpAddress.valueOf(node.get("start").asText());
272 + IpAddress endIp = IpAddress.valueOf(node.get("end").asText());
273 + AllocationPool alocPls = new DefaultAllocationPool(startIp, endIp);
274 + alocplMaps.putIfAbsent(i, alocPls);
275 + i++;
276 + }
277 + return Collections.unmodifiableCollection(alocplMaps.values());
278 + }
279 +
280 + /**
281 + * Changes hostRoutes JsonNode to a collection of the hostRoutes.
282 + *
283 + * @param hostRoutes the hostRoutes json node
284 + * @return a collection of hostRoutes
285 + */
286 + public Iterable<HostRoute> jsonNodeToHostRoutes(JsonNode hostRoutes) {
287 + checkNotNull(hostRoutes, JSON_NOT_NULL);
288 + ConcurrentMap<Integer, HostRoute> hostRouteMaps = Maps
289 + .newConcurrentMap();
290 + Integer i = 0;
291 + for (JsonNode node : hostRoutes) {
292 + IpAddress nexthop = IpAddress.valueOf(node.get("nexthop").asText());
293 + IpPrefix destination = IpPrefix.valueOf(node.get("destination")
294 + .asText());
295 + HostRoute hostRoute = new DefaultHostRoute(nexthop, destination);
296 + hostRouteMaps.putIfAbsent(i, hostRoute);
297 + i++;
298 + }
299 + return Collections.unmodifiableCollection(hostRouteMaps.values());
300 + }
301 +
302 + /**
303 + * Returns the specified item if that items is null; otherwise throws not
304 + * found exception.
305 + *
306 + * @param item item to check
307 + * @param <T> item type
308 + * @param message not found message
309 + * @return item if not null
310 + * @throws org.onlab.util.ItemNotFoundException if item is null
311 + */
312 + protected <T> T nullIsNotFound(T item, String message) {
313 + if (item == null) {
314 + throw new ItemNotFoundException(message);
315 + }
316 + return item;
317 + }
318 +
319 +}
...@@ -30,7 +30,9 @@ ...@@ -30,7 +30,9 @@
30 <init-param> 30 <init-param>
31 <param-name>com.sun.jersey.config.property.classnames</param-name> 31 <param-name>com.sun.jersey.config.property.classnames</param-name>
32 <param-value> 32 <param-value>
33 - org.onosproject.vtnweb.resources.TenantNetworkWebResource 33 + org.onosproject.vtnweb.resources.TenantNetworkWebResource,
34 + org.onosproject.vtnweb.resources.SubnetWebResource,
35 + org.onosproject.vtnweb.resources.VirtualPortWebResource
34 </param-value> 36 </param-value>
35 </init-param> 37 </init-param>
36 <load-on-startup>1</load-on-startup> 38 <load-on-startup>1</load-on-startup>
......