diff options
Diffstat (limited to 'framework/src/onos/apps')
193 files changed, 12620 insertions, 542 deletions
diff --git a/framework/src/onos/apps/cpman/pom.xml b/framework/src/onos/apps/cpman/pom.xml new file mode 100644 index 00000000..c01af6d8 --- /dev/null +++ b/framework/src/onos/apps/cpman/pom.xml @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright 2014 Open Networking Laboratory + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.onosproject</groupId> + <artifactId>onos-apps</artifactId> + <version>1.4.0-SNAPSHOT</version> + <relativePath>../pom.xml</relativePath> + </parent> + + <artifactId>onos-app-cpman</artifactId> + <packaging>bundle</packaging> + + <description>Control Plane Management Application</description> + + <dependencies> + <dependency> + <groupId>org.onosproject</groupId> + <artifactId>onos-api</artifactId> + <version>1.4.0-SNAPSHOT</version> + </dependency> + </dependencies> +</project> diff --git a/framework/src/onos/apps/cpman/src/main/java/org/onosproject/cpman/ControlMessageType.java b/framework/src/onos/apps/cpman/src/main/java/org/onosproject/cpman/ControlMessageType.java new file mode 100644 index 00000000..82e414d9 --- /dev/null +++ b/framework/src/onos/apps/cpman/src/main/java/org/onosproject/cpman/ControlMessageType.java @@ -0,0 +1,43 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.cpman; + +/** + * Abstracted Control Message Type. + */ +public enum ControlMessageType { + + /** Mapped to PACKET-IN message of OpenFlow. */ + INBOUND_PACKET, + + /** Mapped to PACKET-OUT message of OpenFlow. */ + OUTBOUND_PACKET, + + /** Mapped to FLOW-MOD message of OpenFlow. */ + FLOW_MOD_PACKET, + + /** Mapped to FLOW-REMOVED message of OpenFlow. */ + FLOW_REMOVED_PACKET, + + /** Mapped to STATS-REQUEST message of OpenFlow. */ + REQUEST_PACKET, + + /** Mapped to STATS-REPLY message of OpenFlow. */ + REPLY_PACKET, + + /** All message types. */ + ALL +} diff --git a/framework/src/onos/apps/cpman/src/main/java/org/onosproject/cpman/ControlMetricType.java b/framework/src/onos/apps/cpman/src/main/java/org/onosproject/cpman/ControlMetricType.java new file mode 100644 index 00000000..b5e82811 --- /dev/null +++ b/framework/src/onos/apps/cpman/src/main/java/org/onosproject/cpman/ControlMetricType.java @@ -0,0 +1,34 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.cpman; + +/** + * A set of metric type used in control plane. + */ +public enum ControlMetricType { + + /** Racket Rate of Control Message. */ + PacketRate, + + /** Byte Rate of Control Message. */ + ByteRate, + + /** Cpu Utilization. */ + CpuInfo, + + /** Memory Utilization. */ + MemoryInfo +} diff --git a/framework/src/onos/apps/cpman/src/main/java/org/onosproject/cpman/ControlPlaneLoad.java b/framework/src/onos/apps/cpman/src/main/java/org/onosproject/cpman/ControlPlaneLoad.java new file mode 100644 index 00000000..f55945fd --- /dev/null +++ b/framework/src/onos/apps/cpman/src/main/java/org/onosproject/cpman/ControlPlaneLoad.java @@ -0,0 +1,42 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.cpman; + +import org.onosproject.net.statistic.Load; + +import java.util.concurrent.TimeUnit; + +/** + * Data repository for control plane load information. + */ +public interface ControlPlaneLoad extends Load { + + /** + * Obtain the average of the specified time duration. + * + * @param duration time duration + * @param unit time unit + * @return average control plane metric value + */ + long average(int duration, TimeUnit unit); + + /** + * Obtain the average of all time duration. + * + * @return average control plane metric value + */ + long average(); +} diff --git a/framework/src/onos/apps/cpman/src/main/java/org/onosproject/cpman/ControlPlaneManager.java b/framework/src/onos/apps/cpman/src/main/java/org/onosproject/cpman/ControlPlaneManager.java new file mode 100644 index 00000000..5f3dee73 --- /dev/null +++ b/framework/src/onos/apps/cpman/src/main/java/org/onosproject/cpman/ControlPlaneManager.java @@ -0,0 +1,47 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.cpman; + +import com.sun.jndi.toolkit.ctx.ComponentContext; +import org.apache.felix.scr.annotations.Activate; +import org.apache.felix.scr.annotations.Deactivate; +import org.apache.felix.scr.annotations.Modified; +import org.slf4j.Logger; + +import static org.slf4j.LoggerFactory.getLogger; + +/** + * Control plane management application. + */ +public class ControlPlaneManager { + + private final Logger log = getLogger(getClass()); + + @Activate + public void activate(ComponentContext context) { + + } + + @Deactivate + public void deactivate() { + + } + + @Modified + public void modified(ComponentContext context) { + + } +}
\ No newline at end of file diff --git a/framework/src/onos/apps/cpman/src/main/java/org/onosproject/cpman/ControlPlaneMetric.java b/framework/src/onos/apps/cpman/src/main/java/org/onosproject/cpman/ControlPlaneMetric.java new file mode 100644 index 00000000..19f4153a --- /dev/null +++ b/framework/src/onos/apps/cpman/src/main/java/org/onosproject/cpman/ControlPlaneMetric.java @@ -0,0 +1,41 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.cpman; + +/** + * Include various control plane metrics. + */ +public class ControlPlaneMetric { + + private ControlMetricType metricType; + private long metricValue; + + ControlMetricType metricType() { + return metricType; + } + + void setMetricType(ControlMetricType metricType) { + this.metricType = metricType; + } + + long metricValue() { + return metricValue; + } + + void setMetricValue(long metricValue) { + this.metricValue = metricValue; + } +} diff --git a/framework/src/onos/apps/cpman/src/main/java/org/onosproject/cpman/ControlPlaneStatsService.java b/framework/src/onos/apps/cpman/src/main/java/org/onosproject/cpman/ControlPlaneStatsService.java new file mode 100644 index 00000000..9fc2d7a9 --- /dev/null +++ b/framework/src/onos/apps/cpman/src/main/java/org/onosproject/cpman/ControlPlaneStatsService.java @@ -0,0 +1,59 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.cpman; + +import org.onosproject.cluster.NodeId; +import org.onosproject.net.DeviceId; + +import java.util.Optional; +import java.util.concurrent.TimeUnit; + +/** + * Control Plane Statistics Service Interface. + */ +public interface ControlPlaneStatsService { + + /** + * Add a new control plane metric value with a certain update interval. + * + * @param cpm control plane metric (e.g., control message rate, cpu, memory, etc.) + * @param updateInterval value update interval (time unit will be in minute) + */ + void updateMetric(ControlPlaneMetric cpm, int updateInterval); + + /** + * Obtain the control plane load of a specific device. + * + * @param nodeId node id {@link org.onosproject.cluster.NodeId} + * @param type control metric type + * @param deviceId device id {@link org.onosproject.net.DeviceId} + * @return control plane load + */ + ControlPlaneLoad getLoad(NodeId nodeId, ControlMetricType type, Optional<DeviceId> deviceId); + + /** + * Obtain the control plane load of a specific device with a specific time duration. + * + * @param nodeId node id {@link org.onosproject.cluster.NodeId} + * @param type control metric type + * @param duration time duration + * @param unit time unit + * @param deviceId device id {@link org.onosproject.net.Device} + * @return control plane load + */ + ControlPlaneLoad getLoad(NodeId nodeId, ControlMetricType type, Optional<DeviceId> deviceId, + int duration, TimeUnit unit); +}
\ No newline at end of file diff --git a/framework/src/onos/apps/cpman/src/main/java/org/onosproject/cpman/package-info.java b/framework/src/onos/apps/cpman/src/main/java/org/onosproject/cpman/package-info.java new file mode 100644 index 00000000..e2c1dc85 --- /dev/null +++ b/framework/src/onos/apps/cpman/src/main/java/org/onosproject/cpman/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Application for control plane management. + */ +package org.onosproject.cpman;
\ No newline at end of file diff --git a/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/rest/DhcpWebResource.java b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/rest/DhcpWebResource.java index cd8149ea..6265fee0 100644 --- a/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/rest/DhcpWebResource.java +++ b/framework/src/onos/apps/dhcp/app/src/main/java/org/onosproject/dhcp/rest/DhcpWebResource.java @@ -51,7 +51,7 @@ public class DhcpWebResource extends AbstractWebResource { * Shows lease, renewal and rebinding times in seconds. * * @return 200 OK - * @rsModel DhcpConfigGet + * @onos.rsModel DhcpConfigGet */ @GET @Path("config") @@ -68,7 +68,7 @@ public class DhcpWebResource extends AbstractWebResource { * Get all MAC/IP mappings. * Shows all MAC/IP mappings held by the DHCP server. * - * @rsModel DhcpConfigGetMappings + * @onos.rsModel DhcpConfigGetMappings * @return 200 OK */ @GET @@ -90,7 +90,7 @@ public class DhcpWebResource extends AbstractWebResource { * Get all available IPs. * Shows all the IPs in the free pool of the DHCP Server. * - * @rsModel DhcpConfigGetAvailable + * @onos.rsModel DhcpConfigGetAvailable * @return 200 OK */ @GET @@ -108,7 +108,7 @@ public class DhcpWebResource extends AbstractWebResource { * Post a new static MAC/IP binding. * Registers a static binding to the DHCP server, and displays the current set of bindings. * - * @rsModel DhcpConfigPut + * @onos.rsModel DhcpConfigPut * @param stream JSON stream * @return 200 OK */ diff --git a/framework/src/onos/apps/faultmanagement/app/app.xml b/framework/src/onos/apps/faultmanagement/app/app.xml new file mode 100644 index 00000000..288ccc49 --- /dev/null +++ b/framework/src/onos/apps/faultmanagement/app/app.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright 2015 Open Networking Laboratory + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> +<app name="org.onosproject.faultmanagement" origin="BTI Systems" version="${project.version}" + featuresRepo="mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features" + features="${project.artifactId}"> + <description>${project.description}</description> + + <artifact>mvn:${project.groupId}/onos-app-fm-mgr/${project.version}</artifact> + <artifact>mvn:${project.groupId}/onos-app-fm-web/${project.version}</artifact> +</app> diff --git a/framework/src/onos/apps/faultmanagement/app/features.xml b/framework/src/onos/apps/faultmanagement/app/features.xml new file mode 100644 index 00000000..86aab911 --- /dev/null +++ b/framework/src/onos/apps/faultmanagement/app/features.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<!-- + ~ Copyright 2015 Open Networking Laboratory + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> +<features xmlns="http://karaf.apache.org/xmlns/features/v1.2.0" name="${project.artifactId}-${project.version}"> + <feature name="${project.artifactId}" version="${project.version}" + description="${project.description}"> + <feature>onos-api</feature> + <feature>onos-drivers</feature> + <bundle>mvn:${project.groupId}/onos-app-fm-mgr/${project.version}</bundle> + <bundle>mvn:${project.groupId}/onos-app-fm-web/${project.version}</bundle> + </feature> +</features> diff --git a/framework/src/onos/apps/faultmanagement/app/pom.xml b/framework/src/onos/apps/faultmanagement/app/pom.xml new file mode 100644 index 00000000..ef41cdde --- /dev/null +++ b/framework/src/onos/apps/faultmanagement/app/pom.xml @@ -0,0 +1,46 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright 2015 Open Networking Laboratory + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.onosproject</groupId> + <artifactId>onos-app-fm</artifactId> + <version>1.4.0-SNAPSHOT</version> + <relativePath>../pom.xml</relativePath> + </parent> + + <artifactId>onos-app-fm-onosfw</artifactId> + <packaging>pom</packaging> + + <description>ONOS framework applications</description> + + <dependencies> + <dependency> + <groupId>org.onosproject</groupId> + <artifactId>onos-app-fm-web</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.onosproject</groupId> + <artifactId>onos-app-fm-mgr</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + +</project> diff --git a/framework/src/onos/apps/faultmanagement/fmmgr/pom.xml b/framework/src/onos/apps/faultmanagement/fmmgr/pom.xml new file mode 100644 index 00000000..86b7cb67 --- /dev/null +++ b/framework/src/onos/apps/faultmanagement/fmmgr/pom.xml @@ -0,0 +1,54 @@ +<?xml version="1.0"?> +<!-- + ~ Copyright 2015 Open Networking Laboratory + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> +<project + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" + xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.onosproject</groupId> + <artifactId>onos-app-fm</artifactId> + <version>1.4.0-SNAPSHOT</version> + <relativePath>../pom.xml</relativePath> + </parent> + + <artifactId>onos-app-fm-mgr</artifactId> + <packaging>bundle</packaging> + + <dependencies> + <dependency> + <groupId>javax.ws.rs</groupId> + <artifactId>jsr311-api</artifactId> + <version>1.1.1</version> + </dependency> + <dependency> + <groupId>org.onosproject</groupId> + <artifactId>onos-incubator-api</artifactId> + </dependency> + <dependency> + <groupId>org.onosproject</groupId> + <artifactId>onos-core-serializers</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.osgi</groupId> + <artifactId>org.osgi.compendium</artifactId> + <version>5.0.0</version> + <type>jar</type> + </dependency> + </dependencies> +</project> diff --git a/framework/src/onos/apps/faultmanagement/fmmgr/src/main/java/org/onosproject/faultmanagement/impl/AlarmsManager.java b/framework/src/onos/apps/faultmanagement/fmmgr/src/main/java/org/onosproject/faultmanagement/impl/AlarmsManager.java new file mode 100644 index 00000000..74fe7072 --- /dev/null +++ b/framework/src/onos/apps/faultmanagement/fmmgr/src/main/java/org/onosproject/faultmanagement/impl/AlarmsManager.java @@ -0,0 +1,222 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.faultmanagement.impl; + +import static com.google.common.base.Strings.isNullOrEmpty; +import java.util.Dictionary; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicLong; +import org.apache.felix.scr.annotations.Activate; +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Deactivate; +import org.apache.felix.scr.annotations.Modified; +import org.apache.felix.scr.annotations.Property; +import static org.onlab.util.Tools.nullIsNotFound; + +import org.onosproject.incubator.net.faultmanagement.alarm.Alarm; +import org.onosproject.incubator.net.faultmanagement.alarm.AlarmEntityId; +import org.onosproject.incubator.net.faultmanagement.alarm.AlarmEvent; +import org.onosproject.incubator.net.faultmanagement.alarm.AlarmId; +import org.onosproject.incubator.net.faultmanagement.alarm.AlarmListener; +import org.onosproject.incubator.net.faultmanagement.alarm.AlarmService; +import org.onosproject.net.ConnectPoint; +import org.onosproject.net.DeviceId; +import org.slf4j.Logger; +import static org.slf4j.LoggerFactory.getLogger; +import org.apache.felix.scr.annotations.Service; +import static org.onlab.util.Tools.get; +import org.onosproject.core.ApplicationId; +import org.onosproject.core.IdGenerator; +import org.onosproject.core.CoreService; +import org.apache.felix.scr.annotations.Reference; +import org.apache.felix.scr.annotations.ReferenceCardinality; +import org.onlab.util.ItemNotFoundException; +import org.onosproject.incubator.net.faultmanagement.alarm.DefaultAlarm; +import org.osgi.service.component.ComponentContext; + +/** + * Implementation of the Alarm service. + */ +@Component(immediate = true) +@Service +public class AlarmsManager implements AlarmService { + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected CoreService coreService; + private final Logger log = getLogger(getClass()); + private ApplicationId appId; + private IdGenerator idGenerator; + + + @Property(name = "fmDevices", value = "127.0.0.1", label = "Instance-specific configurations") + private String devConfigs; + + private final Map<AlarmId, Alarm> alarms = new ConcurrentHashMap<>(); + + + private final AtomicLong alarmIdGenerator = new AtomicLong(0); + + @Override + public Alarm update(final Alarm replacement) { + + final Alarm found = alarms.get(replacement.id()); + if (found == null) { + throw new ItemNotFoundException("Alarm with id " + replacement.id() + " found"); + } + final Alarm updated = new DefaultAlarm.Builder(found). + withAcknowledged(replacement.acknowledged()). + withAssignedUser(replacement.assignedUser()).build(); + alarms.put(replacement.id(), updated); + return updated; + } + + @Override + public int getActiveAlarmCount(final DeviceId deviceId) { + //TODO + throw new UnsupportedOperationException(NOT_SUPPORTED_YET); + } + private static final String NOT_SUPPORTED_YET = "Not supported yet."; + + @Override + public Alarm getAlarm(final AlarmId alarmId) { + return nullIsNotFound( + alarms.get(alarmId), + "Alarm is not found"); + } + + @Override + public Set<Alarm> getAlarms() { + //TODO + throw new UnsupportedOperationException(NOT_SUPPORTED_YET); + } + + @Override + public Set<Alarm> getActiveAlarms() { + // Enpty set if no values + return alarms.isEmpty() ? new HashSet<>() : new HashSet<>(alarms.values()); + + } + + private static DefaultAlarm generateFake(final DeviceId deviceId, final AlarmId alarmId) { + + return new DefaultAlarm.Builder( + alarmId, deviceId, "NE is not reachable", Alarm.SeverityLevel.MAJOR, System.currentTimeMillis()). + withTimeUpdated(System.currentTimeMillis()). + withServiceAffecting(true) + .withAcknowledged(true). + withManuallyClearable(true) + .withAssignedUser("user1").build(); + } + + @Override + public Set<Alarm> getAlarms(final Alarm.SeverityLevel severity) { + //TODO + throw new UnsupportedOperationException(NOT_SUPPORTED_YET); + } + + @Override + public Set<Alarm> getAlarms(final DeviceId deviceId) { + //TODO + throw new UnsupportedOperationException(NOT_SUPPORTED_YET); + } + + @Override + public Set<Alarm> getAlarms(final DeviceId deviceId, final AlarmEntityId source) { + //TODO + throw new UnsupportedOperationException(NOT_SUPPORTED_YET); + } + + @Override + public Set<Alarm> getAlarmsForLink(final ConnectPoint src, final ConnectPoint dst) { + //TODO + throw new UnsupportedOperationException(NOT_SUPPORTED_YET); + } + + @Override + public Set<Alarm> getAlarmsForFlow(final DeviceId deviceId, final long flowId) { + //TODO + throw new UnsupportedOperationException(NOT_SUPPORTED_YET); + } + + private void discoverAlarmsForDevice(final DeviceId deviceId) { + final AlarmId alarmId = new AlarmId(alarmIdGenerator.incrementAndGet()); + + // TODO In a new thread invoke SNMP Provider with DeviceId and device type and when done update our of alarms + // + alarms.put(alarmId, generateFake(deviceId, alarmId)); + + } + + private class InternalAlarmListener implements AlarmListener { + + @Override + public void event(final AlarmEvent event) { + // TODO + throw new UnsupportedOperationException(NOT_SUPPORTED_YET); + } + } + + @Activate + public void activate(final ComponentContext context) { + log.info("Activate ..."); + appId = coreService.registerApplication("org.onos.faultmanagement.alarms"); + idGenerator = coreService.getIdGenerator("alarm-ids"); + log.info("Started with appId={} idGenerator={}", appId, idGenerator); + + final boolean result = modified(context); + log.info("modified result = {}", result); + + } + + @Deactivate + public void deactivate(final ComponentContext context) { + log.info("Deactivate ..."); + // cfgService.unregisterProperties(getClass(), false); + + log.info("Stopped"); + } + + @Modified + public boolean modified(final ComponentContext context) { + log.info("context={}", context); + if (context == null) { + log.info("No configuration file"); + return false; + } + final Dictionary<?, ?> properties = context.getProperties(); + final String ipaddresses = get(properties, "fmDevices"); + log.info("Settings: devConfigs={}", ipaddresses); + if (!isNullOrEmpty(ipaddresses)) { + discover(ipaddresses); + + } + return true; + } + + private void discover(final String ipaddresses) { + for (String deviceEntry : ipaddresses.split(",")) { + final DeviceId deviceId = DeviceId.deviceId(deviceEntry); + if (deviceId != null) { + log.info("Device {} needs to have its alarms refreshed!", deviceId); + discoverAlarmsForDevice(deviceId); + } + } + } + +} diff --git a/framework/src/onos/apps/faultmanagement/fmmgr/src/main/java/org/onosproject/faultmanagement/impl/package-info.java b/framework/src/onos/apps/faultmanagement/fmmgr/src/main/java/org/onosproject/faultmanagement/impl/package-info.java new file mode 100644 index 00000000..a3f56459 --- /dev/null +++ b/framework/src/onos/apps/faultmanagement/fmmgr/src/main/java/org/onosproject/faultmanagement/impl/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Fault Management application implementation. + */ +package org.onosproject.faultmanagement.impl; diff --git a/framework/src/onos/apps/faultmanagement/fmweb/pom.xml b/framework/src/onos/apps/faultmanagement/fmweb/pom.xml new file mode 100644 index 00000000..8d759710 --- /dev/null +++ b/framework/src/onos/apps/faultmanagement/fmweb/pom.xml @@ -0,0 +1,141 @@ +<?xml version="1.0"?> +<!-- +~ Copyright 2015 Open Networking Laboratory +~ +~ Licensed under the Apache License, Version 2.0 (the "License"); +~ you may not use this file except in compliance with the License. +~ You may obtain a copy of the License at +~ +~ http://www.apache.org/licenses/LICENSE-2.0 +~ +~ Unless required by applicable law or agreed to in writing, software +~ distributed under the License is distributed on an "AS IS" BASIS, +~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +~ See the License for the specific language governing permissions and +~ limitations under the License. +--> +<project + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" + xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.onosproject</groupId> + <artifactId>onos-app-fm</artifactId> + <version>1.4.0-SNAPSHOT</version> + <relativePath>../pom.xml</relativePath> + </parent> + + + <artifactId>onos-app-fm-web</artifactId> + <packaging>bundle</packaging> + <properties> + <web.context>/onos/v1/fm</web.context> + <api.version>1.0.0</api.version> + <api.title>ONOS Fault Management Application REST API</api.title> + <api.description> + APIs for interacting with the Fault Management application. + </api.description> + <api.package>org.onos.faultmanagement.web</api.package> + </properties> + + <dependencies> + <dependency> + <groupId>javax.ws.rs</groupId> + <artifactId>jsr311-api</artifactId> + <version>1.1.1</version> + </dependency> + <dependency> + <groupId>org.onosproject</groupId> + <artifactId>onos-incubator-api</artifactId> + <version>${project.version}</version> + <type>jar</type> + </dependency> + <dependency> + <groupId>org.onosproject</groupId> + <artifactId>onlab-osgi</artifactId> + <version>${project.version}</version> + <classifier>tests</classifier> + <scope>test</scope> + </dependency> + <dependency> + <groupId>com.sun.jersey</groupId> + <artifactId>jersey-client</artifactId> + <version>1.19</version> + <scope>test</scope> + <type>jar</type> + </dependency> + <dependency> + <groupId>org.onosproject</groupId> + <artifactId>onos-core-common</artifactId> + <version>${project.version}</version> + <scope>test</scope> + <type>jar</type> + </dependency> + <dependency> + <groupId>org.onosproject</groupId> + <artifactId>onos-rest</artifactId> + <version>${project.version}</version> + <scope>test</scope> + <type>jar</type> + </dependency> + + <dependency> + <groupId>org.onosproject</groupId> + <artifactId>onos-rest</artifactId> + <version>${project.version}</version> + <classifier>tests</classifier> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>com.sun.jersey.jersey-test-framework</groupId> + <artifactId>jersey-test-framework-core</artifactId> + <version>1.19</version> + </dependency> + + </dependencies> + <build> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <extensions>true</extensions> + <configuration> + <instructions> + <_wab>src/main/webapp/</_wab> + <Include-Resource> + WEB-INF/classes/apidoc/swagger.json=target/swagger.json, + {maven-resources} + </Include-Resource> + <Bundle-SymbolicName> + ${project.groupId}.${project.artifactId} + </Bundle-SymbolicName> + <Import-Package> + org.slf4j, + org.osgi.framework, + javax.ws.rs, + javax.ws.rs.core, + com.sun.jersey.api.core, + com.sun.jersey.spi.container.servlet, + com.sun.jersey.server.impl.container.servlet, + com.fasterxml.jackson.databind, + com.fasterxml.jackson.databind.node, + com.fasterxml.jackson.core, + org.apache.karaf.shell.commands, + org.apache.commons.lang.math.*, + com.google.common.*, + org.onlab.packet.*, + org.onlab.rest.*, + org.onosproject.*, + org.onlab.util.*, + org.jboss.netty.util.* + </Import-Package> + <Web-ContextPath>${web.context}</Web-ContextPath> + </instructions> + </configuration> + </plugin> + </plugins> + </build> + +</project> diff --git a/framework/src/onos/apps/faultmanagement/fmweb/src/main/java/org/onosproject/faultmanagement/web/AlarmCodec.java b/framework/src/onos/apps/faultmanagement/fmweb/src/main/java/org/onosproject/faultmanagement/web/AlarmCodec.java new file mode 100644 index 00000000..a764c908 --- /dev/null +++ b/framework/src/onos/apps/faultmanagement/fmweb/src/main/java/org/onosproject/faultmanagement/web/AlarmCodec.java @@ -0,0 +1,101 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.faultmanagement.web; + +import com.fasterxml.jackson.databind.JsonNode; +import org.onosproject.codec.CodecContext; +import org.onosproject.codec.JsonCodec; + +import com.fasterxml.jackson.databind.node.ObjectNode; + +import static com.google.common.base.Preconditions.checkNotNull; +import org.onosproject.net.DeviceId; +import org.onosproject.incubator.net.faultmanagement.alarm.Alarm; +import org.onosproject.incubator.net.faultmanagement.alarm.AlarmEntityId; +import org.onosproject.incubator.net.faultmanagement.alarm.AlarmId; +import org.onosproject.incubator.net.faultmanagement.alarm.DefaultAlarm; +import org.slf4j.Logger; +import static org.slf4j.LoggerFactory.getLogger; + +/** + * Implementation of encoder for Alarm codec. + */ +public final class AlarmCodec extends JsonCodec<Alarm> { + + private final Logger log = getLogger(getClass()); + + @Override + public ObjectNode encode(final Alarm alarm, final CodecContext context) { + checkNotNull(alarm, "Alarm cannot be null"); + + return context.mapper().createObjectNode() + .put("id", alarm.id().fingerprint()) + .put("deviceId", alarm.deviceId().toString()) + .put("description", alarm.description()) + .put("source", + alarm.source() == null ? null + : alarm.source().toString()) + .put("timeRaised", alarm.timeRaised()) + .put("timeUpdated", alarm.timeUpdated()) + .put("timeCleared", alarm.timeCleared()) + .put("severity", alarm.severity().toString()) + .put("serviceAffecting", alarm.serviceAffecting()) + .put("acknowledged", alarm.acknowledged()) + .put("manuallyClearable", alarm.manuallyClearable()) + .put("assignedUser", alarm.assignedUser()); + + } + + @Override + public Alarm decode(final ObjectNode json, final CodecContext context) { + if (json == null || !json.isObject()) { + return null; + } + + log.debug("id={}, full json={} ", json.get("id"), json); + final Long id = json.get("id").asLong(); + + final DeviceId deviceId = DeviceId.deviceId(json.get("deviceId").asText()); + final String description = json.get("description").asText(); + final Long timeRaised = json.get("timeRaised").asLong(); + final Long timeUpdated = json.get("timeUpdated").asLong(); + + final JsonNode jsonTimeCleared = json.get("timeCleared"); + final Long timeCleared = jsonTimeCleared == null || jsonTimeCleared.isNull() ? null : jsonTimeCleared.asLong(); + + final Alarm.SeverityLevel severity + = Alarm.SeverityLevel.valueOf(json.get("severity").asText().toUpperCase()); + + final Boolean serviceAffecting = json.get("serviceAffecting").asBoolean(); + final Boolean acknowledged = json.get("acknowledged").asBoolean(); + final Boolean manuallyClearable = json.get("manuallyClearable").asBoolean(); + + final JsonNode jsonAssignedUser = json.get("assignedUser"); + final String assignedUser + = jsonAssignedUser == null || jsonAssignedUser.isNull() ? null : jsonAssignedUser.asText(); + + return new DefaultAlarm.Builder( + AlarmId.valueOf(id), deviceId, description, severity, timeRaised).forSource(AlarmEntityId.NONE). + withTimeUpdated(timeUpdated). + withTimeCleared(timeCleared). + withServiceAffecting(serviceAffecting). + withAcknowledged(acknowledged). + withManuallyClearable(manuallyClearable). + withAssignedUser(assignedUser). + build(); + + } +} diff --git a/framework/src/onos/apps/faultmanagement/fmweb/src/main/java/org/onosproject/faultmanagement/web/AlarmsWebResource.java b/framework/src/onos/apps/faultmanagement/fmweb/src/main/java/org/onosproject/faultmanagement/web/AlarmsWebResource.java new file mode 100644 index 00000000..56c891cd --- /dev/null +++ b/framework/src/onos/apps/faultmanagement/fmweb/src/main/java/org/onosproject/faultmanagement/web/AlarmsWebResource.java @@ -0,0 +1,148 @@ +/* + * Copyright 2014-2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.faultmanagement.web; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; +import java.io.IOException; +import java.io.InputStream; +import org.onosproject.rest.AbstractWebResource; + +import javax.ws.rs.core.Response; +import org.onosproject.incubator.net.faultmanagement.alarm.Alarm; +import org.onosproject.incubator.net.faultmanagement.alarm.AlarmId; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DefaultValue; +import javax.ws.rs.GET; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.MediaType; +import org.onosproject.codec.CodecService; +import org.onosproject.incubator.net.faultmanagement.alarm.AlarmService; +import org.slf4j.Logger; +import static org.slf4j.LoggerFactory.getLogger; + +/** + * Alarms on devices or ONOS. + */ +@Path("alarms") +public class AlarmsWebResource extends AbstractWebResource { + + public static final String ALARM_NOT_FOUND = "Alarm is not found"; + + private final Logger log = getLogger(getClass()); + + public AlarmsWebResource() { + get(CodecService.class).registerCodec(Alarm.class, new AlarmCodec()); + } + + /** + * Get all alarms. Returns a list of all alarms across all devices. + * + * @param includeCleared include recently cleared alarms in response + * @return JSON encoded set of alarms + */ + @GET + @Produces(MediaType.APPLICATION_JSON) + public Response getAlarms(@DefaultValue("false") @QueryParam("includeCleared") final boolean includeCleared + ) { + + log.info("Requesting all alarms, includeCleared={}", includeCleared); + final AlarmService service = get(AlarmService.class); + + final Iterable<Alarm> alarms = includeCleared + ? service.getAlarms() + : service.getActiveAlarms(); + + final ObjectNode result = new ObjectMapper().createObjectNode(); + result.set("alarms", + codec(Alarm.class). + encode(alarms, this)); + return ok(result.toString()).build(); + + } + + /** + * Get specified alarm. Returns details of the specified alarm. + * + * @param id ONOS allocated identifier + * @return JSON encoded alarm + */ + @GET + @Path("{id}") + @Produces(MediaType.APPLICATION_JSON) + public Response getAlarm(@PathParam("id") final String id) { + log.info("HTTP GET alarm for id={}", id); + + final AlarmId alarmId = toAlarmId(id); + final Alarm alarm = get(AlarmService.class).getAlarm(alarmId); + + final ObjectNode result = mapper().createObjectNode(); + result.set("alarm", codec(Alarm.class).encode(alarm, this)); + return ok(result.toString()).build(); + } + + /** + * Update book-keeping fields on the alarm. Returns an up-to-date version of the alarm. Some of its fields may have + * been updated since the REST client last retrieved the alarm being updated. + * + * @param alarmIdPath + * @param stream input JSON + * @return updated JSON encoded alarm + */ + @PUT + @Path("{alarm_id}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public Response update(@PathParam("alarm_id") final String alarmIdPath, final InputStream stream) { + log.info("PUT NEW ALARM at /{}", alarmIdPath); + + try { + final ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream); + log.info("jsonTree={}", jsonTree); + + final Alarm alarm = codec(Alarm.class).decode(jsonTree, this); + + final AlarmService service = get(AlarmService.class); + + if (Long.parseLong(alarmIdPath) != alarm.id().fingerprint()) { + throw new IllegalArgumentException("id in path is " + Long.parseLong(alarmIdPath) + + " but payload uses id=" + alarm.id().fingerprint()); + + } + final Alarm updated = service.update(alarm); + final ObjectNode encoded = new AlarmCodec().encode(updated, this); + return ok(encoded.toString()).build(); + + } catch (IOException ioe) { + throw new IllegalArgumentException(ioe); + } + } + + private static AlarmId toAlarmId(final String id) { + try { + return AlarmId.valueOf(Long.parseLong(id)); + } catch (NumberFormatException ex) { + throw new IllegalArgumentException("Alarm id should be numeric", ex); + } + + } + +} diff --git a/framework/src/onos/apps/faultmanagement/fmweb/src/main/java/org/onosproject/faultmanagement/web/package-info.java b/framework/src/onos/apps/faultmanagement/fmweb/src/main/java/org/onosproject/faultmanagement/web/package-info.java new file mode 100644 index 00000000..9c291231 --- /dev/null +++ b/framework/src/onos/apps/faultmanagement/fmweb/src/main/java/org/onosproject/faultmanagement/web/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Fault management web support. + */ +package org.onosproject.faultmanagement.web; diff --git a/framework/src/onos/apps/faultmanagement/fmweb/src/main/webapp/WEB-INF/web.xml b/framework/src/onos/apps/faultmanagement/fmweb/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 00000000..18671f01 --- /dev/null +++ b/framework/src/onos/apps/faultmanagement/fmweb/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,42 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +~ Copyright 2015 Open Networking Laboratory +~ +~ Licensed under the Apache License, Version 2.0 (the "License"); +~ you may not use this file except in compliance with the License. +~ You may obtain a copy of the License at +~ +~ http://www.apache.org/licenses/LICENSE-2.0 +~ +~ Unless required by applicable law or agreed to in writing, software +~ distributed under the License is distributed on an "AS IS" BASIS, +~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +~ See the License for the specific language governing permissions and +~ limitations under the License. +--> +<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" + xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" + xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" + id="ONOS" version="2.5"> + <display-name>FM2 REST API v1.0</display-name> + + <servlet> + <servlet-name>JAX-RS Service</servlet-name> + <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class> + <init-param> + <param-name>com.sun.jersey.config.property.resourceConfigClass</param-name> + <param-value>com.sun.jersey.api.core.ClassNamesResourceConfig</param-value> + </init-param> + <init-param> + <param-name>com.sun.jersey.config.property.classnames</param-name> + <param-value> + org.onosproject.faultmanagement.web.AlarmsWebResource</param-value> + </init-param> + <load-on-startup>10</load-on-startup> + </servlet> + + <servlet-mapping> + <servlet-name>JAX-RS Service</servlet-name> + <url-pattern>/*</url-pattern> + </servlet-mapping> +</web-app> diff --git a/framework/src/onos/apps/faultmanagement/fmweb/src/test/java/org/onosproject/faultmanagement/web/AlarmCodecContext.java b/framework/src/onos/apps/faultmanagement/fmweb/src/test/java/org/onosproject/faultmanagement/web/AlarmCodecContext.java new file mode 100644 index 00000000..89886e8a --- /dev/null +++ b/framework/src/onos/apps/faultmanagement/fmweb/src/test/java/org/onosproject/faultmanagement/web/AlarmCodecContext.java @@ -0,0 +1,73 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.faultmanagement.web; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.onosproject.codec.CodecContext; +import org.onosproject.codec.JsonCodec; + + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.onosproject.incubator.net.faultmanagement.alarm.Alarm; + +/** + * Mock codec context for use in codec unit tests. + */ +public class AlarmCodecContext implements CodecContext { + + private final ObjectMapper mapper = new ObjectMapper(); + private final Map<Class<?>, JsonCodec> codecs = new ConcurrentHashMap<>(); + + /** + * Constructs a new mock codec context. + */ + public AlarmCodecContext() { + codecs.clear(); + registerCodec(Alarm.class, new AlarmCodec()); + + } + + @Override + public ObjectMapper mapper() { + return mapper; + } + + @SuppressWarnings("unchecked") + @Override + public <T> T getService(Class<T> serviceClass) { + // TODO + return null; + } + + /** + * Registers the specified JSON codec for the given entity class. + * + * @param entityClass entity class + * @param codec JSON codec + * @param <T> entity type + */ + public <T> void registerCodec(Class<T> entityClass, JsonCodec<T> codec) { + codecs.putIfAbsent(entityClass, codec); + } + + @SuppressWarnings("unchecked") + @Override + public <T> JsonCodec<T> codec(Class<T> entityClass) { + return codecs.get(entityClass); + } +} diff --git a/framework/src/onos/apps/faultmanagement/fmweb/src/test/java/org/onosproject/faultmanagement/web/AlarmCodecTest.java b/framework/src/onos/apps/faultmanagement/fmweb/src/test/java/org/onosproject/faultmanagement/web/AlarmCodecTest.java new file mode 100644 index 00000000..3009b99a --- /dev/null +++ b/framework/src/onos/apps/faultmanagement/fmweb/src/test/java/org/onosproject/faultmanagement/web/AlarmCodecTest.java @@ -0,0 +1,140 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.faultmanagement.web; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ObjectNode; +import java.io.IOException; +import java.io.InputStream; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.Matchers.nullValue; + +import org.junit.Test; +import org.onosproject.codec.JsonCodec; +import static org.onosproject.faultmanagement.web.AlarmJsonMatcher.matchesAlarm; +import org.onosproject.net.DeviceId; +import org.onosproject.incubator.net.faultmanagement.alarm.Alarm; +import org.onosproject.incubator.net.faultmanagement.alarm.AlarmEntityId; +import org.onosproject.incubator.net.faultmanagement.alarm.AlarmId; +import org.onosproject.incubator.net.faultmanagement.alarm.DefaultAlarm; + +public class AlarmCodecTest { + + private final AlarmCodecContext context = new AlarmCodecContext(); + + // Use this to check handling for miminal Alarm + private final Alarm alarmMinimumFields = new DefaultAlarm.Builder( + new AlarmId(44), + DeviceId.deviceId("of:2222000000000000"), + "NE unreachable", + Alarm.SeverityLevel.CLEARED, + 1). + build(); + + // Use this to check handling for fully populated Alarm + private final Alarm alarmWithSource = new DefaultAlarm.Builder( + new AlarmId(44), + DeviceId.deviceId("of:2222000000000000"), + "NE unreachable", + Alarm.SeverityLevel.CLEARED, 1). + forSource(AlarmEntityId.alarmEntityId("port:1/2/3/4")). + withTimeUpdated(2). + withTimeCleared(3L). + withServiceAffecting(true). + withAcknowledged(true). + withManuallyClearable(true). + withAssignedUser("the assigned user").build(); + + @Test + public void alarmCodecTestWithOptionalFieldMissing() { + //context.registerService(AlarmService.class, new AlarmServiceAdapter()); + final JsonCodec<Alarm> codec = context.codec(Alarm.class); + assertThat(codec, is(notNullValue())); + + final ObjectNode alarmJson = codec.encode(alarmMinimumFields, context); + assertThat(alarmJson, notNullValue()); + assertThat(alarmJson, matchesAlarm(alarmMinimumFields)); + + } + + @Test + public void alarmCodecTestWithOptionalField() { + final JsonCodec<Alarm> codec = context.codec(Alarm.class); + assertThat(codec, is(notNullValue())); + + final ObjectNode alarmJson = codec.encode(alarmWithSource, context); + assertThat(alarmJson, notNullValue()); + assertThat(alarmJson, matchesAlarm(alarmWithSource)); + + } + + @Test + public void verifyMinimalAlarmIsEncoded() throws Exception { + final JsonCodec<Alarm> alarmCodec = context.codec(Alarm.class); + + final Alarm alarm = getDecodedAlarm(alarmCodec, "alarm-minimal.json"); + assertCommon(alarm); + + assertThat(alarm.timeCleared(), nullValue()); + assertThat(alarm.assignedUser(), nullValue()); + + } + + @Test + public void verifyFullyLoadedAlarmIsEncoded() throws Exception { + final JsonCodec<Alarm> alarmCodec = context.codec(Alarm.class); + + final Alarm alarm = getDecodedAlarm(alarmCodec, "alarm-full.json"); + assertCommon(alarm); + + assertThat(alarm.timeCleared(), is(2222L)); + assertThat(alarm.assignedUser(), is("foo")); + + } + + private void assertCommon(final Alarm alarm) { + assertThat(alarm.id(), is(new AlarmId(10L))); + assertThat(alarm.description(), is("NE is not reachable")); + assertThat(alarm.source(), is(AlarmEntityId.NONE)); + assertThat(alarm.timeRaised(), is(999L)); + assertThat(alarm.timeUpdated(), is(1111L)); + assertThat(alarm.severity(), is(Alarm.SeverityLevel.MAJOR)); + assertThat(alarm.serviceAffecting(), is(true)); + assertThat(alarm.acknowledged(), is(false)); + assertThat(alarm.manuallyClearable(), is(true)); + } + + /** + * Reads in a rule from the given resource and decodes it. + * + * @param resourceName resource to use to read the JSON for the rule + * @return decoded flow rule + * @throws IOException if processing the resource failsdecode + */ + private Alarm getDecodedAlarm(final JsonCodec<Alarm> codec, final String resourceName) throws IOException { + final InputStream jsonStream = AlarmCodecTest.class + .getResourceAsStream(resourceName); + final JsonNode json = context.mapper().readTree(jsonStream); + assertThat(json, notNullValue()); + final Alarm result = codec.decode((ObjectNode) json, context); + assertThat(result, notNullValue()); + return result; + } + + +} diff --git a/framework/src/onos/apps/faultmanagement/fmweb/src/test/java/org/onosproject/faultmanagement/web/AlarmJsonMatcher.java b/framework/src/onos/apps/faultmanagement/fmweb/src/test/java/org/onosproject/faultmanagement/web/AlarmJsonMatcher.java new file mode 100644 index 00000000..14bb45f3 --- /dev/null +++ b/framework/src/onos/apps/faultmanagement/fmweb/src/test/java/org/onosproject/faultmanagement/web/AlarmJsonMatcher.java @@ -0,0 +1,135 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.faultmanagement.web; + +import org.hamcrest.Description; +import org.hamcrest.TypeSafeDiagnosingMatcher; +import org.onosproject.incubator.net.faultmanagement.alarm.Alarm; + +import com.fasterxml.jackson.databind.JsonNode; + +/** + * Hamcrest matcher for alarms. + */ +public final class AlarmJsonMatcher extends TypeSafeDiagnosingMatcher<JsonNode> { + + private final Alarm alarm; + + private AlarmJsonMatcher(final Alarm alarm) { + this.alarm = alarm; + } + + @Override + public boolean matchesSafely(final JsonNode jsonAlarm, final Description description) { + final String jsonAlarmId = jsonAlarm.get("id").asText(); + final String alarmId = Long.toString(alarm.id().fingerprint()); + if (!jsonAlarmId.equals(alarmId)) { + description.appendText("alarm id was " + jsonAlarmId); + return false; + } + + final String jsonDeviceId = jsonAlarm.get("deviceId").asText(); + final String alarmDeviceId = alarm.deviceId().toString(); + if (!jsonDeviceId.equals(alarmDeviceId)) { + description.appendText("DeviceId was " + jsonDeviceId); + return false; + } + + + final String jsonDescription = jsonAlarm.get("description").asText(); + final String alarmDesc = alarm.description(); + if (!jsonDescription.equals(alarmDesc)) { + description.appendText("description was " + jsonDescription); + return false; + } + + final long jsonTimeRaised = jsonAlarm.get("timeRaised").asLong(); + final long timeRaised = alarm.timeRaised(); + if (timeRaised != jsonTimeRaised) { + description.appendText("timeRaised was " + jsonTimeRaised); + return false; + } + + + final long jsonTimeUpdated = jsonAlarm.get("timeUpdated").asLong(); + final long timeUpdated = alarm.timeUpdated(); + if (timeUpdated != jsonTimeUpdated) { + description.appendText("timeUpdated was " + jsonTimeUpdated); + return false; + } + + final JsonNode jsonTimeClearedNode = jsonAlarm.get("timeCleared"); + + if (alarm.timeCleared() != null) { + final Long jsonTimeCleared = jsonTimeClearedNode.longValue(); + final Long timeCleared = alarm.timeCleared(); + + if (!timeCleared.equals(jsonTimeCleared)) { + description.appendText("Time Cleared was " + jsonTimeCleared); + return false; + } + } else { + // No clear time not specified, JSON representation must be empty + if (!jsonTimeClearedNode.isNull()) { + description.appendText("Time Cleared should be null"); + return false; + } + } + + final String jsonSeverity = jsonAlarm.get("severity").asText(); + final String severity = alarm.severity().toString(); + if (!severity.equals(jsonSeverity)) { + description.appendText("severity was " + jsonSeverity); + return false; + } + + final JsonNode jsonAlarmNode = jsonAlarm.get("source"); + + if (alarm.source() != null) { + final String jsonSource = jsonAlarmNode.textValue(); + final String source = alarm.source().toString(); + + if (!source.equals(jsonSource)) { + description.appendText("source was " + jsonSource); + return false; + } + } else { + // source not specified, JSON representation must be empty + if (!jsonAlarmNode.isNull()) { + description.appendText("source should be null"); + return false; + } + } + + // In progress + return true; + } + + @Override + public void describeTo(final Description description) { + description.appendText(alarm.toString()); + } + + /** + * Factory to allocate a alarm matcher. + * + * @param alarm alarm object we are looking for + * @return matcher + */ + public static AlarmJsonMatcher matchesAlarm(final Alarm alarm) { + return new AlarmJsonMatcher(alarm); + } +} diff --git a/framework/src/onos/apps/faultmanagement/fmweb/src/test/java/org/onosproject/faultmanagement/web/AlarmsWebResourceTest.java b/framework/src/onos/apps/faultmanagement/fmweb/src/test/java/org/onosproject/faultmanagement/web/AlarmsWebResourceTest.java new file mode 100644 index 00000000..0b7d9811 --- /dev/null +++ b/framework/src/onos/apps/faultmanagement/fmweb/src/test/java/org/onosproject/faultmanagement/web/AlarmsWebResourceTest.java @@ -0,0 +1,72 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.faultmanagement.web; + +import com.sun.jersey.api.client.WebResource; +import org.junit.Before; +import org.junit.Test; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.not; +import org.junit.Ignore; +import org.onlab.osgi.ServiceDirectory; +import org.onlab.osgi.TestServiceDirectory; +import org.onlab.rest.BaseResource; +import org.onosproject.codec.CodecService; +import org.onosproject.codec.impl.CodecManager; +import org.onosproject.rest.ResourceTest; + +/** + * Test of the Fault Management Web REST API for Alarms. + */ +public class AlarmsWebResourceTest extends ResourceTest { + + @Before + public void setUp() { + + final CodecManager codecService = new CodecManager(); + codecService.activate(); + + final ServiceDirectory testDirectory + = new TestServiceDirectory() + // Currently no alarms-service implemented + // .add(AlarmsService.class, alarmsService) + .add(CodecService.class, codecService); + BaseResource.setServiceDirectory(testDirectory); + } + + @Test + @Ignore + public void getAllAlarms() { + final WebResource rs = resource(); + final String response = rs.path("/alarms").get(String.class); + // Ensure hard-coded alarms returned okay + assertThat(response, containsString("\"NE is not reachable\",")); + assertThat(response, containsString("\"Equipment Missing\",")); + } + + @Test + @Ignore + public void getAlarm() { + final WebResource rs = resource(); + final String response = rs.path("/alarms/1").get(String.class); + // Ensure hard-coded alarms returned okay + assertThat(response, containsString("\"NE is not reachable\",")); + assertThat(response, not(containsString("\"Equipment Missing\","))); + } + +} diff --git a/framework/src/onos/apps/faultmanagement/fmweb/src/test/resources/org/onosproject/faultmanagement/web/alarm-full.json b/framework/src/onos/apps/faultmanagement/fmweb/src/test/resources/org/onosproject/faultmanagement/web/alarm-full.json new file mode 100644 index 00000000..215fc938 --- /dev/null +++ b/framework/src/onos/apps/faultmanagement/fmweb/src/test/resources/org/onosproject/faultmanagement/web/alarm-full.json @@ -0,0 +1,15 @@ +{ + "id": 10, + "deviceId": "of:123", + "description": "NE is not reachable", + "source": "none:none", + "timeRaised": 999, + "timeUpdated": 1111, + "timeUpdated": 1111, + "timeCleared": 2222, + "severity": "MAJOR", + "serviceAffecting": true, + "acknowledged": false, + "manuallyClearable": true, + "assignedUser": "foo" +}
\ No newline at end of file diff --git a/framework/src/onos/apps/faultmanagement/fmweb/src/test/resources/org/onosproject/faultmanagement/web/alarm-minimal.json b/framework/src/onos/apps/faultmanagement/fmweb/src/test/resources/org/onosproject/faultmanagement/web/alarm-minimal.json new file mode 100644 index 00000000..4a24db09 --- /dev/null +++ b/framework/src/onos/apps/faultmanagement/fmweb/src/test/resources/org/onosproject/faultmanagement/web/alarm-minimal.json @@ -0,0 +1,12 @@ +{ + "id": 10, + "deviceId": "of:123", + "description": "NE is not reachable", + "source": "none:none", + "timeRaised": 999, + "timeUpdated": 1111, + "severity": "MAJOR", + "serviceAffecting": true, + "acknowledged": false, + "manuallyClearable": true +}
\ No newline at end of file diff --git a/framework/src/onos/apps/faultmanagement/pom.xml b/framework/src/onos/apps/faultmanagement/pom.xml new file mode 100644 index 00000000..e7bb6a1b --- /dev/null +++ b/framework/src/onos/apps/faultmanagement/pom.xml @@ -0,0 +1,56 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright 2014 Open Networking Laboratory + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.onosproject</groupId> + <artifactId>onos-apps</artifactId> + <version>1.4.0-SNAPSHOT</version> + <relativePath>../pom.xml</relativePath> + </parent> + + <artifactId>onos-app-fm</artifactId> + <packaging>pom</packaging> + + <description>ONOS framework applications</description> + + <modules> + <module>fmmgr</module> + <module>fmweb</module> + <module>app</module> + </modules> + <dependencies> + <dependency> + <groupId>org.onosproject</groupId> + <artifactId>onlab-junit</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>com.google.guava</groupId> + <artifactId>guava-testlib</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.easymock</groupId> + <artifactId>easymock</artifactId> + <scope>test</scope> + </dependency> + </dependencies> +</project> diff --git a/framework/src/onos/apps/iptopology-api/pom.xml b/framework/src/onos/apps/iptopology-api/pom.xml new file mode 100644 index 00000000..50cb4adc --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/pom.xml @@ -0,0 +1,29 @@ +<!-- + ~ Copyright 2015 Open Networking Laboratory + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.onosproject</groupId> + <artifactId>onos-apps</artifactId> + <version>1.4.0-SNAPSHOT</version> + </parent> + <artifactId>onos-app-iptopology-api</artifactId> + <packaging>bundle</packaging> + + <description>IP Layer Topology API</description> +</project> diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/AreaId.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/AreaId.java new file mode 100644 index 00000000..79a326da --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/AreaId.java @@ -0,0 +1,70 @@ +/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.iptopology.api;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+import java.util.Objects;
+
+/**
+ * Area identifier class (32 Bit Area-ID).
+ */
+public class AreaId {
+ private final int areaId;
+
+ /**
+ * Constructor to set area identifier.
+ *
+ * @param areaId area id
+ */
+ public AreaId(int areaId) {
+ this.areaId = areaId;
+ }
+
+ /**
+ * obtain area identifier.
+ *
+ * @return area identifier
+ */
+ public int areaId() {
+ return areaId;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(areaId);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj instanceof AreaId) {
+ AreaId other = (AreaId) obj;
+ return Objects.equals(areaId, other.areaId);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .add("areaId", areaId)
+ .toString();
+ }
+}
\ No newline at end of file diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/AsNumber.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/AsNumber.java new file mode 100644 index 00000000..3159b20a --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/AsNumber.java @@ -0,0 +1,70 @@ +/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.iptopology.api;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+import java.util.Objects;
+
+/**
+ * Autonomous system Number class (32 Bit ASNumber).
+ */
+public class AsNumber {
+ private final int asNum;
+
+ /**
+ * Constructor to set As number.
+ *
+ * @param asNum As number
+ */
+ public AsNumber(int asNum) {
+ this.asNum = asNum;
+ }
+
+ /**
+ * Obtain autonomous system number.
+ *
+ * @return autonomous system number
+ */
+ public int asNum() {
+ return asNum;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(asNum);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj instanceof AsNumber) {
+ AsNumber other = (AsNumber) obj;
+ return Objects.equals(asNum, other.asNum);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .add("asNum", asNum)
+ .toString();
+ }
+}
\ No newline at end of file diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/Color.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/Color.java new file mode 100644 index 00000000..cb38fa67 --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/Color.java @@ -0,0 +1,72 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.iptopology.api; + +import static com.google.common.base.MoreObjects.toStringHelper; + +import java.util.Objects; + +/** + * Represents administrative group color. + * bit mask - least significant bit is referred to as 'group 0', + * and the most significant bit is referred to as 'group 31' + */ +public class Color { + private final int color; + + /** + * Constructor to initialize its parameter. + * + * @param color assigned by the network administrator + */ + public Color(int color) { + this.color = color; + } + + /** + * Obtains administrative group. + * + * @return administrative group + */ + public int color() { + return color; + } + + @Override + public int hashCode() { + return Objects.hash(color); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj instanceof Color) { + Color other = (Color) obj; + return Objects.equals(color, other.color); + } + return false; + } + + @Override + public String toString() { + return toStringHelper(this) + .add("color", color) + .toString(); + } +}
\ No newline at end of file diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/DefaultDeviceIntf.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/DefaultDeviceIntf.java new file mode 100644 index 00000000..e40cbfc0 --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/DefaultDeviceIntf.java @@ -0,0 +1,79 @@ +/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.iptopology.api;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+import java.util.Objects;
+
+import org.onosproject.net.Element;
+
+/**
+ * Default Device interface implementation.
+ */
+public class DefaultDeviceIntf implements DeviceIntf {
+
+ private final Element element;
+ private final DeviceInterface deviceInterface;
+
+ /**
+ * Constructor to initialize device interface parameters.
+ *
+ * @param element parent network element
+ * @param deviceInterface device interface
+ */
+ public DefaultDeviceIntf(Element element, DeviceInterface deviceInterface) {
+ this.element = element;
+ this.deviceInterface = deviceInterface;
+ }
+
+ @Override
+ public Element element() {
+ return element;
+ }
+
+ @Override
+ public DeviceInterface deviceInterface() {
+ return deviceInterface;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(element, deviceInterface);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj instanceof DefaultDeviceIntf) {
+ final DefaultDeviceIntf other = (DefaultDeviceIntf) obj;
+ return Objects.equals(this.element.id(), other.element.id())
+ && Objects.equals(this.deviceInterface, other.deviceInterface);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .add("element", element.id())
+ .add("deviceInterface", deviceInterface)
+ .toString();
+ }
+}
\ No newline at end of file diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/DefaultDevicePrefix.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/DefaultDevicePrefix.java new file mode 100644 index 00000000..2b1dde6f --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/DefaultDevicePrefix.java @@ -0,0 +1,95 @@ +/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.iptopology.api;
+
+import org.onosproject.net.AbstractAnnotated;
+import org.onosproject.net.Annotations;
+import org.onosproject.net.Element;
+
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Default Device prefix implementation.
+ */
+public class DefaultDevicePrefix extends AbstractAnnotated implements DevicePrefix {
+
+ private final Element element;
+ private final PrefixIdentifier prefixIdentifier;
+ private final PrefixTed prefixTed;
+
+ /**
+ * Creates a network device prefix attributed to the specified element.
+ *
+ * @param element parent network element
+ * @param prefixIdentifier prefix identifier
+ * @param prefixTed prefid traffic engineering parameters
+ * @param annotations optional key/value annotations
+ */
+ public DefaultDevicePrefix(Element element, PrefixIdentifier prefixIdentifier,
+ PrefixTed prefixTed, Annotations... annotations) {
+ super(annotations);
+ this.element = element;
+ this.prefixIdentifier = prefixIdentifier;
+ this.prefixTed = prefixTed;
+ }
+
+ @Override
+ public Element element() {
+ return element;
+ }
+
+ @Override
+ public PrefixIdentifier prefixIdentifier() {
+ return prefixIdentifier;
+ }
+
+ @Override
+ public PrefixTed prefixTed() {
+ return prefixTed;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(element, prefixIdentifier, prefixTed);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof DefaultDevicePrefix) {
+ final DefaultDevicePrefix other = (DefaultDevicePrefix) obj;
+ return Objects.equals(this.element.id(), other.element.id()) &&
+ Objects.equals(this.prefixIdentifier, other.prefixIdentifier) &&
+ Objects.equals(this.prefixTed, other.prefixTed) &&
+ Objects.equals(this.annotations(), other.annotations());
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .omitNullValues()
+ .add("element", element.id())
+ .add("prefixIdentifier", prefixIdentifier)
+ .add("prefixTed", prefixTed)
+ .toString();
+ }
+}
\ No newline at end of file diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/DefaultIpDevice.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/DefaultIpDevice.java new file mode 100644 index 00000000..a2d0165c --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/DefaultIpDevice.java @@ -0,0 +1,113 @@ +/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.iptopology.api;
+
+import org.onosproject.net.AbstractElement;
+import org.onosproject.net.Annotations;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.provider.ProviderId;
+
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * Default ip device model implementation.
+ */
+public class DefaultIpDevice extends AbstractElement implements IpDevice {
+
+ private final Type type;
+ private final IpDeviceIdentifier deviceIdentifier;
+ private final DeviceTed deviceTed;
+
+
+ /**
+ * For Serialization.
+ */
+ private DefaultIpDevice() {
+ this.type = null;
+ this.deviceIdentifier = null;
+ this.deviceTed = null;
+ }
+
+ /**
+ * Creates a network element attributed to the specified provider.
+ *
+ * @param providerId identity of the provider
+ * @param id device identifier
+ * @param type device type
+ * @param deviceIdentifier provides device identifier details
+ * @param deviceTed device traffic engineering parameters
+ * @param annotations optional key/value annotations
+ */
+ public DefaultIpDevice(ProviderId providerId, DeviceId id, Type type,
+ IpDeviceIdentifier deviceIdentifier, DeviceTed deviceTed,
+ Annotations... annotations) {
+ super(providerId, id, annotations);
+ this.type = type;
+ this.deviceIdentifier = deviceIdentifier;
+ this.deviceTed = deviceTed;
+ }
+
+ @Override
+ public DeviceId id() {
+ return (DeviceId) id;
+ }
+
+ @Override
+ public Type type() {
+ return type;
+ }
+
+ @Override
+ public IpDeviceIdentifier deviceIdentifier() {
+ return deviceIdentifier;
+ }
+
+ @Override
+ public DeviceTed deviceTed() {
+ return deviceTed; }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(type, deviceIdentifier, deviceTed);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj instanceof DefaultIpDevice) {
+ final DefaultIpDevice other = (DefaultIpDevice) obj;
+ return Objects.equals(this.id, other.id) &&
+ Objects.equals(this.type, other.type) &&
+ Objects.equals(this.deviceIdentifier, other.deviceIdentifier) &&
+ Objects.equals(this.deviceTed, other.deviceTed);
+ }
+ return false;
+ }
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .omitNullValues()
+ .add("id", id)
+ .add("deviceIdentifier", deviceIdentifier)
+ .add("deviceTed", deviceTed)
+ .toString();
+ }
+}
\ No newline at end of file diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/DefaultIpLink.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/DefaultIpLink.java new file mode 100644 index 00000000..41f06047 --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/DefaultIpLink.java @@ -0,0 +1,105 @@ +/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.iptopology.api;
+
+import org.onosproject.net.AbstractModel;
+import org.onosproject.net.Annotations;
+import org.onosproject.net.provider.ProviderId;
+
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+/**
+ * This class provides Link identifier and link ted details.
+ */
+public class DefaultIpLink extends AbstractModel implements IpLink {
+
+ private final TerminationPoint src;
+ private final TerminationPoint dst;
+ private final IpLinkIdentifier linkIdentifier;
+ private final LinkTed linkTed;
+
+ /**
+ * Constructor to initialize its parameters.
+ *
+ * @param src link source termination point
+ * @param dst link destination termination point
+ * @param linkIdentifier provides link identifier details
+ * @param linkTed provides link traffic engineering details
+ * @param annotations optional key/value annotations
+ */
+ public DefaultIpLink(ProviderId providerId, TerminationPoint src, TerminationPoint dst,
+ IpLinkIdentifier linkIdentifier, LinkTed linkTed,
+ Annotations... annotations) {
+ super(providerId, annotations);
+ this.src = src;
+ this.dst = dst;
+ this.linkIdentifier = linkIdentifier;
+ this.linkTed = linkTed;
+ }
+
+ @Override
+ public TerminationPoint src() {
+ return src;
+ }
+
+ @Override
+ public TerminationPoint dst() {
+ return dst;
+ }
+
+ @Override
+ public IpLinkIdentifier linkIdentifier() {
+ return linkIdentifier;
+ }
+
+ @Override
+ public LinkTed linkTed() {
+ return linkTed;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(src, dst, linkIdentifier, linkTed);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof DefaultIpLink) {
+ final DefaultIpLink other = (DefaultIpLink) obj;
+ return Objects.equals(this.src, other.src) &&
+ Objects.equals(this.dst, other.dst) &&
+ Objects.equals(this.linkIdentifier, other.linkIdentifier) &&
+ Objects.equals(this.linkTed, other.linkTed);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .omitNullValues()
+ .add("src", src)
+ .add("dst", dst)
+ .add("linkIdentifier", linkIdentifier)
+ .add("linkTed", linkTed)
+ .toString();
+ }
+}
\ No newline at end of file diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/DeviceInterface.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/DeviceInterface.java new file mode 100644 index 00000000..131aa623 --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/DeviceInterface.java @@ -0,0 +1,100 @@ +/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.iptopology.api;
+
+import java.util.Objects;
+
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip6Address;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Representation of device interface.
+ */
+public class DeviceInterface {
+ private final Ip4Address ip4Address;
+ private final Ip6Address ip6Address;
+ private final InterfaceIdentifier interfaceId;
+
+ /**
+ * Constructor to initialize its parameter.
+ *
+ * @param ip4Address ipv4 interface address
+ * @param ip6Address ipv6 interface address
+ * @param interfaceId interface Identifier
+ */
+ public DeviceInterface(Ip4Address ip4Address, Ip6Address ip6Address, InterfaceIdentifier interfaceId) {
+ this.ip4Address = ip4Address;
+ this.ip6Address = ip6Address;
+ this.interfaceId = interfaceId;
+ }
+
+ /**
+ * obtains ipv4 address of an interface.
+ *
+ * @return ipv4 interface address
+ */
+ public Ip4Address ip4Address() {
+ return ip4Address;
+ }
+
+ /**
+ * obtains ipv6 interface address.
+ *
+ * @return ipv6 interface address
+ */
+ public Ip6Address ip6Address() {
+ return ip6Address;
+ }
+
+ /**
+ * obtains interface identifier.
+ *
+ * @return interface identifier
+ */
+ public InterfaceIdentifier interfaceId() {
+ return interfaceId;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(ip4Address, ip6Address, interfaceId);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof DeviceInterface) {
+ final DeviceInterface other = (DeviceInterface) obj;
+ return Objects.equals(this.ip4Address, other.ip4Address)
+ && Objects.equals(this.ip6Address, other.ip6Address)
+ && Objects.equals(this.interfaceId, other.interfaceId);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("ip4Address", ip4Address)
+ .add("ip6Address", ip6Address)
+ .add("interfaceId", interfaceId)
+ .toString();
+ }
+}
\ No newline at end of file diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/DeviceIntf.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/DeviceIntf.java new file mode 100644 index 00000000..ff18d3ac --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/DeviceIntf.java @@ -0,0 +1,37 @@ +/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.iptopology.api;
+
+import org.onosproject.net.Element;
+
+/**
+ * Abstraction of Device interface.
+ */
+public interface DeviceIntf {
+ /**
+ * Returns the parent network element to which this interface belongs.
+ *
+ * @return parent network element
+ */
+ Element element();
+
+ /**
+ * Returns device interface details.
+ *
+ * @return device interface details
+ */
+ DeviceInterface deviceInterface();
+}
\ No newline at end of file diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/DevicePrefix.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/DevicePrefix.java new file mode 100644 index 00000000..89efccd4 --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/DevicePrefix.java @@ -0,0 +1,46 @@ +/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.iptopology.api;
+
+import org.onosproject.net.Annotated;
+import org.onosproject.net.Element;
+
+/**
+ * Abstraction of Device Prefix.
+ */
+public interface DevicePrefix extends Annotated {
+
+ /**
+ * Returns the parent network element to which this port belongs.
+ *
+ * @return parent network element
+ */
+ Element element();
+
+ /**
+ * Returns prefix identifier details.
+ *
+ * @return prefix identifier details
+ */
+ PrefixIdentifier prefixIdentifier();
+
+ /**
+ * Returns prefix Traffic engineering parameters.
+ *
+ * @return prefix Traffic engineering parameters
+ */
+ PrefixTed prefixTed();
+}
\ No newline at end of file diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/DeviceTed.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/DeviceTed.java new file mode 100644 index 00000000..4d9da55d --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/DeviceTed.java @@ -0,0 +1,173 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.iptopology.api; + +import static com.google.common.base.MoreObjects.toStringHelper; + +import java.util.Iterator; +import java.util.List; +import java.util.Objects; + +import org.onlab.packet.Ip4Address; +import org.onlab.packet.Ip6Address; + +/** + * Represents Device Traffic Engineering parameters. + */ +public class DeviceTed { + private final List<Ip4Address> ipv4RouterIds; + private final List<Ip6Address> ipv6RouterIds; + private final List<TopologyId> topologyIds; + private final Position position; + + /** + * Constructor to initialize the parameter fields. + * + * @param ipv4RouterIds Router ids of Ipv4 + * @param ipv6RouterIds Router ids of Ipv6 + * @param topologyIds list of multi-topology IDs of the node + * @param position of router whether it is ABR or ASBR + */ + public DeviceTed(List<Ip4Address> ipv4RouterIds, List<Ip6Address> ipv6RouterIds, + List<TopologyId> topologyIds, Position position) { + this.ipv4RouterIds = ipv4RouterIds; + this.ipv6RouterIds = ipv6RouterIds; + this.topologyIds = topologyIds; + this.position = position; + } + + /** + * Obtain list of Ipv4 Router id. + * + * @return Ipv4 Router ids + */ + public List<Ip4Address> ipv4RouterIds() { + return ipv4RouterIds; + } + + /** + * Obtain list of Ipv6 Router id. + * + * @return Ipv6 Router ids + */ + public List<Ip6Address> ipv6RouterIds() { + return ipv6RouterIds; + } + + /** + * Obtain the list of topology ID's. + * + * @return list of topology id's + */ + public List<TopologyId> topologyIds() { + return topologyIds; + } + + + /** + * Obtain position of device in the network. + * + * @return position of device in the network + */ + public Position position() { + return position; + } + + @Override + public int hashCode() { + return Objects.hash(ipv4RouterIds, ipv6RouterIds, topologyIds, position); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj instanceof DeviceTed) { + int countObjSubTlv = 0; + int countOtherSubTlv = 0; + int countObjTopologyId = 0; + int countOtherTopologyId = 0; + boolean isCommonSubTlv = true; + boolean isCommonSubTlv6 = true; + boolean isCommonTopology = true; + DeviceTed other = (DeviceTed) obj; + Iterator<Ip4Address> objListIterator = other.ipv4RouterIds.iterator(); + countOtherSubTlv = other.ipv4RouterIds.size(); + countObjSubTlv = ipv4RouterIds.size(); + + Iterator<Ip6Address> objListIteratorIpv6 = other.ipv6RouterIds.iterator(); + int countOtherSubTlv6 = other.ipv6RouterIds.size(); + int countObjSubTlv6 = ipv6RouterIds.size(); + + Iterator<TopologyId> topologyId = other.topologyIds.iterator(); + countOtherTopologyId = other.topologyIds.size(); + countObjTopologyId = topologyIds.size(); + + if (countObjSubTlv != countOtherSubTlv || countOtherSubTlv6 != countObjSubTlv6 + || countObjTopologyId != countOtherTopologyId) { + return false; + } else { + while (objListIterator.hasNext() && isCommonSubTlv) { + Ip4Address subTlv = objListIterator.next(); + //find index of that element and then get that from the list and then compare + if (ipv4RouterIds.contains(subTlv) && other.ipv4RouterIds.contains(subTlv)) { + isCommonSubTlv = Objects.equals(ipv4RouterIds.get(ipv4RouterIds.indexOf(subTlv)), + other.ipv4RouterIds.get(other.ipv4RouterIds.indexOf(subTlv))); + } else { + isCommonSubTlv = false; + } + } + while (objListIteratorIpv6.hasNext() && isCommonSubTlv6) { + Ip6Address subTlv = objListIteratorIpv6.next(); + //find index of that element and then get that from the list and then compare + if (ipv6RouterIds.contains(subTlv) && other.ipv6RouterIds.contains(subTlv)) { + isCommonSubTlv6 = Objects.equals(ipv6RouterIds.get(ipv6RouterIds.indexOf(subTlv)), + other.ipv6RouterIds.get(other.ipv6RouterIds.indexOf(subTlv))); + } else { + isCommonSubTlv6 = false; + } + } + while (topologyId.hasNext() && isCommonTopology) { + TopologyId subTlv = topologyId.next(); + //find index of that element and then get that from the list and then compare + if (topologyIds.contains(subTlv) && other.topologyIds.contains(subTlv)) { + isCommonTopology = Objects.equals(topologyIds.get(topologyIds.indexOf(subTlv)), + other.topologyIds.get(other.topologyIds.indexOf(subTlv))); + } else { + isCommonTopology = false; + } + } + return isCommonSubTlv && isCommonSubTlv6 && isCommonTopology + && Objects.equals(position, other.position); + } + } + return false; + } + + @Override + public String toString() { + return toStringHelper(this) + .omitNullValues() + .add("ipv6RouterIds", ipv6RouterIds) + .add("ipv4RouterIds", ipv4RouterIds) + .add("topologyIds", topologyIds) + .add("position", position) + .toString(); + } + +}
\ No newline at end of file diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/DomainId.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/DomainId.java new file mode 100644 index 00000000..4fb10701 --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/DomainId.java @@ -0,0 +1,71 @@ +/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.iptopology.api;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+import java.util.Objects;
+
+/**
+ * Domain Identifier(32 Bit).
+ */
+public class DomainId {
+ private final int domainIdentifier;
+
+ /**
+ * Constructor to initialize domain identifier.
+ *
+ * @param domainIdentifier domain identifier
+ */
+ public DomainId(int domainIdentifier) {
+ this.domainIdentifier = domainIdentifier;
+ }
+
+ /**
+ * Obtain domain identifier.
+ *
+ * @return domain identifier
+ */
+ public int domainIdentifier() {
+ return domainIdentifier;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(domainIdentifier);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj instanceof DomainId) {
+ DomainId other = (DomainId) obj;
+ return Objects.equals(domainIdentifier, other.domainIdentifier);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .add("domainIdentifier", domainIdentifier)
+ .toString();
+ }
+}
\ No newline at end of file diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/ExtendedRouteTag.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/ExtendedRouteTag.java new file mode 100644 index 00000000..9bd87c1b --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/ExtendedRouteTag.java @@ -0,0 +1,70 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.iptopology.api; + +import static com.google.common.base.MoreObjects.toStringHelper; + +import java.util.Objects; + +/** + * Represents the extended igp administrative tags of the prefix. + */ +public class ExtendedRouteTag { + private final long extRouteTag; + + /** + * Constructor to initialize its parameter. + * + * @param extRouteTag extended ISIS route tag + */ + public ExtendedRouteTag(long extRouteTag) { + this.extRouteTag = extRouteTag; + } + + /** + * Obtains extended igp administrative tags. + * + * @return extended igp administrative tags + */ + public long extRouteTag() { + return extRouteTag; + } + + @Override + public int hashCode() { + return Objects.hash(extRouteTag); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj instanceof ExtendedRouteTag) { + ExtendedRouteTag other = (ExtendedRouteTag) obj; + return Objects.equals(extRouteTag, other.extRouteTag); + } + return false; + } + + @Override + public String toString() { + return toStringHelper(this) + .add("extRouteTag", extRouteTag) + .toString(); + } +}
\ No newline at end of file diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/IgpFlags.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/IgpFlags.java new file mode 100644 index 00000000..59084c04 --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/IgpFlags.java @@ -0,0 +1,114 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.iptopology.api; + +import static com.google.common.base.MoreObjects.toStringHelper; + +import java.util.Objects; + +/** + * This class provides implementation IS-IS and OSPF flags assigned to the prefix. + */ +public class IgpFlags { + private final boolean isisUpDown; + private final boolean ospfNoUnicast; + private final boolean ospfLclAddr; + private final boolean ospfNssa; + + /** + * Constructor to initialize its parameters. + * + * @param isisUpDown IS-IS Up/Down + * @param ospfNoUnicast OSPF no unicast + * @param ospfLclAddr OSPF local address + * @param ospfNssa OSPF propagate NSSA + */ + public IgpFlags(boolean isisUpDown, boolean ospfNoUnicast, boolean ospfLclAddr, + boolean ospfNssa) { + this.isisUpDown = isisUpDown; + this.ospfNoUnicast = ospfNoUnicast; + this.ospfLclAddr = ospfLclAddr; + this.ospfNssa = ospfNssa; + } + + /** + * Provides information whether IS-IS is Up/Down. + * + * @return IS-IS Up/Down bit enabled or not + */ + public boolean isisUpDown() { + return isisUpDown; + } + + /** + * Provides information whether OSPF is unicast or not. + * + * @return OSPF no unicast Bit set or not + */ + public boolean ospfNoUnicast() { + return ospfNoUnicast; + } + + /** + * Provides information on OSPF local address. + * + * @return OSPF local address Bit set or not + */ + public boolean ospfLclAddr() { + return ospfLclAddr; + } + + /** + * Provides information on OSPF propagate NSSA. + * + * @return OSPF propagate NSSA Bit set or not + */ + public boolean ospfNssa() { + return ospfNssa; + } + + @Override + public int hashCode() { + return Objects.hash(isisUpDown, ospfNoUnicast, ospfLclAddr, + ospfNssa); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj instanceof IgpFlags) { + IgpFlags other = (IgpFlags) obj; + return Objects.equals(isisUpDown, other.isisUpDown) + && Objects.equals(ospfNoUnicast, other.ospfNoUnicast) + && Objects.equals(ospfLclAddr, other.ospfLclAddr) + && Objects.equals(ospfNssa, other.ospfNssa); + } + return false; + } + + @Override + public String toString() { + return toStringHelper(this) + .add("isisUpDown", isisUpDown) + .add("ospfNoUnicast", ospfNoUnicast) + .add("ospfLclAddr", ospfLclAddr) + .add("ospfNssa", ospfNssa) + .toString(); + } +}
\ No newline at end of file diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/InterfaceIdentifier.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/InterfaceIdentifier.java new file mode 100644 index 00000000..405e1417 --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/InterfaceIdentifier.java @@ -0,0 +1,71 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.iptopology.api; + +import static com.google.common.base.MoreObjects.toStringHelper; + +import java.util.Objects; + +/** + * This class provides information on Local Interface Identifier and Remote + * Interface Identifier of the link. + */ +public class InterfaceIdentifier { + private final Integer identifier; + + /** + * Constructor to initialize identifier. + * + * @param identifier local/remote interface identifier + */ + public InterfaceIdentifier(Integer identifier) { + this.identifier = identifier; + } + + /** + * Provides the local/remote interface identifier of the link. + * + * @return interface identifier + */ + public Integer identifier() { + return identifier; + } + + @Override + public int hashCode() { + return Objects.hash(identifier); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj instanceof InterfaceIdentifier) { + InterfaceIdentifier other = (InterfaceIdentifier) obj; + return Objects.equals(identifier, other.identifier); + } + return false; + } + + @Override + public String toString() { + return toStringHelper(this) + .add("identifier", identifier) + .toString(); + } +} diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/IpDevice.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/IpDevice.java new file mode 100644 index 00000000..131b7eae --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/IpDevice.java @@ -0,0 +1,68 @@ +/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.iptopology.api;
+
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Element;
+
+/**
+ * Abstraction of Ip Device.
+ */
+public interface IpDevice extends Element {
+ /**
+ ** Enum type to store Device Type.
+ */
+ enum Type {
+ /**
+ * Signifies that the device is pseudo device.
+ */
+ PSEUDO,
+
+ /**
+ * Signifies that the device is non-pseudo device.
+ */
+ NONPSEUDO;
+ }
+
+ /**
+ * Obtains device id.
+ *
+ * @return device id
+ */
+ @Override
+ DeviceId id();
+
+ /**
+ * Obtains device type.
+ *
+ * @return device type
+ */
+ Type type();
+
+ /**
+ * Obtains Device identifier details.
+ *
+ * @return identifier of the device
+ */
+ IpDeviceIdentifier deviceIdentifier();
+
+ /**
+ * Obtains the traffic engineering parameters of the device.
+ *
+ * @return traffic engineering parameters of the device
+ */
+ DeviceTed deviceTed();
+}
\ No newline at end of file diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/IpDeviceIdentifier.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/IpDeviceIdentifier.java new file mode 100644 index 00000000..472fe008 --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/IpDeviceIdentifier.java @@ -0,0 +1,141 @@ +/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.iptopology.api;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+import java.util.Objects;
+
+/**
+ * Represents IP Device Identifiers.
+ */
+public class IpDeviceIdentifier {
+
+ private final RouteDistinguisher routeDish;
+ private final RouteInstance routeInstance;
+ private final AsNumber asNum;
+ private final DomainId domainIdentifier;
+ private final AreaId areaId;
+ private final RouteIdentifier routerIdentifier;
+
+ /**
+ * Constructor to initialize parameters.
+ *
+ * @param routeInstance routing protocol instance
+ * @param asNum AS number
+ * @param domainIdentifier BGP-LS domain
+ * @param areaId Area ID
+ * @param routerIdentifier IGP router ID
+ */
+ public IpDeviceIdentifier(RouteDistinguisher routeDish, RouteInstance routeInstance, AsNumber asNum,
+ DomainId domainIdentifier, AreaId areaId, RouteIdentifier routerIdentifier) {
+ this.routeDish = routeDish;
+ this.areaId = areaId;
+ this.asNum = asNum;
+ this.domainIdentifier = domainIdentifier;
+ this.routeInstance = routeInstance;
+ this.routerIdentifier = routerIdentifier;
+ }
+
+ /**
+ * Obtains Route Distinguisher of Ip Device.
+ *
+ * @return Area ID
+ */
+ public RouteDistinguisher routeDish() {
+ return routeDish;
+ }
+
+ /**
+ * Obtains Area ID if Ip Device.
+ *
+ * @return Area ID
+ */
+ public AreaId areaId() {
+ return areaId;
+ }
+
+ /**
+ * Obtains AS number of Ip Device.
+ *
+ * @return AS number
+ */
+ public AsNumber asNum() {
+ return asNum;
+ }
+
+ /**
+ * Obtains domain identifier of Ip Device.
+ *
+ * @return domain identifier
+ */
+ public DomainId domainIdentifier() {
+ return domainIdentifier;
+ }
+
+ /**
+ * Obtains Router id of Ip Device.
+ *
+ * @return Router id
+ */
+ public RouteIdentifier routerIdentifier() {
+ return routerIdentifier;
+ }
+
+ /**
+ * Obtains routing protocol instance.
+ *
+ * @return routing protocol instance
+ */
+ public RouteInstance routeInstance() {
+ return routeInstance;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(routeDish, areaId, asNum, domainIdentifier, routerIdentifier, routeInstance);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj instanceof IpDeviceIdentifier) {
+ IpDeviceIdentifier other = (IpDeviceIdentifier) obj;
+ return Objects.equals(areaId, other.areaId) && Objects.equals(asNum, other.asNum)
+ && Objects.equals(domainIdentifier, other.domainIdentifier)
+ && Objects.equals(routerIdentifier, other.routerIdentifier)
+ && Objects.equals(routeInstance, other.routeInstance)
+ && Objects.equals(routeDish, other.routeDish);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .omitNullValues()
+ .add("areaId", areaId)
+ .add("asNum", asNum)
+ .add("domainIdentifier", domainIdentifier)
+ .add("routerIdentifier", routerIdentifier)
+ .add("routeInstance", routeInstance)
+ .add("routeDish", routeDish)
+ .toString();
+ }
+}
\ No newline at end of file diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/IpLink.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/IpLink.java new file mode 100644 index 00000000..d632d2db --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/IpLink.java @@ -0,0 +1,54 @@ +/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.iptopology.api;
+
+import org.onosproject.net.Annotated;
+import org.onosproject.net.NetworkResource;
+import org.onosproject.net.Provided;
+
+/**
+ * Abstraction of a network ip link.
+ */
+public interface IpLink extends Annotated, Provided, NetworkResource {
+
+ /**
+ * Returns source termination point of link.
+ *
+ * @return source termination point of link
+ */
+ TerminationPoint src();
+
+ /**
+ * Returns destination termination point of link.
+ *
+ * @return destination termination point of link
+ */
+ TerminationPoint dst();
+
+ /**
+ * Returns link identifier details.
+ *
+ * @return link identifier details
+ */
+ IpLinkIdentifier linkIdentifier();
+
+ /**
+ * Returns the link traffic engineering parameters.
+ *
+ * @return links traffic engineering parameters
+ */
+ LinkTed linkTed();
+}
\ No newline at end of file diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/IpLinkIdentifier.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/IpLinkIdentifier.java new file mode 100644 index 00000000..8522f945 --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/IpLinkIdentifier.java @@ -0,0 +1,161 @@ +/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.iptopology.api;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+import java.util.Objects;
+
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip6Address;
+
+/**
+ * Represents Ip Link Identifier.
+ */
+public class IpLinkIdentifier {
+ private final InterfaceIdentifier localIndentifier;
+ private final InterfaceIdentifier remoteIndentifier;
+ private final Ip4Address localIpv4Addr;
+ private final Ip4Address remoteIpv4Addr;
+ private final Ip6Address localIpv6Addr;
+ private final Ip6Address remoteIpv6Addr;
+ private final TopologyId topologyId;
+
+ /**
+ * Constructor to initialize its parameters.
+ *
+ * @param localIndentifier local interface identifier of the link
+ * @param remoteIndentifier remote interface identifier of the link
+ * @param localIpv4Addr local IPv4 address of the link
+ * @param remoteIpv4Addr remote IPv4 address of the link
+ * @param localIpv6Addr local IPv6 address of the link
+ * @param remoteIpv6Addr remote IPv6 address of the link
+ * @param topologyId link topology identifier
+ */
+ public IpLinkIdentifier(InterfaceIdentifier localIndentifier, InterfaceIdentifier remoteIndentifier,
+ Ip4Address localIpv4Addr, Ip4Address remoteIpv4Addr, Ip6Address localIpv6Addr,
+ Ip6Address remoteIpv6Addr, TopologyId topologyId) {
+ this.localIndentifier = localIndentifier;
+ this.remoteIndentifier = remoteIndentifier;
+ this.localIpv4Addr = localIpv4Addr;
+ this.remoteIpv4Addr = remoteIpv4Addr;
+ this.localIpv6Addr = localIpv6Addr;
+ this.remoteIpv6Addr = remoteIpv6Addr;
+ this.topologyId = topologyId;
+ }
+
+ /**
+ * Obtains link local identifier.
+ *
+ * @return link local identifier
+ */
+ public InterfaceIdentifier localIndentifier() {
+ return localIndentifier;
+ }
+
+ /**
+ * Obtains link local identifier.
+ *
+ * @return link local identifier
+ */
+ public InterfaceIdentifier remoteIndentifier() {
+ return remoteIndentifier;
+ }
+
+ /**
+ * Obtains local IPv4 address of the link.
+ *
+ * @return local IPv4 address of the link
+ */
+ public Ip4Address localIpv4Addr() {
+ return localIpv4Addr;
+ }
+
+ /**
+ * Obtains remote IPv4 address of the link.
+ *
+ * @return remote IPv4 address of the link
+ */
+ public Ip4Address remoteIpv4Addr() {
+ return remoteIpv4Addr;
+ }
+
+ /**
+ * Obtains local IPv6 address of the link.
+ *
+ * @return local IPv6 address of the link
+ */
+ public Ip6Address localIpv6Addr() {
+ return localIpv6Addr;
+ }
+
+ /**
+ * Obtains remote IPv6 address of the link.
+ *
+ * @return remote IPv6 address of the link
+ */
+ public Ip6Address remoteIpv6Addr() {
+ return remoteIpv6Addr;
+ }
+
+ /**
+ * Obtains Topology ID of the link.
+ *
+ * @return Topology ID of the link
+ */
+ public TopologyId topologyId() {
+ return topologyId;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(localIndentifier, remoteIndentifier, localIpv4Addr, remoteIpv4Addr,
+ localIpv6Addr, remoteIpv6Addr, topologyId);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj instanceof IpLinkIdentifier) {
+ IpLinkIdentifier other = (IpLinkIdentifier) obj;
+ return Objects.equals(topologyId, other.topologyId)
+ && Objects.equals(localIndentifier, other.localIndentifier)
+ && Objects.equals(remoteIndentifier, other.remoteIndentifier)
+ && Objects.equals(localIpv4Addr, other.localIpv4Addr)
+ && Objects.equals(remoteIpv4Addr, other.remoteIpv4Addr)
+ && Objects.equals(localIpv6Addr, other.localIpv6Addr)
+ && Objects.equals(remoteIpv6Addr, other.remoteIpv6Addr);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .omitNullValues()
+ .add("localIndentifier", localIndentifier)
+ .add("remoteIndentifier", remoteIndentifier)
+ .add("localIpv4Addr", localIpv4Addr)
+ .add("remoteIpv4Addr", remoteIpv4Addr)
+ .add("localIpv6Addr", localIpv6Addr)
+ .add("remoteIpv6Addr", remoteIpv6Addr)
+ .add("topologyId", topologyId)
+ .toString();
+ }
+}
\ No newline at end of file diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/IpReachability.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/IpReachability.java new file mode 100644 index 00000000..8fdd4d31 --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/IpReachability.java @@ -0,0 +1,73 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.iptopology.api; + +import static com.google.common.base.MoreObjects.toStringHelper; + +import java.util.Objects; + +import org.onlab.packet.IpPrefix; + +/** + * Provides information of IP address prefix in the IGP topology and a router advertises + * this to each of its BGP nexthop. + */ +public class IpReachability { + private final IpPrefix ipPrefix; + + /** + * Constructor to initialize IP prefix. + * + * @param ipPrefix IP address prefix + */ + public IpReachability(IpPrefix ipPrefix) { + this.ipPrefix = ipPrefix; + } + + /** + * Provides IP Address prefix reachability. + * + * @return IP Address prefix + */ + public IpPrefix ipPrefix() { + return ipPrefix; + } + + @Override + public int hashCode() { + return Objects.hash(ipPrefix); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj instanceof IpReachability) { + IpReachability other = (IpReachability) obj; + return Objects.equals(ipPrefix, other.ipPrefix); + } + return false; + } + + @Override + public String toString() { + return toStringHelper(this) + .add("ipPrefix", ipPrefix) + .toString(); + } +}
\ No newline at end of file diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/IsIsPseudonode.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/IsIsPseudonode.java new file mode 100644 index 00000000..064d830b --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/IsIsPseudonode.java @@ -0,0 +1,93 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.iptopology.api; + +import static com.google.common.base.MoreObjects.toStringHelper; + +import java.util.Objects; + +/** + * Represents the Pseudonode information of device in ISIS domain. + */ +public class IsIsPseudonode implements RouteIdentifier { + private final IsoNodeId isoNodeId; + private final byte psnIdentifier; + private final ProtocolType type; + + /** + * Constructor to initialize the values. + * + * @param isoNodeId ISO system-ID + * @param psnIdentifier Pseudonode identifier + * @param type Protocol ID + */ + public IsIsPseudonode(IsoNodeId isoNodeId, byte psnIdentifier, ProtocolType type) { + this.isoNodeId = isoNodeId; + this.psnIdentifier = psnIdentifier; + this.type = type; + } + + /** + * Obtains iso system id of Pseudonode of device in ISIS domain. + * + * @return ISO system Id + */ + public IsoNodeId isoNodeId() { + return isoNodeId; + } + + /** + * Obtains Pseudonode identifier. + * + * @return Pseudonode identifier + */ + public byte psnIdentifier() { + return psnIdentifier; + } + + @Override + public ProtocolType type() { + return type; + } + + @Override + public int hashCode() { + return Objects.hash(isoNodeId, psnIdentifier, type); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj instanceof IsIsPseudonode) { + IsIsPseudonode other = (IsIsPseudonode) obj; + return Objects.equals(isoNodeId, other.isoNodeId) && Objects.equals(psnIdentifier, other.psnIdentifier) + && Objects.equals(type, other.type); + } + return false; + } + + @Override + public String toString() { + return toStringHelper(this) + .add("isoNodeId", isoNodeId) + .add("psnIdentifier", psnIdentifier) + .add("type", type) + .toString(); + } +}
\ No newline at end of file diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/IsoNodeId.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/IsoNodeId.java new file mode 100644 index 00000000..8bb3d8b9 --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/IsoNodeId.java @@ -0,0 +1,79 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.iptopology.api; + +import static com.google.common.base.MoreObjects.toStringHelper; + +import java.util.Objects; + +/** + * Represents ISO system id of the device. + */ +public class IsoNodeId implements RouteIdentifier { + private final byte[] isoNodeId; + private final ProtocolType type; + + /** + * Constructor to initialize the values. + * + * @param isoNodeId ISO system-ID + * @param type Protocol type + */ + public IsoNodeId(byte[] isoNodeId, ProtocolType type) { + this.isoNodeId = isoNodeId; + this.type = type; + } + + /** + * Obtains ISO system id of the device. + * + * @return ISO system id + */ + public byte[] isoNodeId() { + return isoNodeId; + } + + @Override + public ProtocolType type() { + return type; + } + + @Override + public int hashCode() { + return Objects.hash(isoNodeId, type); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj instanceof IsoNodeId) { + IsoNodeId other = (IsoNodeId) obj; + return Objects.equals(isoNodeId, other.isoNodeId) && Objects.equals(type, other.type); + } + return false; + } + + @Override + public String toString() { + return toStringHelper(this) + .add("isoNodeId", isoNodeId) + .add("type", type) + .toString(); + } +}
\ No newline at end of file diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/LinkTed.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/LinkTed.java new file mode 100644 index 00000000..3a686034 --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/LinkTed.java @@ -0,0 +1,349 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.iptopology.api; + +import static com.google.common.base.MoreObjects.toStringHelper; + +import java.util.Iterator; +import java.util.List; +import java.util.Objects; + +import org.onlab.packet.Ip4Address; +import org.onlab.packet.Ip6Address; +import org.onlab.util.Bandwidth; + +/** + * Represents Link Traffic engineering parameters. + */ +public class LinkTed { + private final Bandwidth maximumLink; + private final Bandwidth maxReserved; + private final List<Bandwidth> maxUnResBandwidth; + private final Metric teMetric; + private final Metric igpMetric; + private final List<Ip4Address> ipv4LocRouterId; + private final List<Ip6Address> ipv6LocRouterId; + private final List<Ip4Address> ipv4RemRouterId; + private final List<Ip6Address> ipv6RemRouterId; + private final Color color; + private final Signalling signalType; + private final List<Srlg> srlgGroup; + private final ProtectionType protectType; + + /** + * Constructor to initialize its parameter. + * + * @param maximumLink maximum bandwidth can be used + * @param maxReserved max bandwidth that can be reserved + * @param maxUnResBandwidth amount of bandwidth reservable + * @param teMetric Traffic engineering metric + * @param igpMetric IGP metric + * @param color information on administrative group assigned to the interface + * @param signalType MPLS signaling protocols + * @param srlgGroup Shared Risk Link Group information + * @param protectType protection capabilities of the link + * @param ipv4LocRouterId IPv4 router-Id of local node + * @param ipv6LocRouterId IPv6 router-Id of local node + * @param ipv4RemRouterId IPv4 router-Id of remote node + * @param ipv6RemRouterId IPv6 router-Id of remote node + */ + public LinkTed(Bandwidth maximumLink, Bandwidth maxReserved, List<Bandwidth> maxUnResBandwidth, + Metric teMetric, Metric igpMetric, Color color, Signalling signalType, List<Srlg> srlgGroup, + ProtectionType protectType, List<Ip4Address> ipv4LocRouterId, List<Ip6Address> ipv6LocRouterId, + List<Ip4Address> ipv4RemRouterId, List<Ip6Address> ipv6RemRouterId) { + this.maximumLink = maximumLink; + this.maxReserved = maxReserved; + this.maxUnResBandwidth = maxUnResBandwidth; + this.teMetric = teMetric; + this.igpMetric = igpMetric; + this.color = color; + this.signalType = signalType; + this.srlgGroup = srlgGroup; + this.protectType = protectType; + this.ipv4LocRouterId = ipv4LocRouterId; + this.ipv6LocRouterId = ipv6LocRouterId; + this.ipv4RemRouterId = ipv4RemRouterId; + this.ipv6RemRouterId = ipv6RemRouterId; + } + + /** + * Provides maximum bandwidth can be used on the link. + * + * @return maximum bandwidth + */ + public Bandwidth maximumLink() { + return maximumLink; + } + + /** + * Amount of bandwidth reservable on the link. + * + * @return unreserved bandwidth + */ + public List<Bandwidth> maxUnResBandwidth() { + return maxUnResBandwidth; + } + + /** + * Provides max bandwidth that can be reserved on the link. + * + * @return max bandwidth reserved + */ + public Bandwidth maxReserved() { + return maxReserved; + } + + /** + * Provides Traffic engineering metric for the link. + * + * @return Traffic engineering metric + */ + public Metric teMetric() { + return teMetric; + } + + /** + * Provides IGP metric for the link. + * + * @return IGP metric + */ + public Metric igpMetric() { + return igpMetric; + } + + /** + * Provides protection capabilities of the link. + * + * @return link protection type + */ + public ProtectionType protectType() { + return protectType; + } + + /** + * Provides Shared Risk Link Group information. + * + * @return Shared Risk Link Group value + */ + public List<Srlg> srlgGroup() { + return srlgGroup; + } + + /** + * Provides which MPLS signaling protocols are enabled. + * + * @return signal type + */ + public Signalling signalType() { + return signalType; + } + + /** + * Provides information on administrative group assigned to the interface. + * + * @return 4-octect bit mask assigned by network administrator + */ + public Color color() { + return color; + } + + /** + * Provides IPv4 router-Id of local node. + * + * @return IPv4 router-Id of local node + */ + public List<Ip4Address> ipv4LocRouterId() { + return ipv4LocRouterId; + } + + /** + * Provides IPv6 router-Id of local node. + * + * @return IPv6 router-Id of local node + */ + public List<Ip6Address> ipv6LocRouterId() { + return ipv6LocRouterId; + } + + /** + * Provides IPv4 router-Id of remote node. + * + * @return IPv4 router-Id of remote node + */ + public List<Ip4Address> ipv4RemRouterId() { + return ipv4RemRouterId; + } + + /** + * Provides IPv6 router-Id of remote node. + * + * @return IPv6 router-Id of remote node + */ + public List<Ip6Address> ipv6RemRouterId() { + return ipv6RemRouterId; + } + + @Override + public int hashCode() { + return Objects.hash(maximumLink, maxReserved, maxUnResBandwidth, teMetric, igpMetric, + ipv4LocRouterId, ipv6LocRouterId, ipv4RemRouterId, ipv6RemRouterId, + color, signalType, srlgGroup, protectType); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj instanceof LinkTed) { + int countCommonBandwidth = 0; + int countOtherCommonBandwidth = 0; + int countOther4LocRouterId = 0; + int countCommon4LocRouterId = 0; + int countOther6RemRouterId = 0; + int countCommon6RemRouterId = 0; + int countOther4RemRouterId = 0; + int countCommon4RemRouterId = 0; + int countCommon6LocRouterId = 0; + int countOther6LocRouterId = 0; + int countCommonSrlg = 0; + int countOtherSrlg = 0; + boolean isCommonBandwidth = true; + boolean isCommonIp4Loc = true; + boolean isCommonIp4Rem = true; + boolean isCommonIp6Loc = true; + boolean isCommonIp6Rem = true; + boolean isCommonSrlg = true; + LinkTed other = (LinkTed) obj; + Iterator<Bandwidth> objListIterator = other.maxUnResBandwidth.iterator(); + countOtherCommonBandwidth = other.maxUnResBandwidth.size(); + countCommonBandwidth = maxUnResBandwidth.size(); + + Iterator<Ip4Address> ipv4local = other.ipv4LocRouterId.iterator(); + countOther4LocRouterId = other.ipv4LocRouterId.size(); + countCommon4LocRouterId = ipv4LocRouterId.size(); + + Iterator<Ip4Address> ipv4remote = other.ipv4RemRouterId.iterator(); + countOther4RemRouterId = other.ipv4RemRouterId.size(); + countCommon4RemRouterId = ipv4RemRouterId.size(); + + Iterator<Ip6Address> ipv6local = other.ipv6LocRouterId.iterator(); + countOther6LocRouterId = other.ipv6LocRouterId.size(); + countCommon6LocRouterId = ipv6LocRouterId.size(); + + Iterator<Ip6Address> ipv6remote = other.ipv6RemRouterId.iterator(); + countOther6RemRouterId = other.ipv6RemRouterId.size(); + countCommon6RemRouterId = ipv6RemRouterId.size(); + + Iterator<Srlg> srlg = other.srlgGroup.iterator(); + countOtherSrlg = other.srlgGroup.size(); + countCommonSrlg = srlgGroup.size(); + + if (countOtherCommonBandwidth != countCommonBandwidth + || countOther4LocRouterId != countCommon4LocRouterId + || countOther4RemRouterId != countCommon4RemRouterId + || countOther6LocRouterId != countCommon6LocRouterId + || countOther6RemRouterId != countCommon6RemRouterId + || countOtherSrlg != countCommonSrlg) { + return false; + } else { + while (objListIterator.hasNext() && isCommonBandwidth) { + Bandwidth subTlv = objListIterator.next(); + if (maxUnResBandwidth.contains(subTlv) && other.maxUnResBandwidth.contains(subTlv)) { + isCommonBandwidth = Objects.equals(maxUnResBandwidth.get(maxUnResBandwidth.indexOf(subTlv)), + other.maxUnResBandwidth.get(other.maxUnResBandwidth.indexOf(subTlv))); + } else { + isCommonBandwidth = false; + } + } + while (ipv4local.hasNext() && isCommonIp4Loc) { + Ip4Address subTlv = ipv4local.next(); + if (ipv4LocRouterId.contains(subTlv) && other.ipv4LocRouterId.contains(subTlv)) { + isCommonIp4Loc = Objects.equals(ipv4LocRouterId.get(ipv4LocRouterId.indexOf(subTlv)), + other.ipv4LocRouterId.get(other.ipv4LocRouterId.indexOf(subTlv))); + } else { + isCommonIp4Loc = false; + } + } + while (ipv4remote.hasNext() && isCommonIp4Rem) { + Ip4Address subTlv = ipv4remote.next(); + if (ipv4RemRouterId.contains(subTlv) && other.ipv4RemRouterId.contains(subTlv)) { + isCommonIp4Rem = Objects.equals(ipv4RemRouterId.get(ipv4RemRouterId.indexOf(subTlv)), + other.ipv4RemRouterId.get(other.ipv4RemRouterId.indexOf(subTlv))); + } else { + isCommonIp4Rem = false; + } + } + while (ipv6remote.hasNext() && isCommonIp6Rem) { + Ip6Address subTlv = ipv6remote.next(); + if (ipv6RemRouterId.contains(subTlv) && other.ipv6RemRouterId.contains(subTlv)) { + isCommonIp6Rem = Objects.equals(ipv6RemRouterId.get(ipv6RemRouterId.indexOf(subTlv)), + other.ipv6RemRouterId.get(other.ipv6RemRouterId.indexOf(subTlv))); + } else { + isCommonIp6Rem = false; + } + } + while (ipv6local.hasNext() && isCommonIp6Loc) { + Ip6Address subTlv = ipv6local.next(); + if (ipv6LocRouterId.contains(subTlv) && other.ipv6LocRouterId.contains(subTlv)) { + isCommonIp6Loc = Objects.equals(ipv6LocRouterId.get(ipv6LocRouterId.indexOf(subTlv)), + other.ipv6LocRouterId.get(other.ipv6LocRouterId.indexOf(subTlv))); + } else { + isCommonIp6Loc = false; + } + } + while (srlg.hasNext() && isCommonIp6Loc) { + Srlg subTlv = srlg.next(); + if (srlgGroup.contains(subTlv) && other.srlgGroup.contains(subTlv)) { + isCommonSrlg = Objects.equals(srlgGroup.get(srlgGroup.indexOf(subTlv)), + other.srlgGroup.get(other.srlgGroup.indexOf(subTlv))); + } else { + isCommonSrlg = false; + } + } + return isCommonBandwidth && isCommonIp4Loc && isCommonIp4Rem && isCommonIp6Rem && isCommonIp6Loc + && isCommonSrlg + && Objects.equals(igpMetric, other.igpMetric) + && Objects.equals(teMetric, other.teMetric) + && Objects.equals(maximumLink, other.maximumLink) + && Objects.equals(protectType, other.protectType) + && Objects.equals(color, other.color) + && Objects.equals(signalType, other.signalType); + } + } + return false; + } + + @Override + public String toString() { + return toStringHelper(this) + .add("igpMetric", igpMetric) + .add("teMetric", teMetric) + .add("maximumLink", maximumLink) + .add("maxReserved", maxReserved) + .add("maxUnResBandwidth", maxUnResBandwidth) + .add("ipv4LocRouterId", ipv4LocRouterId) + .add("ipv4RemRouterId", ipv4RemRouterId) + .add("ipv6LocRouterId", ipv6LocRouterId) + .add("ipv6RemRouterId", ipv6RemRouterId) + .add("protectType", protectType) + .add("color", color) + .add("srlgGroup", srlgGroup) + .add("signalType", signalType) + .toString(); + } +}
\ No newline at end of file diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/Metric.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/Metric.java new file mode 100644 index 00000000..0af95b01 --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/Metric.java @@ -0,0 +1,70 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.iptopology.api; + +import static com.google.common.base.MoreObjects.toStringHelper; + +import java.util.Objects; + +/** + * Represents Traffic engineering metrics. + */ +public class Metric { + private final Integer metric; + + /** + * Constructor to initialize its metric. + * + * @param metric can be TE metric or IGP metric or Prefix metric + */ + public Metric(Integer metric) { + this.metric = metric; + } + + /** + * Obtains traffic engineering metric. + * + * @return traffic engineering metric + */ + public Integer metric() { + return metric; + } + + @Override + public int hashCode() { + return Objects.hash(metric); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj instanceof Metric) { + Metric other = (Metric) obj; + return Objects.equals(metric, other.metric); + } + return false; + } + + @Override + public String toString() { + return toStringHelper(this) + .add("metric", metric) + .toString(); + } +}
\ No newline at end of file diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/OspfPseudonode.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/OspfPseudonode.java new file mode 100644 index 00000000..86d96acb --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/OspfPseudonode.java @@ -0,0 +1,96 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.iptopology.api; + +import static com.google.common.base.MoreObjects.toStringHelper; + +import java.util.Objects; + +import org.onlab.packet.Ip4Address; + +/** + * Represents Pseudonode information of OSFP device. + */ +public class OspfPseudonode implements RouteIdentifier { + private final RouterId designatedRouter; + private final Ip4Address drInterface; + private final ProtocolType type; + + /** + * Constructor to initialize the values. + * + * @param designatedRouter Router Id of designated router + * @param drInterface IP address of Designated Router interface + * @param type Protocol ID + */ + public OspfPseudonode(RouterId designatedRouter, Ip4Address drInterface, ProtocolType type) { + this.designatedRouter = designatedRouter; + this.drInterface = drInterface; + this.type = type; + } + + /** + * Obtains designated Router Id. + * + * @return designated Router Id + */ + public RouterId designatedRouter() { + return designatedRouter; + } + + /** + * Obtains IP address of Designated Router interface. + * + * @return IP address of Designated Router interface + */ + public Ip4Address drInterface() { + return drInterface; + } + + @Override + public ProtocolType type() { + return type; + } + + @Override + public int hashCode() { + return Objects.hash(designatedRouter, drInterface, type); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj instanceof OspfPseudonode) { + OspfPseudonode other = (OspfPseudonode) obj; + return Objects.equals(designatedRouter, other.designatedRouter) + && Objects.equals(drInterface, other.drInterface) + && Objects.equals(type, other.type); + } + return false; + } + + @Override + public String toString() { + return toStringHelper(this) + .add("designatedRouter", designatedRouter) + .add("drInterface", drInterface) + .add("type", type) + .toString(); + } +}
\ No newline at end of file diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/Position.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/Position.java new file mode 100644 index 00000000..f81f9fd3 --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/Position.java @@ -0,0 +1,84 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.iptopology.api; + +import static com.google.common.base.MoreObjects.toStringHelper; + +import java.util.Objects; + +/** + * Represents Position of device in the network. + */ +public class Position { + private final Boolean asbr; + private final Boolean abr; + + /** + * Constructor to set position of device. + * + * @param asbr autonomous system boundary router + * @param abr area boundary router + */ + public Position(Boolean asbr, Boolean abr) { + this.asbr = asbr; + this.abr = abr; + } + + /** + * obtain whether the device is autonomous system boundary router or not. + * + * @return autonomous system boundary router or not + */ + Boolean asbr() { + return asbr; + } + + /** + * obtain whether the device is area boundary router or not. + * + * @return area boundary router or not + */ + Boolean abr() { + return abr; + } + + @Override + public int hashCode() { + return Objects.hash(abr, asbr); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj instanceof Position) { + Position other = (Position) obj; + return Objects.equals(abr, other.abr) && Objects.equals(asbr, other.asbr); + } + return false; + } + + @Override + public String toString() { + return toStringHelper(this) + .omitNullValues() + .add("abrBit", abr) + .add("asbrBit", asbr) + .toString(); + } +}
\ No newline at end of file diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/PrefixIdentifier.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/PrefixIdentifier.java new file mode 100644 index 00000000..b41b5d71 --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/PrefixIdentifier.java @@ -0,0 +1,98 @@ +/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.iptopology.api;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+import java.util.Objects;
+
+/**
+ * This class provides Prefix Identifier details.
+ */
+public class PrefixIdentifier {
+ private final TopologyId topologyId;
+ private final RouteType routeType;
+ private final IpReachability ipReach;
+
+ /**
+ * Constructor to initialize its parameters.
+ *
+ * @param topologyId topology ID of prefix
+ * @param routeType OSPF Route type of the prefix
+ * @param ipReach IP address prefix reachability information
+ */
+ public PrefixIdentifier(TopologyId topologyId, RouteType routeType, IpReachability ipReach) {
+ this.topologyId = topologyId;
+ this.routeType = routeType;
+ this.ipReach = ipReach;
+ }
+
+ /**
+ * Provides topology ID of prefix.
+ *
+ * @return topology id
+ */
+ public TopologyId topologyId() {
+ return this.topologyId;
+ }
+
+ /**
+ * Provides IP address prefix reachability information.
+ *
+ * @return IP address prefix
+ */
+ public IpReachability ipReach() {
+ return this.ipReach;
+ }
+
+ /**
+ * Provides OSPF Route type of the prefix.
+ *
+ * @return Route type
+ */
+ public RouteType routeType() {
+ return this.routeType;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(topologyId, routeType, ipReach);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if (obj instanceof PrefixIdentifier) {
+ PrefixIdentifier other = (PrefixIdentifier) obj;
+ return Objects.equals(topologyId, other.topologyId) && Objects.equals(routeType, other.routeType)
+ && Objects.equals(ipReach, other.ipReach);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return toStringHelper(this)
+ .omitNullValues()
+ .add("routeType", routeType)
+ .add("ipReach", ipReach)
+ .add("topologyId", topologyId)
+ .toString();
+ }
+}
\ No newline at end of file diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/PrefixTed.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/PrefixTed.java new file mode 100644 index 00000000..9f1c40ad --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/PrefixTed.java @@ -0,0 +1,138 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.iptopology.api; + +import static com.google.common.base.MoreObjects.toStringHelper; + +import java.util.Objects; + +import org.onlab.packet.IpAddress; + +/** + * This class provides implementation of prefix traffic engineering data. + */ +public class PrefixTed { + private final IgpFlags igpFlags; + private final RouteTag routeTag; + private final ExtendedRouteTag extendedRouteTag; + private final Metric metric; + private final IpAddress fwdingAddress; + + /** + * Constructor to initialize its parameters. + * + * @param igpFlags igp flags + * @param routeTag ospf route tag + * @param extendedRouteTag isis route tag + * @param metric prefix metric + * @param fwdingAddress forwarding address + */ + /** + * Constructor to initialize its parameters. + * + * @param igpFlags IS-IS and OSPF flags assigned to the prefix + * @param routeTag IGP (ISIS or OSPF) tags of the prefix + * @param extendedRouteTag extended ISIS route tags of the prefix + * @param metric metric of the prefix + * @param fwdingAddress OSPF forwarding address + */ + public PrefixTed(IgpFlags igpFlags, RouteTag routeTag, ExtendedRouteTag extendedRouteTag, + Metric metric, IpAddress fwdingAddress) { + this.igpFlags = igpFlags; + this.routeTag = routeTag; + this.extendedRouteTag = extendedRouteTag; + this.metric = metric; + this.fwdingAddress = fwdingAddress; + } + + /** + * Provides IS-IS and OSPF flags assigned to the prefix. + * + * @return IGP flags + */ + public IgpFlags igpFlags() { + return igpFlags; + } + + /** + * Provides IGP (ISIS or OSPF) tags of the prefix. + * + * @return IGP route tag. + */ + public RouteTag routeTag() { + return routeTag; + } + + /** + * Provides extended ISIS route tags of the prefix. + * + * @return extended IS-IS route tag + */ + public ExtendedRouteTag extendedRouteTag() { + return extendedRouteTag; + } + + /** + * Provides metric of the prefix. + * + * @return prefix metric + */ + public Metric metric() { + return metric; + } + + /** + * Provides OSPF forwarding address. + * + * @return forwarding address + */ + public IpAddress fwdingAddress() { + return fwdingAddress; + } + + + @Override + public int hashCode() { + return Objects.hash(igpFlags, routeTag, extendedRouteTag, metric, fwdingAddress); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj instanceof PrefixTed) { + PrefixTed other = (PrefixTed) obj; + return Objects.equals(igpFlags, other.igpFlags) && Objects.equals(extendedRouteTag, other.extendedRouteTag) + && Objects.equals(routeTag, other.routeTag) && Objects.equals(metric, other.metric) + && Objects.equals(fwdingAddress, other.fwdingAddress); + } + return false; + } + + @Override + public String toString() { + return toStringHelper(this) + .omitNullValues() + .add("igpFlags", igpFlags) + .add("extendedRouteTag", extendedRouteTag) + .add("routeTag", routeTag) + .add("metric", metric) + .add("fwdingAddress", fwdingAddress) + .toString(); + } +}
\ No newline at end of file diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/ProtectionType.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/ProtectionType.java new file mode 100644 index 00000000..be7fb5a9 --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/ProtectionType.java @@ -0,0 +1,97 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.iptopology.api; + +import static com.google.common.base.MoreObjects.toStringHelper; + +import java.util.Objects; + +/** + * Represents protection capabilities of the link. + */ +public class ProtectionType { + private final LinkProtectionType protectionType; + + /** + * Enum to provide Link Protection type. + */ + public enum LinkProtectionType { + Extra_Traffic(1), Unprotected(2), Shared(4), Enhanced(0x20), Dedicated_OneIsToOne(8), + Dedicated_OnePlusOne(0x10), Reserved(0x40); + int value; + + /** + * Constructor to assign value. + * + * @param val link protection type + */ + LinkProtectionType(int val) { + value = val; + } + + /** + * Provides Link protection type. + * + * @return protection type + */ + public byte type() { + return (byte) value; + } + } + + /** + * Constructor to initialize protection type. + * + * @param protectionType link protection type + */ + public ProtectionType(LinkProtectionType protectionType) { + this.protectionType = protectionType; + } + + /** + * Provides protection capabilities of the link. + * + * @return link protection type. + */ + public LinkProtectionType protectionType() { + return protectionType; + } + + @Override + public int hashCode() { + return Objects.hash(protectionType); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj instanceof ProtectionType) { + ProtectionType other = (ProtectionType) obj; + return Objects.equals(protectionType, other.protectionType); + } + return false; + } + + @Override + public String toString() { + return toStringHelper(this) + .add("protectionType", protectionType) + .toString(); + } +}
\ No newline at end of file diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/RouteDistinguisher.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/RouteDistinguisher.java new file mode 100644 index 00000000..b6b83368 --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/RouteDistinguisher.java @@ -0,0 +1,74 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Implementation of RouteDistinguisher. + */ +package org.onosproject.iptopology.api; + +import static com.google.common.base.MoreObjects.toStringHelper; + +import java.util.Objects; + +/** + * Represents Route Distinguisher of device in the network. + */ +public class RouteDistinguisher { + private final Long routeDistinguisher; + + /** + * Constructor to initialize parameters. + * + * @param routeDistinguisher route distinguisher + */ + public RouteDistinguisher(Long routeDistinguisher) { + this.routeDistinguisher = routeDistinguisher; + } + + /** + * Obtain route distinguisher. + * + * @return route distinguisher + */ + public Long routeDistinguisher() { + return routeDistinguisher; + } + + @Override + public int hashCode() { + return Objects.hash(routeDistinguisher); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj instanceof RouteDistinguisher) { + RouteDistinguisher other = (RouteDistinguisher) obj; + return Objects.equals(routeDistinguisher, other.routeDistinguisher); + } + return false; + } + + @Override + public String toString() { + return toStringHelper(this) + .add("routeDistinguisher", routeDistinguisher) + .toString(); + } +}
\ No newline at end of file diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/RouteIdentifier.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/RouteIdentifier.java new file mode 100644 index 00000000..73cda7a6 --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/RouteIdentifier.java @@ -0,0 +1,54 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.iptopology.api; + +/** + * Abstraction of Router ID to identify the router with a distinct IP address. + */ +public interface RouteIdentifier { + /** + * Enum to provide Protocol type. + */ + public enum ProtocolType { + ISIS_LevelOne(1), ISIS_LevelTwo(2), OSPFv2(3), Direct(4), Static_Configuration(5), OSPFv3(6); + int value; + + /** + * Sets protocol ID. + * + * @param val protocol ID + */ + ProtocolType(int val) { + value = val; + } + + /** + * Provides Protocol ID. + * + * @return Protocol ID + */ + public byte getType() { + return (byte) value; + } + } + + /** + * Provides Protocol ID to identify which protocol routing instance is used. + * + * @return Protocol type + */ + ProtocolType type(); +}
\ No newline at end of file diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/RouteInstance.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/RouteInstance.java new file mode 100644 index 00000000..fbca820c --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/RouteInstance.java @@ -0,0 +1,70 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.iptopology.api; + +import static com.google.common.base.MoreObjects.toStringHelper; + +import java.util.Objects; + +/** + * Represents routing universe where the network element belongs. + */ +public class RouteInstance { + private final long routeInstance; + + /** + * Constructor to initialize routeInstance. + * + * @param routeInstance routing protocol instance + */ + public RouteInstance(long routeInstance) { + this.routeInstance = routeInstance; + } + + /** + * Obtain route instance. + * + * @return route instance + */ + public long routeInstance() { + return routeInstance; + } + + @Override + public int hashCode() { + return Objects.hash(routeInstance); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj instanceof RouteInstance) { + RouteInstance other = (RouteInstance) obj; + return Objects.equals(routeInstance, other.routeInstance); + } + return false; + } + + @Override + public String toString() { + return toStringHelper(this) + .add("routeInstance", routeInstance) + .toString(); + } +}
\ No newline at end of file diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/RouteTag.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/RouteTag.java new file mode 100644 index 00000000..f77cc5e6 --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/RouteTag.java @@ -0,0 +1,70 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.iptopology.api; + +import static com.google.common.base.MoreObjects.toStringHelper; + +import java.util.Objects; + +/** + * Represents the igp administrative tags of the prefix. + */ +public class RouteTag { + private final int routeTag; + + /** + * Constructor to initialize its parameter. + * + * @param routeTag IGP route tag + */ + public RouteTag(int routeTag) { + this.routeTag = routeTag; + } + + /** + * Obtains igp administrative tags of the prefix. + * + * @return igp administrative tags of the prefix + */ + public int routeTag() { + return routeTag; + } + + @Override + public int hashCode() { + return Objects.hash(routeTag); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj instanceof RouteTag) { + RouteTag other = (RouteTag) obj; + return Objects.equals(routeTag, other.routeTag); + } + return false; + } + + @Override + public String toString() { + return toStringHelper(this) + .add("routeTag", routeTag) + .toString(); + } +}
\ No newline at end of file diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/RouteType.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/RouteType.java new file mode 100644 index 00000000..11268f6f --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/RouteType.java @@ -0,0 +1,96 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.iptopology.api; + +import static com.google.common.base.MoreObjects.toStringHelper; + +import java.util.Objects; + +/** + * Represents Route type of the prefix in the OSPF domain. + */ +public class RouteType { + private final Type routeType; + + /** + * Enum to provide Route type. + */ + public enum Type { + Intra_Area(1), Inter_Area(2), External_1(3), External_2(4), NSSA_1(5), NSSA_2(6); + int value; + + /** + * Constructor to assign value. + * + * @param val route type + */ + Type(int val) { + value = val; + } + + /** + * Provides route type. + * + * @return route type + */ + public byte type() { + return (byte) value; + } + } + + /** + * Constructor to initialize routeType. + * + * @param routeType Route type + */ + public RouteType(Type routeType) { + this.routeType = routeType; + } + + /** + * Provides Route type of the prefix. + * + * @return Route type + */ + public Type routeType() { + return routeType; + } + + @Override + public int hashCode() { + return Objects.hash(routeType); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj instanceof RouteType) { + RouteType other = (RouteType) obj; + return Objects.equals(routeType, other.routeType); + } + return false; + } + + @Override + public String toString() { + return toStringHelper(this) + .add("routeType", routeType) + .toString(); + } +}
\ No newline at end of file diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/RouterId.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/RouterId.java new file mode 100644 index 00000000..85714cb1 --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/RouterId.java @@ -0,0 +1,78 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.iptopology.api; + +import static com.google.common.base.MoreObjects.toStringHelper; + +import java.util.Objects; + +/** + * Represents Router ID of the device. + */ +public class RouterId implements RouteIdentifier { + private final int routerId; + private final ProtocolType type; + + /** + * Constructor to initialize its parameters. + * + * @param routerId Router ID of designated router + */ + public RouterId(int routerId, ProtocolType type) { + this.routerId = routerId; + this.type = type; + } + + /** + * Obtains Router Id of the device. + * + * @return Router Id of the device + */ + public int routerId() { + return routerId; + } + + @Override + public ProtocolType type() { + return type; + } + + @Override + public int hashCode() { + return Objects.hash(routerId, type); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj instanceof RouterId) { + RouterId other = (RouterId) obj; + return Objects.equals(routerId, other.routerId) && Objects.equals(type, other.type); + } + return false; + } + + @Override + public String toString() { + return toStringHelper(this) + .add("routerId", routerId) + .add("type", type) + .toString(); + } +}
\ No newline at end of file diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/Signalling.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/Signalling.java new file mode 100644 index 00000000..41593977 --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/Signalling.java @@ -0,0 +1,83 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.iptopology.api; + +import static com.google.common.base.MoreObjects.toStringHelper; + +import java.util.Objects; + +/** + * Represents signaling protocols that are enabled. + */ +public class Signalling { + private final Boolean ldp; + private final Boolean rsvpte; + + /** + * Constructor to initialize the values. + * + * @param ldp Label Distribution Protocol whether enabled or not + * @param rsvpte RSVP TE whether enabled or not + */ + public Signalling(Boolean ldp, Boolean rsvpte) { + this.ldp = ldp; + this.rsvpte = rsvpte; + } + + /** + * Obtains whether LDP signalling protocol is enabled or not. + * + * @return LDP signalling protocol is enabled or not + */ + public Boolean ldp() { + return ldp; + } + + /** + * Obtains whether rsvp-te signalling protocol is enabled or not. + * + * @return rsvp-te signalling protocol is enabled or not + */ + public Boolean rsvpte() { + return rsvpte; + } + + @Override + public int hashCode() { + return Objects.hash(ldp, rsvpte); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj instanceof Signalling) { + Signalling other = (Signalling) obj; + return Objects.equals(ldp, other.ldp) && Objects.equals(rsvpte, other.rsvpte); + } + return false; + } + + @Override + public String toString() { + return toStringHelper(this) + .add("ldp", ldp) + .add("rsvpte", rsvpte) + .toString(); + } +}
\ No newline at end of file diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/Srlg.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/Srlg.java new file mode 100644 index 00000000..1f39bad2 --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/Srlg.java @@ -0,0 +1,70 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.iptopology.api; + +import static com.google.common.base.MoreObjects.toStringHelper; + +import java.util.Objects; + +/** + * Represents Shared Risk Link Group information. + */ +public class Srlg { + private final int srlgGroup; + + /** + * Constructor to initialize its parameter. + * + * @param srlgGroup list of Shared Risk Link Group value + */ + public Srlg(int srlgGroup) { + this.srlgGroup = srlgGroup; + } + + /** + * Provides Shared Risk link group. + * + * @return Shared Risk link group value + */ + public int srlgGroup() { + return srlgGroup; + } + + @Override + public int hashCode() { + return Objects.hash(srlgGroup); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj instanceof Srlg) { + Srlg other = (Srlg) obj; + return Objects.equals(srlgGroup, other.srlgGroup); + } + return false; + } + + @Override + public String toString() { + return toStringHelper(this) + .add("srlgGroup", srlgGroup) + .toString(); + } +}
\ No newline at end of file diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/TerminationPoint.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/TerminationPoint.java new file mode 100644 index 00000000..9c21cb46 --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/TerminationPoint.java @@ -0,0 +1,104 @@ +/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.iptopology.api;
+
+import java.util.Objects;
+
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.ElementId;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Abstraction of a network termination point expressed as a pair of the network element identifier and device
+ * interface.
+ */
+public class TerminationPoint {
+ private final ElementId elementId;
+ private final DeviceInterface deviceInterface;
+
+ /**
+ * Constructor to initialize its parameters.
+ *
+ * @param elementId network element identifier
+ * @param deviceInterface device interface
+ */
+ public TerminationPoint(ElementId elementId, DeviceInterface deviceInterface) {
+ this.elementId = elementId;
+ this.deviceInterface = deviceInterface;
+ }
+
+ /**
+ * Returns the network element identifier.
+ *
+ * @return element identifier
+ */
+ public ElementId elementId() {
+ return elementId;
+ }
+
+ /**
+ * Returns the identifier of the infrastructure device if the termination
+ * point belongs to a network element which is indeed an ip
+ * device.
+ *
+ * @return network element identifier as a device identifier
+ * @throws java.lang.IllegalStateException if termination point is not
+ * associated with a device
+ */
+ public DeviceId deviceId() {
+ if (elementId instanceof DeviceId) {
+ return (DeviceId) elementId;
+ }
+ throw new IllegalStateException("Termination point not associated " +
+ "with an ip device");
+ }
+
+ /**
+ * Returns Device interface details.
+ *
+ * @return device interface details
+ */
+ public DeviceInterface deviceInterface() {
+ return deviceInterface;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(elementId, deviceInterface);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof TerminationPoint) {
+ final TerminationPoint other = (TerminationPoint) obj;
+ return Objects.equals(this.elementId, other.elementId)
+ && Objects.equals(this.deviceInterface, other.deviceInterface);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("elementId", elementId)
+ .add("deviceInterface", deviceInterface)
+ .toString();
+ }
+}
\ No newline at end of file diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/TopologyId.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/TopologyId.java new file mode 100644 index 00000000..9d414e35 --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/TopologyId.java @@ -0,0 +1,70 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.iptopology.api; + +import java.util.Objects; + +import com.google.common.base.MoreObjects; + +/** + * Represents Multi-Topology IDs for a network link, node or prefix. + */ +public class TopologyId { + private final short topologyId; + + /** + * Constructor to initialize its parameter. + * + * @param topologyId topology id for node/link/prefix + */ + public TopologyId(short topologyId) { + this.topologyId = topologyId; + } + + /** + * Obtains the topology ID. + * + * @return topology ID + */ + public short topologyId() { + return topologyId; + } + + @Override + public int hashCode() { + return Objects.hash(topologyId); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj instanceof TopologyId) { + TopologyId other = (TopologyId) obj; + return Objects.equals(topologyId, other.topologyId); + } + return false; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("topologyId", topologyId) + .toString(); + } +}
\ No newline at end of file diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/DefaultInterfaceDescription.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/DefaultInterfaceDescription.java new file mode 100644 index 00000000..c7e413d7 --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/DefaultInterfaceDescription.java @@ -0,0 +1,97 @@ +/* + * Copyright 2014 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.iptopology.api.device; + +import com.google.common.base.MoreObjects; +import org.onlab.packet.Ip6Address; +import org.onlab.packet.Ip4Address; +import org.onosproject.iptopology.api.InterfaceIdentifier; +import org.onosproject.net.AbstractDescription; +import org.onosproject.net.SparseAnnotations; + +/** + * Default implementation of immutable Interface description. + */ +public class DefaultInterfaceDescription extends AbstractDescription + implements InterfaceDescription { + + private final InterfaceIdentifier intfId; + private final Ip4Address ipv4Address; + private final Ip6Address ipv6Address; + + + + /** + * Creates an interface description using the supplied information. + * + * @param intfId interface identifier + * @param ipv4Address ipv4 address of an interface + * @param ipv6Address ipv6 address of an interface + * @param annotations optional key/value annotations map + */ + public DefaultInterfaceDescription(InterfaceIdentifier intfId, Ip4Address ipv4Address, + Ip6Address ipv6Address, SparseAnnotations...annotations) { + super(annotations); + this.intfId = intfId; + this.ipv4Address = ipv4Address; + this.ipv6Address = ipv6Address; + } + + /** + * Default constructor for serialization. + */ + private DefaultInterfaceDescription() { + this.intfId = null; + this.ipv4Address = null; + this.ipv6Address = null; + } + + /** + * Creates an interface description using the supplied information. + * + * @param base InterfaceDescription to get basic information from + * @param annotations optional key/value annotations map + */ + public DefaultInterfaceDescription(InterfaceDescription base, + SparseAnnotations annotations) { + this(base.intfId(), base.ipv4Address(), base.ipv6Address(), annotations); + } + + @Override + public InterfaceIdentifier intfId() { + return intfId; + } + + @Override + public Ip4Address ipv4Address() { + return ipv4Address; + } + + @Override + public Ip6Address ipv6Address() { + return ipv6Address; } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("intfId", intfId) + .add("ipv4Address", ipv4Address) + .add("ipv6Address", ipv6Address) + .add("annotations", annotations()) + .toString(); + } + +} diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/DefaultIpDeviceDescription.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/DefaultIpDeviceDescription.java new file mode 100644 index 00000000..889e48a7 --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/DefaultIpDeviceDescription.java @@ -0,0 +1,117 @@ +/* + * Copyright 2014-2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.iptopology.api.device; + +import org.onosproject.iptopology.api.DeviceTed; +import org.onosproject.iptopology.api.IpDeviceIdentifier; +import org.onosproject.net.AbstractDescription; +import org.onosproject.net.SparseAnnotations; + +import java.net.URI; + +import static com.google.common.base.MoreObjects.toStringHelper; +import static com.google.common.base.Preconditions.checkNotNull; +import static org.onosproject.iptopology.api.IpDevice.Type; + +/** + * Default implementation of immutable device description entity. + */ +public class DefaultIpDeviceDescription extends AbstractDescription + implements IpDeviceDescription { + private final URI uri; + private final Type type; + private final IpDeviceIdentifier deviceIdentifier; + private final DeviceTed deviceTed; + + /** + * Creates an ip device description using the supplied information. + * + * @param uri device URI + * @param type device type + * @param deviceIdentifier device manufacturer + * @param deviceTed device Traffic Engineering parameters + * @param annotations optional key/value annotations map + */ + public DefaultIpDeviceDescription(URI uri, Type type, IpDeviceIdentifier deviceIdentifier, + DeviceTed deviceTed, SparseAnnotations... annotations) { + super(annotations); + this.uri = checkNotNull(uri, "Device URI cannot be null"); + this.type = checkNotNull(type, "Device type cannot be null"); + this.deviceIdentifier = deviceIdentifier; + this.deviceTed = deviceTed; + } + + /** + * Creates an ip device description using the supplied information. + * @param base IpDeviceDescription to basic information + * @param annotations Annotations to use. + */ + public DefaultIpDeviceDescription(IpDeviceDescription base, SparseAnnotations... annotations) { + this(base.deviceURI(), base.type(), base.deviceIdentifier(), + base.deviceTed(), annotations); + } + + /** + * Creates an ip device description using the supplied information. + * @param base IpDeviceDescription to basic information (except for type) + * @param type device type + * @param annotations Annotations to use. + */ + public DefaultIpDeviceDescription(IpDeviceDescription base, Type type, SparseAnnotations... annotations) { + this(base.deviceURI(), type, base.deviceIdentifier(), + base.deviceTed(), annotations); + } + + @Override + public URI deviceURI() { + return uri; + } + + @Override + public Type type() { + return type; + } + + @Override + public IpDeviceIdentifier deviceIdentifier() { + return deviceIdentifier; + } + + @Override + public DeviceTed deviceTed() { + return deviceTed; + } + + @Override + public String toString() { + return toStringHelper(this) + .add("uri", uri) + .add("type", type) + .add("devid", deviceIdentifier) + .add("devTed", deviceTed) + .toString(); + } + + /** + * Default constructor for serialization. + */ + private DefaultIpDeviceDescription() { + this.uri = null; + this.type = null; + this.deviceIdentifier = null; + this.deviceTed = null; + } +} diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/DefaultPrefixDescription.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/DefaultPrefixDescription.java new file mode 100644 index 00000000..36cc14a6 --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/DefaultPrefixDescription.java @@ -0,0 +1,86 @@ +/* + * Copyright 2014 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.iptopology.api.device; + +import com.google.common.base.MoreObjects; +import org.onosproject.iptopology.api.PrefixIdentifier; +import org.onosproject.iptopology.api.PrefixTed; +import org.onosproject.net.AbstractDescription; +import org.onosproject.net.SparseAnnotations; + +/** + * Default implementation of immutable Prefix description. + */ +public class DefaultPrefixDescription extends AbstractDescription + implements PrefixDescription { + + private final PrefixIdentifier prefixIdentifier; + private final PrefixTed prefixTed; + + + /** + * Creates prefix description using the supplied information. + * + * @param prefixIdentifier prefix identifier + * @param prefixTed prefix traffic engineering parameters + * @param annotations optional key/value annotations map + */ + public DefaultPrefixDescription(PrefixIdentifier prefixIdentifier, PrefixTed prefixTed, + SparseAnnotations...annotations) { + super(annotations); + this.prefixIdentifier = prefixIdentifier; + this.prefixTed = prefixTed; + } + + /** + * Default constructor for serialization. + */ + private DefaultPrefixDescription() { + this.prefixIdentifier = null; + this.prefixTed = null; + } + + /** + * Creates prefix description using the supplied information. + * + * @param base PrefixDescription to get basic information from + * @param annotations optional key/value annotations map + */ + public DefaultPrefixDescription(PrefixDescription base, + SparseAnnotations annotations) { + this(base.prefixIdentifier(), base.prefixTed(), annotations); + } + + @Override + public PrefixIdentifier prefixIdentifier() { + return prefixIdentifier; + } + + @Override + public PrefixTed prefixTed() { + return prefixTed; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("prefixIdentifier", prefixIdentifier) + .add("prefixTed", prefixTed) + .add("annotations", annotations()) + .toString(); + } + +} diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/InterfaceDescription.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/InterfaceDescription.java new file mode 100644 index 00000000..6e7804d9 --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/InterfaceDescription.java @@ -0,0 +1,51 @@ +/* + * Copyright 2014 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.iptopology.api.device; + +import org.onlab.packet.Ip4Address; +import org.onlab.packet.Ip6Address; +import org.onosproject.iptopology.api.InterfaceIdentifier; +import org.onosproject.net.Description; + + +/** + * Information about an interface. + */ +public interface InterfaceDescription extends Description { + + /** + * Returns the IPv4 Address of an interface. + * + * @return ipv4 address + */ + Ip4Address ipv4Address(); + + /** + * Returns the IPv6 Address of an interface. + * + * @return ipv6 address + */ + Ip6Address ipv6Address(); + + + /** + * Returns the interface id of the interface. + * + * @return interface identifier + */ + InterfaceIdentifier intfId(); + +} diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/IpDeviceDescription.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/IpDeviceDescription.java new file mode 100644 index 00000000..c0a4391d --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/IpDeviceDescription.java @@ -0,0 +1,61 @@ +/* + * Copyright 2014-2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.iptopology.api.device; + +import org.onosproject.iptopology.api.DeviceTed; +import org.onosproject.iptopology.api.IpDevice; +import org.onosproject.iptopology.api.IpDeviceIdentifier; +import org.onosproject.net.Description; + + +import java.net.URI; + +/** + * Carrier of immutable information about an ip device. + */ +public interface IpDeviceDescription extends Description { + + /** + * Protocol/provider specific URI that can be used to encode the identity + * information required to communicate with the ip device externally, e.g. + * datapath ID. + * + * @return provider specific URI for the ip device + */ + URI deviceURI(); + + /** + * Returns the type of the ip device. For ex: Psuedo or actual + * + * @return type of the device + */ + IpDevice.Type type(); + + /** + * Returns the device identifier details. + * + * @return identifier of the device + */ + IpDeviceIdentifier deviceIdentifier(); + + /** + * Returns the traffic engineering parameters of the device. + * + * @return traffic engineering parameters of the device + */ + DeviceTed deviceTed(); + +} diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/IpDeviceEvent.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/IpDeviceEvent.java new file mode 100644 index 00000000..07f263e4 --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/IpDeviceEvent.java @@ -0,0 +1,183 @@ +/* + * Copyright 2014-2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.iptopology.api.device; + +import org.joda.time.LocalDateTime; +import org.onosproject.event.AbstractEvent; +import org.onosproject.iptopology.api.DeviceIntf; +import org.onosproject.iptopology.api.DevicePrefix; +import org.onosproject.iptopology.api.IpDevice; + + +import static com.google.common.base.MoreObjects.toStringHelper; + +/** + * Describes ip device event. + */ +public class IpDeviceEvent extends AbstractEvent<IpDeviceEvent.Type, IpDevice> { + + private final DeviceIntf devInterface; + private final DevicePrefix devicePrefix; + + /** + * Type of device events. + */ + public enum Type { + /** + * Signifies that a new device has been detected. + */ + DEVICE_ADDED, + + /** + * Signifies that some device attributes have changed; excludes + * availability changes. + */ + DEVICE_UPDATED, + + /** + * Signifies that a device has been removed. + */ + DEVICE_REMOVED, + + /** + * Signifies that an interface has been added. + */ + INTERFACE_ADDED, + + /** + * Signifies that an interface has been updated. + */ + INTERFACE_UPDATED, + + /** + * Signifies that an interface has been removed. + */ + INTERFACE_REMOVED, + + /** + * Signifies that a prefix has been added. + */ + PREFIX_ADDED, + + /** + * Signifies that a prefix has been updated. + */ + PREFIX_UPDATED, + + /** + * Signifies that a prefix has been removed. + */ + PREFIX_REMOVED, + + } + + /** + * Creates an event of a given type and for the specified ip device. + * + * @param type device event type + * @param device event device subject + */ + public IpDeviceEvent(Type type, IpDevice device) { + this(type, device, null, null); + } + + /** + * Creates an event of a given type and for the specified device and interface. + * + * @param type device event type + * @param device event device subject + * @param devInterface optional interface subject + */ + public IpDeviceEvent(Type type, IpDevice device, DeviceIntf devInterface) { + this(type, device, devInterface, null); + } + + /** + * Creates an event of a given type and for the specified device and interface. + * + * @param type device event type + * @param device event device subject + * @param devicePrefix optional prefix subject + */ + public IpDeviceEvent(Type type, IpDevice device, DevicePrefix devicePrefix) { + this(type, device, null, devicePrefix); + } + + + /** + * Creates an event of a given type and for the specified device, interface and prefix. + * + * @param type device event type + * @param device event device subject + * @param devInterface optional interface subject + * @param devicePrefix optional prefix subject + */ + public IpDeviceEvent(Type type, IpDevice device, DeviceIntf devInterface, DevicePrefix devicePrefix) { + super(type, device); + this.devInterface = devInterface; + this.devicePrefix = devicePrefix; + } + + + /** + * Creates an event of a given type and for the specified device, interface and time. + * + * @param type device event type + * @param device event device subject + * @param devInterface optional interface subject + * @param devicePrefix optional prefix subject + * @param time occurrence time + */ + + public IpDeviceEvent(Type type, IpDevice device, DeviceIntf devInterface, DevicePrefix devicePrefix, long time) { + super(type, device, time); + this.devInterface = devInterface; + this.devicePrefix = devicePrefix; + } + + + /** + * Returns the interface subject. + * + * @return interface subject or null if the event is not interface specific. + */ + public DeviceIntf deviceInterface() { + return devInterface; + } + + /** + * Returns the prefix subject. + * + * @return prefix subject or null if the event is not prefix specific. + */ + public DevicePrefix prefix() { + return devicePrefix; + } + + @Override + public String toString() { + if (devInterface == null || devicePrefix == null) { + return super.toString(); + } + return toStringHelper(this) + .add("time", new LocalDateTime(time())) + .add("type", type()) + .add("subject", subject()) + .add("interface", devInterface) + .add("prefix", devicePrefix) + .toString(); + } +} diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/IpDeviceListener.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/IpDeviceListener.java new file mode 100644 index 00000000..cd40c405 --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/IpDeviceListener.java @@ -0,0 +1,24 @@ +/* + * Copyright 2014 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.iptopology.api.device; + +import org.onosproject.event.EventListener; + +/** + * Entity capable of receiving ip device related events. + */ +public interface IpDeviceListener extends EventListener<IpDeviceEvent> { +} diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/IpDeviceProvider.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/IpDeviceProvider.java new file mode 100644 index 00000000..67502eb6 --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/IpDeviceProvider.java @@ -0,0 +1,25 @@ +/* + * Copyright 2014 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.iptopology.api.device; + +import org.onosproject.net.provider.Provider; + +/** + * Abstraction of a ip device information provider. + */ +public interface IpDeviceProvider extends Provider { + // Currently there is none to set some information into the network +} diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/IpDeviceProviderRegistry.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/IpDeviceProviderRegistry.java new file mode 100644 index 00000000..74b27415 --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/IpDeviceProviderRegistry.java @@ -0,0 +1,25 @@ +/* + * Copyright 2014 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.iptopology.api.device; + +import org.onosproject.net.provider.ProviderRegistry; + +/** + * Abstraction of a ip device provider registry. + */ +public interface IpDeviceProviderRegistry + extends ProviderRegistry<IpDeviceProvider, IpDeviceProviderService> { +} diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/IpDeviceProviderService.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/IpDeviceProviderService.java new file mode 100644 index 00000000..f84b8b74 --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/IpDeviceProviderService.java @@ -0,0 +1,78 @@ +/* + * Copyright 2014-2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.iptopology.api.device; + +import org.onosproject.net.DeviceId; +import org.onosproject.net.provider.ProviderService; + +import java.util.List; + +/** + * Service through which ip device providers can inject ip device information into + * the core. + */ +public interface IpDeviceProviderService extends ProviderService<IpDeviceProvider> { + + /** + * Signals the core that an ip device is added or updated with IP topology information. + * + * @param deviceId device identifier + * @param deviceDescription information about network ip device + */ + void addOrUpdateIpDevice(DeviceId deviceId, IpDeviceDescription deviceDescription); + + /** + * Signals the core that an ip device is removed. + * + * @param deviceId identity of the ip device to be removed + */ + void removeIpDevice(DeviceId deviceId); + + /** + * Sends information about all interfaces of a device. It is up to the core to + * determine what has changed. + * + * @param deviceId identity of the ip device + * @param interfaceDescriptions list of device interfaces + */ + void updateInterfaces(DeviceId deviceId, List<InterfaceDescription> interfaceDescriptions); + + /** + * signals interfaces of a device is deleted. + * + * @param deviceId identity of the ip device + * @param interfaceDescriptions list of device interfaces + */ + void removeInterfaces(DeviceId deviceId, List<InterfaceDescription> interfaceDescriptions); + + /** + * Sends information about all ip prefix of a device. It is up to the core to + * determine what has changed. + * + * @param deviceId identity of the ip device + * @param prefixDescriptions list of device ip prefixes + */ + void updatePrefixes(DeviceId deviceId, List<PrefixDescription> prefixDescriptions); + + /** + * signals ip prefix of a device is deleted. + * + * @param deviceId identity of the ip device + * @param prefixDescriptions list of device ip prefixes + */ + void removePrefixes(DeviceId deviceId, List<PrefixDescription> prefixDescriptions); + +} diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/IpDeviceService.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/IpDeviceService.java new file mode 100644 index 00000000..4b126eb3 --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/IpDeviceService.java @@ -0,0 +1,111 @@ +/* + * Copyright 2014-2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.iptopology.api.device; + +import org.onosproject.event.ListenerService; +import org.onosproject.iptopology.api.DeviceIntf; +import org.onosproject.iptopology.api.DevicePrefix; +import org.onosproject.iptopology.api.InterfaceIdentifier; +import org.onosproject.iptopology.api.IpDevice; +import org.onosproject.net.DeviceId; +import org.onlab.packet.Ip4Address; +import org.onlab.packet.Ip6Address; + +import java.util.List; + +/** + * Service for interacting with the inventory of ip devices. + */ +public interface IpDeviceService + extends ListenerService<IpDeviceEvent, IpDeviceListener> { + + /** + * Returns the number of ip devices known to the system. + * + * @return number of infrastructure devices + */ + int getIpDeviceCount(); + + /** + * Returns a collection of the currently known ip + * devices. + * + * @return collection of devices + */ + Iterable<IpDevice> getIpDevices(); + + /** + * Returns a collection of the currently known ip + * devices by device type. + * + * @param type device type + * @return collection of devices + */ + Iterable<IpDevice> getIpDevices(IpDevice.Type type); + + + /** + * Returns the ip device with the specified identifier. + * + * @param deviceId device identifier + * @return device or null if one with the given identifier is not known + */ + IpDevice getIpDevice(DeviceId deviceId); + + /** + * Returns the list of interfaces associated with the device. + * + * @param deviceId device identifier + * @return list of device interfaces + */ + List<DeviceIntf> getInterfaces(DeviceId deviceId); + + /** + * Returns the interface with the specified ipv4 address and hosted by the given device. + * + * @param deviceId device identifier + * @param ipv4Address ipv4 address + * @return device interface + */ + DeviceIntf getInterface(DeviceId deviceId, Ip4Address ipv4Address); + + /** + * Returns the interface with the specified ipv6 address and hosted by the given device. + * + * @param deviceId device identifier + * @param ipv6Address ipv6 address + * @return device interface + */ + DeviceIntf getInterface(DeviceId deviceId, Ip6Address ipv6Address); + + /** + * Returns the interface with the specified interface id and hosted by the given device. + * + * @param deviceId device identifier + * @param intfId interface id + * @return device interface + */ + DeviceIntf getInterface(DeviceId deviceId, InterfaceIdentifier intfId); + + /** + * Returns the list of ip prefix associated with the device. + * + * @param deviceId device identifier + * @return list of device prefixes + */ + List<DevicePrefix> getPrefixes(DeviceId deviceId); + +} diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/IpDeviceStore.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/IpDeviceStore.java new file mode 100644 index 00000000..db1dd429 --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/IpDeviceStore.java @@ -0,0 +1,164 @@ +/* + * Copyright 2014-2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.iptopology.api.device; + +import org.onlab.packet.Ip4Address; +import org.onlab.packet.Ip6Address; +import org.onosproject.iptopology.api.DevicePrefix; +import org.onosproject.iptopology.api.InterfaceIdentifier; +import org.onosproject.iptopology.api.IpDevice; +import org.onosproject.iptopology.api.DeviceIntf; +import org.onosproject.net.DeviceId; +import org.onosproject.net.provider.ProviderId; +import org.onosproject.store.Store; + +import java.util.List; + +/** + * Manages inventory of ip devices; not intended for direct use. + */ +public interface IpDeviceStore extends Store<IpDeviceEvent, IpDeviceStoreDelegate> { + + /** + * Returns the number of ip devices known to the system. + * + * @return number of ip devices + */ + int getIpDeviceCount(); + + /** + * Returns an iterable collection of all ip devices known to the system. + * + * @return ip device collection + */ + Iterable<IpDevice> getIpDevices(); + + + /** + * Returns an ip device with the specified identifier. + * + * @param deviceId device identifier + * @return ip device + */ + IpDevice getIpDevice(DeviceId deviceId); + + /** + * Creates a new infrastructure ip device, or updates an existing one using + * the supplied device description. + * + * @param providerId provider identifier + * @param deviceId device identifier + * @param deviceDescription device description + * @return ready to send event describing what occurred; null if no change + */ + IpDeviceEvent createOrUpdateIpDevice(ProviderId providerId, DeviceId deviceId, + IpDeviceDescription deviceDescription); + + /** + * Administratively removes the specified ip device from the store. + * + * @param deviceId device to be removed + * @return null if no such ip device + */ + IpDeviceEvent removeIpDevice(DeviceId deviceId); + + /** + * Updates the interface of the specified ip device using the given + * list of interface descriptions. The list is assumed to be comprehensive. + * + * @param providerId provider identifier + * @param deviceId ip device identifier + * @param interfaceDescriptions list of interface descriptions + * @return ready to send events describing what occurred; empty list if no change + */ + List<IpDeviceEvent> updateInterfaces(ProviderId providerId, DeviceId deviceId, + List<InterfaceDescription> interfaceDescriptions); + + /** + * Administratively removes the specified interface from the store. + * + * @param deviceId device of the interfaces to be removed + * @param interfaceDescriptions list of interface descriptions + * @return ready to send events describing what occurred. + */ + List<IpDeviceEvent> removeInterfaces(DeviceId deviceId, List<InterfaceDescription> interfaceDescriptions); + + /** + * Returns the list of interfaces that belong to the specified device. + * + * @param deviceId device identifier + * @return list of device interfaces + */ + List<DeviceIntf> getInterfaces(DeviceId deviceId); + + /** + * Returns the specified device interface. + * + * @param deviceId device identifier + * @param ipv4Address ipv4 address of the interface + * @return device interface + */ + DeviceIntf getInterface(DeviceId deviceId, Ip4Address ipv4Address); + + /** + * Returns the specified device interface. + * + * @param deviceId device identifier + * @param ipv6Address ipv6 address of the interface + * @return device interface + */ + DeviceIntf getInterface(DeviceId deviceId, Ip6Address ipv6Address); + + /** + * Returns the specified device interface. + * + * @param deviceId device identifier + * @param intfId interface identifier of the interface + * @return device interface + */ + DeviceIntf getInterface(DeviceId deviceId, InterfaceIdentifier intfId); + + /** + * Updates the prefix information of the specified ip device using the given + * list of prefix descriptions. The list is assumed to be comprehensive. + * + * @param providerId provider identifier + * @param deviceId ip device identifier + * @param prefixDescriptions list of prefix descriptions + * @return ready to send events describing what occurred; empty list if no change + */ + List<IpDeviceEvent> updatePrefixes(ProviderId providerId, DeviceId deviceId, + List<PrefixDescription> prefixDescriptions); + + /** + * Administratively removes the specified prefix from the store. + * + * @param deviceId device of the prefix to be removed + * @param prefixDescriptions list of prefix descriptions + * @return ready to send events describing what occurred. + */ + List<IpDeviceEvent> removePrefixes(DeviceId deviceId, List<PrefixDescription> prefixDescriptions); + + /** + * Returns the list of prefixes that belong to the specified device. + * + * @param deviceId device identifier + * @return list of device prefixes + */ + List<DevicePrefix> getPrefixes(DeviceId deviceId); + +} + diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/IpDeviceStoreDelegate.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/IpDeviceStoreDelegate.java new file mode 100644 index 00000000..14efe064 --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/IpDeviceStoreDelegate.java @@ -0,0 +1,24 @@ +/* + * Copyright 2014 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.iptopology.api.device; + +import org.onosproject.store.StoreDelegate; + +/** + * Infrastructure ip topology store delegate abstraction. + */ +public interface IpDeviceStoreDelegate extends StoreDelegate<IpDeviceEvent> { +} diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/PrefixDescription.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/PrefixDescription.java new file mode 100644 index 00000000..eb1ece33 --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/PrefixDescription.java @@ -0,0 +1,41 @@ +/* + * Copyright 2014 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.iptopology.api.device; + +import org.onosproject.iptopology.api.PrefixIdentifier; +import org.onosproject.iptopology.api.PrefixTed; +import org.onosproject.net.Description; + +/** + * Information about a prefix. + */ +public interface PrefixDescription extends Description { + + /** + * Returns the prefix identifier. + * + * @return prefix identifier + */ + PrefixIdentifier prefixIdentifier(); + + /** + * Returns the prefix Traffic Engineering parameters. + * + * @return prefix Traffic Engineering parameters + */ + PrefixTed prefixTed(); + +} diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/package-info.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/package-info.java new file mode 100644 index 00000000..5e4e29b1 --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/device/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2014 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Ip device model & related services API definitions. + */ +package org.onosproject.iptopology.api.device; diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/DefaultIpLinkDescription.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/DefaultIpLinkDescription.java new file mode 100644 index 00000000..4a3b46d2 --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/DefaultIpLinkDescription.java @@ -0,0 +1,95 @@ +/* + * Copyright 2014 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.iptopology.api.link; + +import com.google.common.base.MoreObjects; +import org.onosproject.iptopology.api.IpLinkIdentifier; +import org.onosproject.iptopology.api.LinkTed; +import org.onosproject.iptopology.api.TerminationPoint; +import org.onosproject.net.AbstractDescription; +import org.onosproject.net.SparseAnnotations; + +/** + * Default implementation of immutable ip link description entity. + */ +public class DefaultIpLinkDescription extends AbstractDescription + implements IpLinkDescription { + + private final TerminationPoint src; + private final TerminationPoint dst; + private final IpLinkIdentifier linkIdentifier; + private final LinkTed linkTed; + + /** + * Creates an ip link description using the supplied information. + * + * @param src link source + * @param dst link destination + * @param linkIdentifier link identifier + * @param linkTed link traffic engineering parameters + * @param annotations optional key/value annotations + */ + public DefaultIpLinkDescription(TerminationPoint src, TerminationPoint dst, + IpLinkIdentifier linkIdentifier, LinkTed linkTed, + SparseAnnotations... annotations) { + super(annotations); + this.src = src; + this.dst = dst; + this.linkIdentifier = linkIdentifier; + this.linkTed = linkTed; + } + + /** + * Creates an ip link description using the supplied information. + * + * @param base IpLinkDescription to basic information + * @param annotations optional key/value annotations + */ + public DefaultIpLinkDescription(IpLinkDescription base, SparseAnnotations... annotations) { + this(base.src(), base.dst(), base.linkIdentifier(), + base.linkTed(), annotations); + } + + @Override + public TerminationPoint src() { + return src; + } + + @Override + public TerminationPoint dst() { + return dst; + } + + @Override + public IpLinkIdentifier linkIdentifier() { + return linkIdentifier; + } + + @Override + public LinkTed linkTed() { + return linkTed; } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("src", src()) + .add("dst", dst()) + .add("linkIdentifier", linkIdentifier()) + .add("linkTed", linkTed()) + .toString(); + } + +} diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/IpLinkDescription.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/IpLinkDescription.java new file mode 100644 index 00000000..258e7444 --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/IpLinkDescription.java @@ -0,0 +1,55 @@ +/* + * Copyright 2014 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.iptopology.api.link; + +import org.onosproject.iptopology.api.IpLinkIdentifier; +import org.onosproject.iptopology.api.LinkTed; +import org.onosproject.iptopology.api.TerminationPoint; +import org.onosproject.net.Description; + +/** + * Describes an ip link. + */ +public interface IpLinkDescription extends Description { + + /** + * Returns the link source. + * + * @return links source + */ + TerminationPoint src(); + + /** + * Returns the link destination. + * + * @return links destination + */ + TerminationPoint dst(); + + /** + * Returns the link identifier. + * + * @return links identifier informations + */ + IpLinkIdentifier linkIdentifier(); + + /** + * Returns the link traffic engineering parameters. + * + * @return links traffic engineering parameters + */ + LinkTed linkTed(); +} diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/IpLinkEvent.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/IpLinkEvent.java new file mode 100644 index 00000000..4050734a --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/IpLinkEvent.java @@ -0,0 +1,68 @@ +/* + * Copyright 2014 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.iptopology.api.link; + +import org.onosproject.event.AbstractEvent; +import org.onosproject.iptopology.api.IpLink; + +/** + * Describes ip link event. + */ +public class IpLinkEvent extends AbstractEvent<IpLinkEvent.Type, IpLink> { + + /** + * Type of link events. + */ + public enum Type { + /** + * Signifies that a new ip link has been detected. + */ + LINK_ADDED, + + /** + * Signifies that an ip link has been updated or changed state. + */ + LINK_UPDATED, + + /** + * Signifies that an ip link has been removed. + */ + LINK_REMOVED + } + + /** + * Creates an event of a given type and for the specified ip link and the + * current time. + * + * @param type link event type + * @param link event link subject + */ + public IpLinkEvent(Type type, IpLink link) { + super(type, link); + } + + /** + * Creates an event of a given type and for the specified ip link and time. + * + * @param type link event type + * @param link event link subject + * @param time occurrence time + */ + public IpLinkEvent(Type type, IpLink link, long time) { + super(type, link, time); + } + +} diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/IpLinkListener.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/IpLinkListener.java new file mode 100644 index 00000000..5acb73aa --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/IpLinkListener.java @@ -0,0 +1,24 @@ +/* + * Copyright 2014 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.iptopology.api.link; + +import org.onosproject.event.EventListener; + +/** + * Entity capable of receiving ip link related events. + */ +public interface IpLinkListener extends EventListener<IpLinkEvent> { +} diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/IpLinkProvider.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/IpLinkProvider.java new file mode 100644 index 00000000..a58bf610 --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/IpLinkProvider.java @@ -0,0 +1,25 @@ +/* + * Copyright 2014 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.iptopology.api.link; + +import org.onosproject.net.provider.Provider; + +/** + * Abstraction of an entity providing information about ip links + * to the core. + */ +public interface IpLinkProvider extends Provider { +} diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/IpLinkProviderRegistry.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/IpLinkProviderRegistry.java new file mode 100644 index 00000000..e060ae68 --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/IpLinkProviderRegistry.java @@ -0,0 +1,25 @@ +/* + * Copyright 2014 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.iptopology.api.link; + +import org.onosproject.net.provider.ProviderRegistry; + +/** + * Abstraction of an ip link provider registry. + */ +public interface IpLinkProviderRegistry + extends ProviderRegistry<IpLinkProvider, IpLinkProviderService> { +} diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/IpLinkProviderService.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/IpLinkProviderService.java new file mode 100644 index 00000000..c2554425 --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/IpLinkProviderService.java @@ -0,0 +1,57 @@ +/* + * Copyright 2014 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.iptopology.api.link; + + +import org.onosproject.iptopology.api.TerminationPoint; +import org.onosproject.net.DeviceId; +import org.onosproject.net.provider.ProviderService; + +/** + * Means for injecting ip link information into the core. + */ +public interface IpLinkProviderService extends ProviderService<IpLinkProvider> { + + /** + * Signals that an ip link is added or updated with IP topology information. + * + * @param linkDescription ip link information + */ + void addOrUpdateIpLink(IpLinkDescription linkDescription); + + /** + * Signals that an ip link has disappeared. + * + * @param linkDescription ip link information + */ + void removeIpLink(IpLinkDescription linkDescription); + + /** + * Signals that ip links associated with the specified + * termination point have vanished. + * + * @param terminationPoint termination point + */ + void removeIpLink(TerminationPoint terminationPoint); + + /** + * Signals that ip links associated with the specified + * device have vanished. + * + * @param deviceId device identifier + */ + void removeIpLink(DeviceId deviceId); +} diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/IpLinkService.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/IpLinkService.java new file mode 100644 index 00000000..723e907b --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/IpLinkService.java @@ -0,0 +1,108 @@ +/* + * Copyright 2014 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.iptopology.api.link; + +import java.util.Set; + +import org.onosproject.event.ListenerService; +import org.onosproject.iptopology.api.IpLink; +import org.onosproject.iptopology.api.TerminationPoint; +import org.onosproject.net.DeviceId; + +/** + * Service for interacting with the inventory of infrastructure links. + */ +public interface IpLinkService + extends ListenerService<IpLinkEvent, IpLinkListener> { + + /** + * Returns the count of all known ip links. + * + * @return number of ip links + */ + int getIpLinkCount(); + + /** + * Returns a collection of all ip links. + * + * @return all ip links + */ + Iterable<IpLink> getIpLinks(); + + + /** + * Returns set of all ip links leading to and from the + * specified ip device. + * + * @param deviceId device identifier + * @return set of ip device links + */ + Set<IpLink> getIpDeviceLinks(DeviceId deviceId); + + /** + * Returns set of all ip links leading from the specified ip device. + * + * @param deviceId device identifier + * @return set of ip device egress links + */ + Set<IpLink> getIpDeviceEgressLinks(DeviceId deviceId); + + /** + * Returns set of all ip links leading to the specified ip device. + * + * @param deviceId device identifier + * @return set of ip device ingress links + */ + Set<IpLink> getIpDeviceIngressLinks(DeviceId deviceId); + + /** + * Returns set of all ip links leading to and from the + * specified termination point. + * + * @param terminationPoint termination point + * @return set of ip links + */ + Set<IpLink> getIpLinks(TerminationPoint terminationPoint); + + /** + * Returns set of all ip links leading from the specified + * termination point. + * + * @param terminationPoint termination point + * @return set of ip device egress links + */ + Set<IpLink> getEgressIpLinks(TerminationPoint terminationPoint); + + /** + * Returns set of all ip links leading to the specified + * termination point. + * + * @param terminationPoint termination point + * @return set of ip device ingress links + */ + Set<IpLink> getIngressIpLinks(TerminationPoint terminationPoint); + + /** + * Returns the ip links between the specified source + * and destination termination points. + * + * @param src source termination point + * @param dst destination termination point + * @return ip link from source to destination; null if none found + */ + IpLink getIpLink(TerminationPoint src, TerminationPoint dst); + +} diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/IpLinkStore.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/IpLinkStore.java new file mode 100644 index 00000000..8f5c60f7 --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/IpLinkStore.java @@ -0,0 +1,115 @@ +/* + * Copyright 2014 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.iptopology.api.link; + +import org.onosproject.iptopology.api.IpLink; +import org.onosproject.iptopology.api.TerminationPoint; +import org.onosproject.net.DeviceId; +import org.onosproject.net.provider.ProviderId; +import org.onosproject.store.Store; + +import java.util.Set; + +/** + * Manages inventory of ip links; not intended for direct use. + */ +public interface IpLinkStore extends Store<IpLinkEvent, IpLinkStoreDelegate> { + + /** + * Returns the number of ip links in the store. + * + * @return number of ip links + */ + int getIpLinkCount(); + + /** + * Returns an iterable collection of all ip links in the inventory. + * + * @return collection of all ip links + */ + Iterable<IpLink> getIpLinks(); + + /** + * Returns all ip links egressing from the specified device. + * + * @param deviceId device identifier + * @return set of ip device links + */ + Set<IpLink> getIpDeviceEgressLinks(DeviceId deviceId); + + /** + * Returns all ip links ingressing from the specified device. + * + * @param deviceId device identifier + * @return set of ip device links + */ + Set<IpLink> getIpDeviceIngressLinks(DeviceId deviceId); + + /** + * Returns the ip link between the two termination points. + * + * @param src source termination point + * @param dst destination termination point + * @return ip link or null if one not found between the termination points + */ + IpLink getIpLink(TerminationPoint src, TerminationPoint dst); + + /** + * Returns all ip links egressing from the specified termination point. + * + * @param src source termination point + * @return set of termination point ip links + */ + Set<IpLink> getEgressIpLinks(TerminationPoint src); + + /** + * Returns all ip links ingressing to the specified termination point. + * + * @param dst destination termination point + * @return set of termination point ip links + */ + Set<IpLink> getIngressIpLinks(TerminationPoint dst); + + /** + * Creates a new ip link, or updates an existing one, based on the given + * information. + * + * @param providerId provider identity + * @param linkDescription ip link description + * @return create or update ip link event, or null if no change resulted + */ + IpLinkEvent createOrUpdateIpLink(ProviderId providerId, + IpLinkDescription linkDescription); + + /** + * Removes ip link, based on the specified information. + * + * @param src ip link source + * @param dst ip link destination + * @return remove or update ip link event, or null if no change resulted + */ + IpLinkEvent removeOrDownIpLink(TerminationPoint src, TerminationPoint dst); + + /** + * Removes ip link based on the specified information. + * + * @param src ip link source + * @param dst ip link destination + * @return remove ip link event, or null if no change resulted + */ + IpLinkEvent removeIpLink(TerminationPoint src, TerminationPoint dst); + +} diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/IpLinkStoreDelegate.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/IpLinkStoreDelegate.java new file mode 100644 index 00000000..9397a499 --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/IpLinkStoreDelegate.java @@ -0,0 +1,24 @@ +/* + * Copyright 2014 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.iptopology.api.link; + +import org.onosproject.store.StoreDelegate; + +/** + * Ip link store delegate abstraction. + */ +public interface IpLinkStoreDelegate extends StoreDelegate<IpLinkEvent> { +} diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/package-info.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/package-info.java new file mode 100644 index 00000000..581c2367 --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/link/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2014 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Ip link model & related services API definitions. + */ +package org.onosproject.iptopology.api.link; diff --git a/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/package-info.java b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/package-info.java new file mode 100644 index 00000000..e1133554 --- /dev/null +++ b/framework/src/onos/apps/iptopology-api/src/main/java/org/onosproject/iptopology/api/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Ip Topology API. + */ +package org.onosproject.iptopology.api; diff --git a/framework/src/onos/apps/openstackswitching/app/features.xml b/framework/src/onos/apps/openstackswitching/app/features.xml index acb07b62..a13c2aaf 100644 --- a/framework/src/onos/apps/openstackswitching/app/features.xml +++ b/framework/src/onos/apps/openstackswitching/app/features.xml @@ -15,7 +15,6 @@ ~ limitations under the License. --> <features xmlns="http://karaf.apache.org/xmlns/features/v1.2.0" name="${project.artifactId}-${project.version}"> - <repository>mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features</repository> <feature name="${project.artifactId}" version="${project.version}" description="${project.description}"> <feature>onos-api</feature> diff --git a/framework/src/onos/apps/openstackswitching/app/pom.xml b/framework/src/onos/apps/openstackswitching/app/pom.xml index 5460faef..7d26f8f2 100644 --- a/framework/src/onos/apps/openstackswitching/app/pom.xml +++ b/framework/src/onos/apps/openstackswitching/app/pom.xml @@ -31,7 +31,6 @@ <description>SONA Openstack Switching applications</description> <properties> - <onos.version>1.4.0-SNAPSHOT</onos.version> <onos.app.name>org.onosproject.openstackswitching</onos.app.name> <web.context>/onos/openstackswitching</web.context> <api.version>1.0.0</api.version> diff --git a/framework/src/onos/apps/pathpainter/pom.xml b/framework/src/onos/apps/pathpainter/pom.xml new file mode 100644 index 00000000..c14294c8 --- /dev/null +++ b/framework/src/onos/apps/pathpainter/pom.xml @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ Copyright 2014 Open Networking Laboratory + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.onosproject</groupId> + <artifactId>onos-apps</artifactId> + <version>1.4.0-SNAPSHOT</version> + <relativePath>../pom.xml</relativePath> + </parent> + + <artifactId>onos-app-pp</artifactId> + <packaging>bundle</packaging> + + <description>Path visualization application</description> + + <properties> + <onos.app.name>org.onosproject.pathpainter</onos.app.name> + </properties> + +</project> diff --git a/framework/src/onos/apps/pathpainter/src/main/java/org/onosproject/pathpainter/PathLink.java b/framework/src/onos/apps/pathpainter/src/main/java/org/onosproject/pathpainter/PathLink.java new file mode 100644 index 00000000..57241705 --- /dev/null +++ b/framework/src/onos/apps/pathpainter/src/main/java/org/onosproject/pathpainter/PathLink.java @@ -0,0 +1,51 @@ +/* + * Copyright 2014,2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.pathpainter; + +import org.onosproject.net.Link; +import org.onosproject.net.LinkKey; +import org.onosproject.ui.topo.BiLink; +import org.onosproject.ui.topo.LinkHighlight; +import org.onosproject.ui.topo.LinkHighlight.Flavor; + +import java.util.Set; + +/** + * Bi-directional link capable of different hilights. + */ +public class PathLink extends BiLink { + + private boolean primary = false; + private boolean secondary = false; + + public PathLink(LinkKey key, Link link) { + super(key, link); + } + + public void computeHilight(Set<Link> selectedLinks, Set<Link> allLinks) { + primary = selectedLinks.contains(this.one()) || + (two() != null && selectedLinks.contains(two())); + secondary = allLinks.contains(this.one()) || + (two() != null && allLinks.contains(two())); + } + + @Override + public LinkHighlight highlight(Enum<?> anEnum) { + Flavor flavor = primary ? Flavor.PRIMARY_HIGHLIGHT : + (secondary ? Flavor.SECONDARY_HIGHLIGHT : Flavor.NO_HIGHLIGHT); + return new LinkHighlight(this.linkId(), flavor); + } +} diff --git a/framework/src/onos/apps/pathpainter/src/main/java/org/onosproject/pathpainter/PathLinkMap.java b/framework/src/onos/apps/pathpainter/src/main/java/org/onosproject/pathpainter/PathLinkMap.java new file mode 100644 index 00000000..9f2ea216 --- /dev/null +++ b/framework/src/onos/apps/pathpainter/src/main/java/org/onosproject/pathpainter/PathLinkMap.java @@ -0,0 +1,30 @@ +/* + * Copyright 2014,2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.pathpainter; + +import org.onosproject.net.Link; +import org.onosproject.net.LinkKey; +import org.onosproject.ui.topo.BiLinkMap; + +/** + * Our concrete link map. + */ +public class PathLinkMap extends BiLinkMap<PathLink> { + @Override + protected PathLink create(LinkKey linkKey, Link link) { + return new PathLink(linkKey, link); + } +} diff --git a/framework/src/onos/apps/pathpainter/src/main/java/org/onosproject/pathpainter/PathPainter.java b/framework/src/onos/apps/pathpainter/src/main/java/org/onosproject/pathpainter/PathPainter.java new file mode 100644 index 00000000..07ce3fe8 --- /dev/null +++ b/framework/src/onos/apps/pathpainter/src/main/java/org/onosproject/pathpainter/PathPainter.java @@ -0,0 +1,86 @@ +/* + * Copyright 2014,2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.pathpainter; + +import com.google.common.collect.ImmutableList; +import org.apache.felix.scr.annotations.Activate; +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Deactivate; +import org.apache.felix.scr.annotations.Reference; +import org.apache.felix.scr.annotations.ReferenceCardinality; +import org.onosproject.ui.UiExtension; +import org.onosproject.ui.UiExtensionService; +import org.onosproject.ui.UiMessageHandlerFactory; +import org.onosproject.ui.UiTopoOverlayFactory; +import org.onosproject.ui.UiView; +import org.onosproject.ui.UiViewHidden; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; + +/** + * Skeletal ONOS UI Topology-Overlay application component. + */ +@Component(immediate = true) +public class PathPainter { + + private static final ClassLoader CL = PathPainter.class.getClassLoader(); + private static final String VIEW_ID = "ppTopov"; + + private final Logger log = LoggerFactory.getLogger(getClass()); + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected UiExtensionService uiExtensionService; + + // List of application views + private final List<UiView> uiViews = ImmutableList.of( + new UiViewHidden(VIEW_ID) + ); + + // Factory for UI message handlers + private final UiMessageHandlerFactory messageHandlerFactory = + () -> ImmutableList.of( + new PathPainterTopovMessageHandler() + ); + + // Factory for UI topology overlays + private final UiTopoOverlayFactory topoOverlayFactory = + () -> ImmutableList.of( + new PathPainterTopovOverlay() + ); + + // Application UI extension + protected UiExtension extension = + new UiExtension.Builder(CL, uiViews) + .resourcePath(VIEW_ID) + .messageHandlerFactory(messageHandlerFactory) + .topoOverlayFactory(topoOverlayFactory) + .build(); + + @Activate + protected void activate() { + uiExtensionService.register(extension); + log.info("Started"); + } + + @Deactivate + protected void deactivate() { + uiExtensionService.unregister(extension); + log.info("Stopped"); + } + +} diff --git a/framework/src/onos/apps/pathpainter/src/main/java/org/onosproject/pathpainter/PathPainterTopovMessageHandler.java b/framework/src/onos/apps/pathpainter/src/main/java/org/onosproject/pathpainter/PathPainterTopovMessageHandler.java new file mode 100644 index 00000000..cf395e49 --- /dev/null +++ b/framework/src/onos/apps/pathpainter/src/main/java/org/onosproject/pathpainter/PathPainterTopovMessageHandler.java @@ -0,0 +1,388 @@ +/* + * Copyright 2014,2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.pathpainter; + +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Sets; +import org.onlab.osgi.ServiceDirectory; +import org.onosproject.net.DeviceId; +import org.onosproject.net.DisjointPath; +import org.onosproject.net.ElementId; +import org.onosproject.net.HostId; +import org.onosproject.net.Link; +import org.onosproject.net.Path; +import org.onosproject.net.device.DeviceService; +import org.onosproject.net.topology.GeoDistanceLinkWeight; +import org.onosproject.net.topology.LinkWeight; +import org.onosproject.net.topology.PathService; +import org.onosproject.net.topology.TopologyEvent; +import org.onosproject.net.topology.TopologyListener; +import org.onosproject.net.topology.TopologyService; +import org.onosproject.ui.RequestHandler; +import org.onosproject.ui.UiConnection; +import org.onosproject.ui.UiMessageHandler; +import org.onosproject.ui.topo.DeviceHighlight; +import org.onosproject.ui.topo.Highlights; +import org.onosproject.ui.topo.HostHighlight; +import org.onosproject.ui.topo.NodeBadge; +import org.onosproject.ui.topo.TopoJson; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Collection; +import java.util.List; +import java.util.Set; + +/** + * Skeletal ONOS UI Topology-Overlay message handler. + */ +public class PathPainterTopovMessageHandler extends UiMessageHandler { + + private static final String PAINTER_CLEAR = "ppTopovClear"; + private static final String PAINTER_SET_SRC = "ppTopovSetSrc"; + private static final String PAINTER_SET_DST = "ppTopovSetDst"; + private static final String PAINTER_SWAP_SRC_DST = "ppTopovSwapSrcDst"; + private static final String PAINTER_SET_MODE = "ppTopovSetMode"; + + private static final String PAINTER_NEXT_PATH = "ppTopovNextPath"; + private static final String PAINTER_PREV_PATH = "ppTopovPrevPath"; + + private static final String ID = "id"; + private static final String MODE = "mode"; + private static final String TYPE = "type"; + private static final String SWITCH = "switch"; + private static final String ENDSTATION = "endstation"; + public static final String DST = "Dst"; + public static final String SRC = "Src"; + private static LinkWeight linkData; + + private final TopologyListener topologyListener = new InternalTopologyListener(); + + private Set<Link> allPathLinks; + private boolean listenersRemoved; + + private enum Mode { + SHORTEST, DISJOINT, GEODATA, SRLG, INVALID + } + + private final Logger log = LoggerFactory.getLogger(getClass()); + + private PathService pathService; + + private ElementId src, dst; + private String srcType, dstType; + private Mode currentMode = Mode.SHORTEST; + private List<Path> paths; + private int pathIndex; + + protected TopologyService topologyService; + + + // ===============-=-=-=-=-=-======================-=-=-=-=-=-=-================================ + + + @Override + public void init(UiConnection connection, ServiceDirectory directory) { + super.init(connection, directory); + pathService = directory.get(PathService.class); + topologyService = directory.get(TopologyService.class); + linkData = new GeoDistanceLinkWeight(directory.get(DeviceService.class)); + addListeners(); + } + + + @Override + public void destroy() { + removeListeners(); + super.destroy(); + } + + @Override + protected Collection<RequestHandler> createRequestHandlers() { + return ImmutableSet.of( + new ClearHandler(), + new SetSrcHandler(), + new SetDstHandler(), + new SwapSrcDstHandler(), + new NextPathHandler(), + new PrevPathHandler(), + new SetModeHandler() + ); + } + + // === ------------------------- + // === Handler classes + + private final class ClearHandler extends RequestHandler { + + public ClearHandler() { + super(PAINTER_CLEAR); + } + + @Override + public void process(long sid, ObjectNode payload) { + src = null; + dst = null; + sendMessage(TopoJson.highlightsMessage(new Highlights())); + } + } + + private final class SetSrcHandler extends RequestHandler { + + public SetSrcHandler() { + super(PAINTER_SET_SRC); + } + + @Override + public void process(long sid, ObjectNode payload) { + String id = string(payload, ID); + src = elementId(id); + srcType = string(payload, TYPE); + if (src.equals(dst)) { + dst = null; + } + sendMessage(TopoJson.highlightsMessage(addBadge(new Highlights(), + srcType, + src.toString(), + SRC))); + findAndSendPaths(currentMode); + } + } + + private final class SetDstHandler extends RequestHandler { + public SetDstHandler() { + super(PAINTER_SET_DST); + } + + @Override + public void process(long sid, ObjectNode payload) { + String id = string(payload, ID); + dst = elementId(id); + dstType = string(payload, TYPE); + if (src.equals(dst)) { + src = null; + } + + sendMessage(TopoJson.highlightsMessage(addBadge(new Highlights(), + dstType, + dst.toString(), + DST))); + findAndSendPaths(currentMode); + } + } + + private final class SwapSrcDstHandler extends RequestHandler { + public SwapSrcDstHandler() { + super(PAINTER_SWAP_SRC_DST); + } + + @Override + public void process(long sid, ObjectNode payload) { + ElementId temp = src; + src = dst; + dst = temp; + String s = srcType; + srcType = dstType; + dstType = s; + findAndSendPaths(currentMode); + } + } + + + + private final class NextPathHandler extends RequestHandler { + public NextPathHandler() { + super(PAINTER_NEXT_PATH); + } + + @Override + public void process(long sid, ObjectNode payload) { + pathIndex = (pathIndex >= paths.size() - 1 ? 0 : pathIndex + 1); + hilightAndSendPaths(); + } + } + + private final class PrevPathHandler extends RequestHandler { + public PrevPathHandler() { + super(PAINTER_PREV_PATH); + } + + @Override + public void process(long sid, ObjectNode payload) { + pathIndex = (pathIndex <= 0 ? paths.size() - 1 : pathIndex - 1); + hilightAndSendPaths(); + } + } + + private final class SetModeHandler extends RequestHandler { + public SetModeHandler() { + super(PAINTER_SET_MODE); + } + + @Override + public void process(long sid, ObjectNode payload) { + String mode = string(payload, MODE); + switch (mode) { + case "shortest": + currentMode = Mode.SHORTEST; + break; + case "disjoint": + currentMode = Mode.DISJOINT; + break; + case "geodata": + currentMode = Mode.GEODATA; + break; + case "srlg": + currentMode = Mode.SRLG; + break; + default: + currentMode = Mode.INVALID; + break; + } + //TODO: add support for SRLG + findAndSendPaths(currentMode); + } + } + + // === ------------ + + private ElementId elementId(String id) { + try { + return DeviceId.deviceId(id); + } catch (IllegalArgumentException e) { + return HostId.hostId(id); + } + } + + private void findAndSendPaths(Mode mode) { + log.info("src={}; dst={}; mode={}", src, dst, currentMode); + if (src != null && dst != null) { + pathIndex = 0; + ImmutableSet.Builder<Link> builder = ImmutableSet.builder(); + if (mode.equals(Mode.SHORTEST)) { + paths = ImmutableList.copyOf(pathService.getPaths(src, dst)); + allPathLinks = buildPaths(builder).build(); + } else if (mode.equals(Mode.DISJOINT)) { + paths = ImmutableList.copyOf(pathService.getDisjointPaths(src, dst)); + allPathLinks = buildDisjointPaths(builder).build(); + } else if (mode.equals(Mode.GEODATA)) { + paths = ImmutableList.copyOf(pathService.getPaths(src, dst, linkData)); + allPathLinks = buildPaths(builder).build(); + } else { + log.info("Unsupported MODE"); + } + } else { + paths = ImmutableList.of(); + allPathLinks = ImmutableSet.of(); + } + hilightAndSendPaths(); + + } + + private ImmutableSet.Builder<Link> buildPaths(ImmutableSet.Builder<Link> pathBuilder) { + paths.forEach(path -> path.links().forEach(pathBuilder::add)); + return pathBuilder; + } + + private ImmutableSet.Builder<Link> buildDisjointPaths(ImmutableSet.Builder<Link> pathBuilder) { + paths.forEach(path -> { + DisjointPath dp = (DisjointPath) path; + pathBuilder.addAll(dp.primary().links()); + pathBuilder.addAll(dp.backup().links()); + }); + return pathBuilder; + } + + private void hilightAndSendPaths() { + PathLinkMap linkMap = new PathLinkMap(); + allPathLinks.forEach(linkMap::add); + + Set<Link> selectedPathLinks; + + // Prepare two working sets; one containing selected path links and + // the other containing all paths links. + if (currentMode.equals(Mode.DISJOINT)) { + DisjointPath dp = (DisjointPath) paths.get(pathIndex); + selectedPathLinks = paths.isEmpty() ? + ImmutableSet.of() : Sets.newHashSet(dp.primary().links()); + selectedPathLinks.addAll(dp.backup().links()); + } else { + selectedPathLinks = paths.isEmpty() ? + ImmutableSet.of() : ImmutableSet.copyOf(paths.get(pathIndex).links()); + } + Highlights highlights = new Highlights(); + for (PathLink plink : linkMap.biLinks()) { + plink.computeHilight(selectedPathLinks, allPathLinks); + highlights.add(plink.highlight(null)); + } + if (src != null) { + highlights = addBadge(highlights, srcType, src.toString(), SRC); + } + if (dst != null) { + highlights = addBadge(highlights, dstType, dst.toString(), DST); + } + sendMessage(TopoJson.highlightsMessage(highlights)); + } + + private Highlights addBadge(Highlights highlights, String type, String elemId, String src) { + if (SWITCH.equals(type)) { + highlights = addDeviceBadge(highlights, elemId, src); + } else if (ENDSTATION.equals(type)) { + highlights = addHostBadge(highlights, elemId, src); + } + return highlights; + } + + private Highlights addDeviceBadge(Highlights h, String elemId, String type) { + DeviceHighlight dh = new DeviceHighlight(elemId); + dh.setBadge(createBadge(type)); + h.add(dh); + return h; + } + + private Highlights addHostBadge(Highlights h, String elemId, String type) { + HostHighlight hh = new HostHighlight(elemId); + hh.setBadge(createBadge(type)); + h.add(hh); + return h; + } + + private NodeBadge createBadge(String type) { + return NodeBadge.text(type); + } + + private synchronized void addListeners() { + listenersRemoved = false; + topologyService.addListener(topologyListener); + } + private synchronized void removeListeners() { + if (!listenersRemoved) { + listenersRemoved = true; + topologyService.removeListener(topologyListener); + } + } + + // Link event listener. + private class InternalTopologyListener implements TopologyListener { + @Override + public void event(TopologyEvent event) { + findAndSendPaths(currentMode); + } + } + +}
\ No newline at end of file diff --git a/framework/src/onos/apps/pathpainter/src/main/java/org/onosproject/pathpainter/PathPainterTopovOverlay.java b/framework/src/onos/apps/pathpainter/src/main/java/org/onosproject/pathpainter/PathPainterTopovOverlay.java new file mode 100644 index 00000000..78f5f905 --- /dev/null +++ b/framework/src/onos/apps/pathpainter/src/main/java/org/onosproject/pathpainter/PathPainterTopovOverlay.java @@ -0,0 +1,56 @@ +/* + * Copyright 2014,2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.pathpainter; + +import org.onosproject.net.DeviceId; +import org.onosproject.net.HostId; +import org.onosproject.ui.UiTopoOverlay; +import org.onosproject.ui.topo.ButtonId; +import org.onosproject.ui.topo.PropertyPanel; + +/** + * Our topology overlay. + */ +public class PathPainterTopovOverlay extends UiTopoOverlay { + + // NOTE: this must match the ID defined in ppTopovOverlay.js + private static final String OVERLAY_ID = "pp-overlay"; + + private static final ButtonId SRC_BUTTON = new ButtonId("src"); + private static final ButtonId DST_BUTTON = new ButtonId("dst"); + + public PathPainterTopovOverlay() { + super(OVERLAY_ID); + } + + @Override + public void deactivate() { + super.deactivate(); + log.debug("PathPainterOverlay Deactivated"); + } + + @Override + public void modifyDeviceDetails(PropertyPanel pp, DeviceId deviceId) { + pp.addButton(SRC_BUTTON).addButton(DST_BUTTON); + } + + @Override + public void modifyHostDetails(PropertyPanel pp, HostId hostId) { + pp.addButton(SRC_BUTTON).addButton(DST_BUTTON); + } + + +} diff --git a/framework/src/onos/apps/pathpainter/src/main/java/org/onosproject/pathpainter/package-info.java b/framework/src/onos/apps/pathpainter/src/main/java/org/onosproject/pathpainter/package-info.java new file mode 100644 index 00000000..e625933b --- /dev/null +++ b/framework/src/onos/apps/pathpainter/src/main/java/org/onosproject/pathpainter/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2014-2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Path visualization GUI topology view overlay. + */ +package org.onosproject.pathpainter;
\ No newline at end of file diff --git a/framework/src/onos/apps/pathpainter/src/main/resources/app/view/ppTopov/ppTopov.css b/framework/src/onos/apps/pathpainter/src/main/resources/app/view/ppTopov/ppTopov.css new file mode 100644 index 00000000..cbf460f9 --- /dev/null +++ b/framework/src/onos/apps/pathpainter/src/main/resources/app/view/ppTopov/ppTopov.css @@ -0,0 +1,2 @@ +/* css for sample app topology overlay */ + diff --git a/framework/src/onos/apps/pathpainter/src/main/resources/app/view/ppTopov/ppTopov.html b/framework/src/onos/apps/pathpainter/src/main/resources/app/view/ppTopov/ppTopov.html new file mode 100644 index 00000000..9141975f --- /dev/null +++ b/framework/src/onos/apps/pathpainter/src/main/resources/app/view/ppTopov/ppTopov.html @@ -0,0 +1,4 @@ +<!-- partial HTML --> +<div id="ov-pp-topov"> + <p>This is a hidden view .. just a placeholder to house the javascript</p> +</div> diff --git a/framework/src/onos/apps/pathpainter/src/main/resources/app/view/ppTopov/ppTopov.js b/framework/src/onos/apps/pathpainter/src/main/resources/app/view/ppTopov/ppTopov.js new file mode 100644 index 00000000..baaaef98 --- /dev/null +++ b/framework/src/onos/apps/pathpainter/src/main/resources/app/view/ppTopov/ppTopov.js @@ -0,0 +1,119 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + Sample Demo module. This contains the "business logic" for the topology + overlay that we are implementing. + */ + +(function () { + 'use strict'; + + // injected refs + var $log, fs, flash, wss; + + // constants + var srcMessage = 'ppTopovSetSrc', + dstMessage = 'ppTopovSetDst', + swapMessage = 'ppTopovSwapSrcDst', + modeMessage = 'ppTopovSetMode', + nextPathMessage = 'ppTopovNextPath', + clearMessage = 'ppTopovClear', + prevPathMessage = 'ppTopovPrevPath'; + + // internal state + var currentMode = null; + + + // === --------------------------- + // === Helper functions + + + // === --------------------------- + // === Main API functions + + function clear() { + wss.sendEvent(clearMessage); + flash.flash('Source node: ' + node.id); + } + + function setSrc(node) { + wss.sendEvent(srcMessage, { + id: node.id, + type: node.type + }); + flash.flash('Source node: ' + node.id); + } + + function setDst(node) { + wss.sendEvent(dstMessage, { + id: node.id, + type: node.type + }); + flash.flash('Destination node: ' + node.id); + } + + function swapSrcDst() { + wss.sendEvent(swapMessage) + flash.flash('Source and destination swap'); + } + + function nextPath() { + wss.sendEvent(nextPathMessage); + } + + function prevPath() { + wss.sendEvent(prevPathMessage); + } + + + function setMode(mode) { + if (currentMode === mode) { + $log.debug('(in mode', mode, 'already)'); + flash.flash('Already in ' + mode + ' mode'); + } else { + currentMode = mode; + wss.sendEvent(modeMessage, { + mode: mode + }); + flash.flash('Path mode: ' + mode); + } + } + + // === --------------------------- + // === Module Factory Definition + + angular.module('ovPpTopov', []) + .factory('PathPainterTopovService', + ['$log', 'FnService', 'FlashService', 'WebSocketService', + + function (_$log_, _fs_, _flash_, _wss_) { + $log = _$log_; + fs = _fs_; + flash = _flash_; + wss = _wss_; + + return { + setSrc: setSrc, + setDst: setDst, + setMode: setMode, + nextPath: nextPath, + prevPath: prevPath, + swapSrcDst: swapSrcDst, + clear: clear + }; + }]); +}()); diff --git a/framework/src/onos/apps/pathpainter/src/main/resources/app/view/ppTopov/ppTopovOverlay.js b/framework/src/onos/apps/pathpainter/src/main/resources/app/view/ppTopov/ppTopovOverlay.js new file mode 100644 index 00000000..f98ed2b7 --- /dev/null +++ b/framework/src/onos/apps/pathpainter/src/main/resources/app/view/ppTopov/ppTopovOverlay.js @@ -0,0 +1,260 @@ +// path painter topology overlay - client side +// +// This is the glue that binds our business logic (in ppTopovDemo.js) +// to the overlay framework. + +(function () { + 'use strict'; + + // injected refs + var $log, tov, pps; + + // internal state should be kept in the service module (not here) + var selection; + + // our overlay definition + var overlay = { + // NOTE: this must match the ID defined in AppUiTopovOverlay + overlayId: 'pp-overlay', + glyphId: 'topo', + tooltip: 'Path Painter Topo Overlay', + + activate: function () { + $log.debug("Path painter topology overlay ACTIVATED"); + }, + deactivate: function () { + pps.clear(); + $log.debug("Path painter topology overlay DEACTIVATED"); + }, + // These glyphs get installed using the overlayId as a prefix. + // e.g. 'src' is installed as 'pp-overlay-src' + // They can be referenced (from this overlay) as '*src' + // That is, the '*' prefix stands in for 'pp-overlay-' + glyphs: { + src: { + vb: '0 0 110 110', + d: 'M28.7,59.3 M14.9,53 M8.7,39 M32.4,92.5H25l-0.2-3.6' + + 'c-0.5-9-5.4-23.9-12.9-33.5c-5.2-6.6-7-12.8-7-16.3c0-13.3,10.7-24,23.8-24c13.1,0,23.8,10.8,23.8,24c0,3.5-1.8,9.7-7,16.3' + + 'C38,65,33.1,80,32.6,88.9L32.4,92.5z M27.9,89.5h1.7l0-0.7c0.5-9.4,5.7-25.2,13.5-35.2c4.7-6,6.4-11.4,6.4-14.5' + + 'c0-11.6-9.3-21-20.8-21C17.3,18,7.9,27.5,7.9,39c0,3,1.7,8.4,6.4,14.5c7.9,10.1,13.1,25.8,13.5,35.2L27.9,89.5z M28.7,83.2' + + 'M28.6,29.8c-4.7,0-8.5,3.8-8.5,8.5c0,4.7,3.8,8.5,8.5,8.5s8.5-3.8,8.5-8.5C37.1,33.6,33.3,29.8,28.6,29.8z M89.6,47 M89.6,29.5' + + 'c-0.1,3.1-0.1,12.8,0,17c0.1,4.2,14.1-5.5,13.9-8.5C103.4,35.1,89.6,25.6,89.6,29.5z M51,38.1L89.5,38 M89.5,39.5l0-3L51,36.5l0,3' + + 'L89.5,39.5z' + }, + dst: { + vb: '0 0 110 110', + d: 'M80.3,59.8 M85.8,92.5h-7.2L78.4,89c-0.4-8.8-5.2-23.6-12.3-33' + + 'c-4.9-6.5-6.7-12.5-6.7-16c0-13,10.2-23.7,22.7-23.7c12.5,0,22.7,10.6,22.7,23.7c0,3.5-1.8,9.5-6.7,16C91.2,65.4,86.4,80.1,86,89' + + 'L85.8,92.5z M81.4,89.5H83l0-0.7c0.5-9.3,5.4-24.8,12.9-34.7c4.5-5.9,6.1-11.2,6.1-14.2c0-11.4-8.9-20.7-19.8-20.7' + + 'c-10.9,0-19.8,9.3-19.8,20.7c0,3,1.6,8.3,6.1,14.2C76,64,80.9,79.5,81.4,88.8L81.4,89.5z M82.1,30.8c-4.5,0-8.1,3.7-8.1,8.4' + + 's3.6,8.4,8.1,8.4c4.5,0,8.1-3.7,8.1-8.4S86.6,30.8,82.1,30.8z M47.2,47.5 M45.2,30.8c-0.1,3.1-0.1,12.6,0,16.7' + + 'c0.1,4.1,13.4-5.4,13.3-8.4C58.4,36.2,45.2,26.9,45.2,30.8z M45.2,39.1L6.7,39.2 M45.2,40.6l0-3L6.7,37.7l0,3L45.2,40.6z' + }, + jp: { + vb: '0 0 110 110', + d: 'M84.3,89.3L58.9,64.2l-1.4,1.4L83,90.7L84.3,89.3z M27,7.6H7.4v19.2H27V7.6z' + + 'M59.3,47.1H39.8v19.2h19.5V47.1z M102.1,79.5H82.6v19.2h19.5V79.5z M41.7,47.6L19,25.1l-1.2,1.2l22.7,22.5L41.7,47.6z' + }, + djp: { + vb: '0 0 110 110', + d: 'M25.8,84l-9.2-57 M27.3,83.8l-9.2-57l-3,0.5l9.2,57L27.3,83.8z M83.2,37.7L26.8,15.5 M83.7,36.1L26.6,14' + + 'l-1,3.2l57,22.1L83.7,36.1z M34.1,95l61.4-40.6 M96.4,55.7l-1.9-2.5L33.2,93.8l1.9,2.5L96.4,55.7z M26.6,27.6H6.7V7.7h19.9V27.6z' + + 'M102.1,36H82.2v19.9h19.9V36z M35.3,83.5H15.3v19.9h19.9V83.5z' + }, + geo: { + vb: '0 0 110 110', + d: 'M55.7,94.6c-0.1-0.3,0-1-0.1-1.4'+ + 'c-0.7-0.5-1.3-2.2-2.1-2.6c-0.5-0.3-1.4-0.2-2-0.5c-0.3-0.1-0.6-0.3-0.9-0.4c-0.4-0.1-0.8-0.1-1.1-0.3c-1.3-0.7-1.9-3-3.5-2.9'+ + 'c-0.7,0-1.3,0.7-1.9,0.7c-0.6,0-1.6-0.5-2.4-0.9c-0.8-0.4-1.6-0.6-2.3-1c-0.5-0.3-0.9-0.9-1.3-1.1C37.8,84,37.2,84,37,83.9'+ + 'c-0.4-0.2-0.8-0.7-1.3-1.1c-0.5-0.4-1-0.9-1-1.4c0-0.6,0.5-1,0.5-1.6c0.2-1.7-1-2.9-1.7-3.9c-0.5-0.7-1.1-1.4-1.7-2.1'+ + 'c0-0.5,0-0.5,0-1c-0.4-0.4-0.7-1.1-1.1-1.7c-0.4-0.6-1.1-1.2-1.2-1.9c-0.1-0.8,0.3-1.5,0-2.3c-0.5-1.3-2-0.7-1.8,1'+ + 'c0.1,0.5,0.6,1.1,0.8,1.6c0.2,0.5,0.1,1.1,0.3,1.6c0.2,0.6,0.7,1,0.8,1.7c0.3,1,0.3,2,0.5,2.7c0.2,0.5,1,1.1,0.6,1.7'+ + 'c-0.6,0.1-0.8-0.5-1.2-0.9c-0.2-0.2-1-0.6-1.1-1.1c-0.1-0.4,0.2-1,0.1-1.5c-0.2-1-2-1-2-2.1c0-0.7,0.8-0.7,0.8-1.4'+ + 'c0-0.7-0.8-1.3-1-1.9c-0.2-0.5-0.2-1.4-0.3-2.2c-0.1-0.7,0-1.5-0.1-2.1c-0.1-0.5-0.8-1.2-1.2-1.4c-0.6-0.3-1-0.2-1.3-0.7'+ + 'c-0.2-0.4-0.4-1.4-0.4-1.9c-0.1-0.9,0-1.8-0.1-2.7c0-0.9-0.1-1.8,0-2.8c0.3-0.7,0.9-1,1.2-1.7c0.2-0.5,0.3-1.1,0.5-1.6'+ + 'c0.5-0.9,1.5-1.8,2.2-2.7c0.7-1,1.4-1.9,1.8-3.1c0.2-0.4,0.6-1.3,0.5-1.8c-0.1-0.7-1.2-1.3-1.1-2.1c0.1-0.5,0.7-0.5,0.9-1'+ + 'c0.1-0.3,0.2-1,0.2-1.3c0-0.7-0.3-1.4-0.2-2.2c0.1-0.6,0.9-0.9,0.5-1.6c-0.4-0.7-1.2,0.4-1.7-0.1c-0.4-0.4,0.1-0.9,0.1-1.7'+ + 'c0-0.3-0.2-0.6-0.1-0.9c0-0.3,0.6-0.9,0.4-1.1c-0.3-0.5-0.7-1.7-1.5-2.2c-0.9-0.5-1.9-0.2-3.2-0.4c-0.8-0.2-1.2-1-1.9-0.9'+ + 'c-0.5,0-0.7,0.6-1.3,0.9c-0.6,0.3-1.4,0.2-2,0.4c-0.6,0.2-0.9,0.6-1.5,0.6c-0.5,0-0.5-0.6-1.1-0.6c-0.2,0-0.7,0.2-1.1,0.2'+ + 'c-1,0.1-2.8,0.2-3.7-0.1c-0.9-0.2-1.5-0.5-2.5-1.1C7.4,28.2,6,27.7,6.1,27c0-0.4,1.3-0.8,1.8-1c0.8-0.3,1.3-0.7,2-0.8'+ + 'c0.2,0,0.6,0.2,0.9,0.1c0.3,0,0.7-0.4,1.1-0.4c0.9-0.1,2.1,0.1,2-0.9c-0.7-0.6-3.4,0.4-3.5-0.9c0-0.8,1-1,1.8-1.2'+ + 'c0.7-0.2,1.8-0.5,2.5-0.4c0.7,0,1.7,1,2.1-0.1c0.2-0.7-0.2-1.3-0.4-1.9c0.5-0.8,1.5-0.7,2.3-0.9c0.9-0.1,1.6-0.3,2.4-0.7'+ + 'c0.7-0.4,1.5-0.6,2.4-0.7c0.9-0.1,1.7-0.5,2.5-0.6c0.6-0.1,1.2,0,1.8-0.1c0.5-0.1,1.1-0.5,1.7-0.4c0.4,0,0.7,0.4,1.1,0.4'+ + 'c0.4,0.1,0.8,0,1.2,0.1c0.3,0.1,0.6,0.3,0.9,0.4c0.5,0.1,1-0.1,1.5,0c0.4,0.1,0.8,0.4,1.2,0.4c1,0.1,2.1-0.1,3.1,0.1'+ + 'c0.4,0.1,0.7,0.3,1.1,0.4c0.4,0.1,0.8,0,1.1,0.1c0.5,0.1,0.9,0.7,1.5,0.7c1,0.1,2.1-0.5,3.1-0.6c0.7-0.1,1.5,0,2.3-0.1'+ + 'c0.7-0.2,1.4-0.5,2-0.5c0.3,0,0.6,0.1,1,0.1c0.3,0,0.7-0.5,1.1-0.4c0.5,0.1,0.4,0.8,0.9,0.9c0.6-0.3,1.1,0,1.7,0'+ + 'c0.6,0,1.1-0.3,1.8-0.2c1.2,0.2,2.8,1.5,3.7,0.8c0.2-0.2,0.2-0.5,0.4-0.9c0.3-0.6,0.8-1.3,0.7-2.2c-1.3,0-2.5,0.7-3.9,0.8'+ + 'c-1.5-1,0.4-1.7,1.5-2.2c0.9-0.4,1.6-1.3,2.7-1.4C62,12.5,63,12.9,64,13c0.6,0.1,1.2,0,1.6,0.1c0.6,0.2,0.9,0.9,1.5,1.1'+ + 'c0.2,0.1,0.6,0.1,0.9,0.1c0.6,0.1,1.1,0.5,1.7,0c0.4,0.1,0.5,0.6,1,0.7c0.4-0.3,0.7-0.9,1.4-1.1c0.3-0.1,0.6,0.1,0.9,0'+ + 'c0.5-0.1,1.2-0.9,1.5-0.1c-0.1,0.5-0.8,0.6-1.2,1c-0.3,0.4-0.9,1.2-0.8,1.6c0.1,0.7,1,0.4,1,1.3c-0.1,0.5-0.7,0.3-1.1,0.5'+ + 'c-0.4,0.2-0.5,0.6-1,0.7c-1.2,0.2-2.1-0.3-3.1-0.3c0,0.5,0.5,0.8,0.8,0.9c0.9,0.5,1.6,0.5,2.9,0.4c0.7,0,1.4,0.2,2-0.2'+ + 'c0.4-0.3,0.3-0.9,0.6-1.2c0.4-0.4,1.2-0.8,1.7-0.7c0.3,0.1,0.7,0.4,0.7,0.7c0,0.7-0.8,0.4-0.8,1.1c0.5,0.4,2-0.4,2-1'+ + 'c0.1-0.4-0.5-0.7-0.4-1.1c0-0.8,0.9-0.7,0.8-1.5c-0.4-0.4-0.9,0.1-1.3,0c-0.6-0.1-1.2-1-1.5-1.5c0.3-0.4,0.9-0.1,1.3-0.1'+ + 'c0.5-0.7,1.3-1,2.5-1.1c0.4,0,1-0.2,1.2,0.2c0.1,0.7-0.9,1.1-0.7,1.9c0.9,0.2,1.1-1.1,1.8-1.6c0.3-0.2,0.8-0.4,1.2-0.6'+ + 'c0.4-0.2,0.8-0.6,1.1-0.6c0.4,0,0.4,0.3,0.8,0.5c0.3,0.1,0.7-0.1,0.8,0.4c-0.7,1.4-3.5,0.6-4.2,2.1c0.2,1-0.4,1.9,0.1,2.6'+ + 'c0.4,0.5,1.1,0.2,1.3,0.6c0.2,0.7-0.8,0.7-0.5,1.4c0.7,0.5,1.5-0.4,2.1-0.8c0.7-0.4,1.5-0.8,1.6-1.7c-0.3-0.7-1.6-0.2-1.8-0.9'+ + 'c-0.1-0.4,0.4-1.3,0.5-1.5c0.7-0.8,3-2,4.6-1.9c0.3,0,0.6,0.3,1,0.3c1.1,0.1,2.4-0.5,3.2,0c0.7-0.5,1.5,0.1,2.5-0.1'+ + 'c0.7,0.5,0.5,1.5,1.7,2c0.3,0.1,0.7,0,1.1,0.1c0.3,0.1,0.6,0.5,1,0.6c0.5,0.2,0.9,0.2,1,0.6c0.1,0.4-0.3,0.6-0.3,1'+ + 'c0.3,0.3,0,0.6,0.2,1c0.3,0.7,1,0.6,1.6,0.9c0.5,0.2,1.5,0.9,1.5,1.4c0,0.4-1,1-1.3,1.1c-0.2,0.1-1.3,0.7-1.7,0.6'+ + 'c-0.6-0.1-0.8-1.5-1.7-1.4c-0.4,0-0.7,0.3-0.7,0.8c0,0.9,0.9,1,1,1.8c0,1-0.5,1-1.2,1.6c-0.5-0.2-1-0.6-1.7-0.6'+ + 'c-0.4,0.5,0.7,0.7,0.3,1.4c-1,0.2-1.8-0.3-2.7-0.6c-0.3-0.1-0.7-0.1-1-0.2c-0.4-0.2-0.5-0.9-0.8-1.3c-0.3-0.4-1-1-1.6-1'+ + 'c-0.8,0-1.9,1.1-2.5,0.1c0.4-1.6,2.5-0.4,3.8-1c0.5-0.2,0.7-0.8,1.1-1.1c0.8-0.5,2.2-0.6,2-1.7c-0.1-0.5-0.7-0.5-1.1-0.8'+ + 'c-0.5-0.4-0.9-1.7-1.6-1.7c-0.4,0-0.6,0.3-1,0.4c-0.8,0.1-1.7-0.4-2.5,0c-0.3,0.2-0.1,0.6-0.4,1c-0.2,0.3-0.7,0.4-1,0.8'+ + 'c-0.2,0.4-0.2,0.9-0.5,1.2c-0.5,0.5-1.6,0.6-2.3,0.9c-0.3,0.1-0.7,0.5-1,0.5c-0.5,0-0.7-0.8-1.3-0.5c0,0.8,0.7,1.1,1.2,1.4'+ + 'c0.5,0.4,1.1,0.8,1.3,1.4c-0.5,1.2-1.3-0.1-2.2-0.1c-0.9,0-2.2,1.9-3,0.4c0.2-0.8,1-1,1.2-1.8c-0.9,0.2-1.7,1-2.7,1.3'+ + 'c-0.4,0.1-0.9,0.1-1.3,0.2c-0.8,0.3-1.3,0.9-2.1,1.2c-0.3,0.1-0.7,0.1-1,0.2c-0.8,0.3-1.7,0.8-2.5,1.3c-0.8,0.5-1.7,1-2.2,1.5'+ + 'c-0.3,0.3-1,1.2-1,1.5c0,0.4,0.7,0.6,0.8,1c0,0.3-0.4,0.8-0.1,1.2c0.3,0.3,0.8,0.1,1.3,0.1c1,0.1,1.6,1,2.4,1.5'+ + 'c0.6,0.4,1.4,0.8,2,0.9c0.9,0.1,1.8-0.3,2,0.5c0.1,0.8-0.8,1-0.9,1.5c0.5,0.7-0.3,1-0.3,1.6c0,0.5,0.5,1.2,1,1.3'+ + 'c0.6,0.1,1.6-0.7,1.8-1.4c0.3-0.9,0.2-2,0.8-2.7c3,0.1,5.5-1.5,5.3-4.9c0-0.3-0.2-0.8-0.1-1.2c0.1-0.6,0.9-1,0.8-1.7'+ + 'c0.8-0.3,0.8-1.8,1.7-2c0.7-0.2,1.5,0.6,2.5,0.5c0.3,0,0.7-0.3,1-0.3c0.6,0.1,1,1,1.5,1.4c0.4,0.4,0.9,0.2,1,0.7'+ + 'c-0.1,0.8-0.6,0.8-0.6,1.6c0,0.7,0.7,1.2,1,1.2c0.5,0.1,1.1-0.2,1.6-0.4c0.8-0.5,1.6-1.8,2.3-1.7c0.6,0.1,1,2.1,1.1,2.9'+ + 'c0.1,0.8-0.1,1.4-0.1,2.1c0.1,1.2,1.4,1.1,2.1,1.7c0.2,0.2,0.3,0.7,0.4,0.9c0.3,0.5,0.7,0.5,0.8,1c0.1,1.2-1,1.3-0.9,2.7'+ + 'c-0.2,0.5-0.8,0.5-0.8,1.2c0.1,1.1,1.5,0.3,1.9,1.1c0.2,0.5,0,0.8-0.2,1.5c0.5,0.7,0.5,1.7-0.4,1.7c-0.5,0-0.7-0.6-1.2-0.8'+ + 'c-0.3-0.1-0.7-0.1-1.1-0.1c-0.3-0.1-0.7-0.2-1-0.2c-0.8-0.1-1.6,0.2-2.1-0.4c0.8-1.1,1.8-2.3,2.7-3.2c0.3-0.3,0.9-0.5,0.8-1.1'+ + 'c-0.5-0.5-1.2,0-1.7,0.4c-0.5,0.3-1.2,0.8-1.8,0.9c-1.1,0.2-2.4-0.3-3.3,0.3c-0.1,0.5,1,0.3,0.8,1.1C92.8,43,92.4,43,92,42.7'+ + 'c-0.3-0.3-0.1-0.8-0.3-0.9c-0.3-0.3-1.5-0.4-2.1-0.3c-0.7,0.1-1.3,0.6-1.3,1.2c0.8,0.4,2.1-0.4,2.4,0.6c-0.4,0.9-1.5,1.4-1.3,2.6'+ + 'c0.1,0.5,0.5,1.1,0.9,1.1c0.3,0.1,0.5-0.3,0.9-0.3c0.4,0,0.3,0.5,0.7,0.4c0.6-0.3,1-1.3,1.7-1.2c0.8,1.2-0.8,1.7-1.7,2.1'+ + 'c-1,0.4-2.3,0.6-3.1,1c-0.4,0.2-1.9,1.9-2.2,0.6c-0.2-0.9,0.8-0.7,1-1.4c-1-0.2-1.9,0.5-2.8,0.9c-1.3,0.5-3.4,0.9-3.8,2.5'+ + 'c-0.1,0.3,0.1,0.9-0.1,1.1c-0.2,0.2-1.1,0.2-1.5,0.4c-0.6,0.2-1.2,0.7-1.5,0.9C77.7,54,77.2,54,77,54.1c-0.5,0.2-0.7,1-1.3,1.5'+ + 'c-0.2,0.2-0.8,0.4-1,0.6c-0.3,0.4-0.4,1.3-1,1.4c-0.4,0-0.7-0.3-1-0.1c0,0.9,0.3,2.2-0.1,3.1c-0.8,0.7-1.6,1.2-2.5,1.8'+ + 'c-0.5,0.3-1,0.4-1.7,0.8c-0.5,0.3-0.9,0.9-1.4,1.2c-1.2,0.8-2.7,1.8-2.7,3.8c0,0.4,0.2,0.9,0.3,1.4c0,0.3,0,0.6,0,0.9'+ + 'c0.1,0.7,0.6,1.7,0,2.2c-0.9-0.4-1.9-0.5-2.5-1.2c-0.2-0.7,0.3-1.3,0.3-1.9c-0.1-0.5-0.7-1.4-1.1-1.5c-0.4-0.1-0.7,0.4-1.1,0.4'+ + 'c-0.5,0-0.9-0.8-1.5-0.9c-0.9-0.1-1.6,0.2-2.5,0.1c-1,0.6-1.2,1.6-2.4,1.5c-0.4,0-0.8-0.4-1.3-0.5c-0.5-0.1-1.3-0.3-1.8-0.3'+ + 'c-1.1,0.1-1.9,1-2.8,1.5c-0.8,0.5-2,1.1-2.2,2.1c-0.1,0.5,0,1.3-0.2,1.8c-0.1,0.3-0.4,0.6-0.5,0.9c-0.7,1.5-1.3,3.4-0.8,5.5'+ + 'c0.1,0.3,0.8,2.1,1.1,2.4c0.3,0.4,1.3,1,1.8,1c0.5,0,1-0.3,1.5-0.4c0.5-0.1,1.2-0.1,1.7-0.3c1.4-0.5,1.1-2.6,2.5-3.3'+ + 'c0.6-0.3,1.3-0.4,2.4-0.4c0.3,0.3,0.5,0.9,0.4,1.4c0,0.4-0.3,0.7-0.5,1.2c-0.1,0.5-0.2,1-0.3,1.4c-0.2,0.5-0.6,0.8-0.8,1.3'+ + 'c-0.1,0.3,0,0.7-0.1,0.9c-0.1,0.5-0.7,0.8-0.4,1.3c1.4,0.6,3-0.2,4.2,0.1c0.5,0.1,1.5,0.8,1.5,1.7c0,0.7-0.4,1.1-0.5,1.8'+ + 'c-0.1,0.9-0.4,2-0.4,2.7c-0.1,1.2,1.5,3.2,2.7,3.2L55.7,94.6z M39.1,54.2L31.7,54v11.2h10.3v-8.7L39.1,54.2z M52.2,35.7l7.5,0.1'+ + 'V24.6H49.5l0,8.9 M39.1,54.2l2.9,2.3l10.3-20.8l-2.7-2.1L39.1,54.2z M47.2,46.4' + + } + }, + + // detail panel button definitions + buttons: { + src: { + gid: '*src', + tt: 'Set source node', + cb: function (data) { + $log.debug('Set src action invoked with data:', data); + pps.setSrc(selection); + } + }, + dst: { + gid: '*dst', + tt: 'Set destination node', + cb: function (data) { + $log.debug('Set dst action invoked with data:', data); + pps.setDst(selection); + } + } + }, + + // Key bindings for traffic overlay buttons + // NOTE: fully qual. button ID is derived from overlay-id and key-name + // FIXME: use into [ and ] instead of 1 and 2 + // FIXME: find better keys for shortest paths & disjoint paths modes + keyBindings: { + 1: { + cb: function () { + pps.setSrc(selection); + }, + tt: 'Set source node', + gid: '*src' + }, + 2: { + cb: function () { + pps.setDst(selection); + }, + tt: 'Set destination node', + gid: '*dst' + }, + 3: { + cb: function () { + pps.swapSrcDst(); + }, + tt: 'Swap source and destination nodes', + gid: 'refresh' + }, + 4: { + cb: function () { + pps.setMode("shortest"); + }, + tt: 'Set shortest paths mode', + gid: '*jp' + }, + 5: { + cb: function () { + pps.setMode("disjoint"); + }, + tt: 'Set disjoint paths mode', + gid: '*djp' + }, + 6: { + cb: function () { + pps.setMode("geodata"); + }, + tt: 'Set geodata path weight mode', + gid: '*geo' + }, + leftArrow: { + cb: function () { + pps.prevPath(); + }, + tt: 'Highlight previous path', + gid: 'prevIntent' + }, + rightArrow: { + cb: function () { + pps.nextPath(); + }, + tt: 'Highlight next path', + gid: 'nextIntent' + }, + + _keyOrder: [ + '1', '2', '3', '4', '5', '6', 'leftArrow', 'rightArrow' + ] + }, + + hooks: { + // hook for handling escape key + // Must return true to consume ESC, false otherwise. + escape: function () { + selectionCallback(); + pps.setSrc(); + pps.setDst(); + }, + + // hooks for when the selection changes... + empty: function () { + selectionCallback(); + }, + single: function (data) { + selectionCallback(data); + } + } + }; + + + function buttonCallback(x) { + $log.debug('Toolbar-button callback', x); + } + + function selectionCallback(d) { + $log.debug('Selection callback', d); + selection = d; + } + + // invoke code to register with the overlay service + angular.module('ovPpTopov') + .run(['$log', 'TopoOverlayService', 'PathPainterTopovService', + + function (_$log_, _tov_, _pps_) { + $log = _$log_; + tov = _tov_; + pps = _pps_; + tov.register(overlay); + }]); + +}()); diff --git a/framework/src/onos/apps/pathpainter/src/main/resources/ppTopov/css.html b/framework/src/onos/apps/pathpainter/src/main/resources/ppTopov/css.html new file mode 100644 index 00000000..56b32b4a --- /dev/null +++ b/framework/src/onos/apps/pathpainter/src/main/resources/ppTopov/css.html @@ -0,0 +1 @@ +<link rel="stylesheet" href="app/view/ppTopov/ppTopov.css">
\ No newline at end of file diff --git a/framework/src/onos/apps/pathpainter/src/main/resources/ppTopov/js.html b/framework/src/onos/apps/pathpainter/src/main/resources/ppTopov/js.html new file mode 100644 index 00000000..24124bf7 --- /dev/null +++ b/framework/src/onos/apps/pathpainter/src/main/resources/ppTopov/js.html @@ -0,0 +1,2 @@ +<script src="app/view/ppTopov/ppTopov.js"></script> +<script src="app/view/ppTopov/ppTopovOverlay.js"></script>
\ No newline at end of file diff --git a/framework/src/onos/apps/pom.xml b/framework/src/onos/apps/pom.xml index 005052fb..1a279c53 100644 --- a/framework/src/onos/apps/pom.xml +++ b/framework/src/onos/apps/pom.xml @@ -31,6 +31,7 @@ <modules> <module>aaa</module> <module>acl</module> + <module>faultmanagement</module> <module>fwd</module> <module>mobility</module> <module>proxyarp</module> @@ -47,6 +48,7 @@ <module>cordfabric</module> <module>xos-integration</module> <module>pcep-api</module> + <module>iptopology-api</module> <module>olt</module> <module>cip</module> <module>flowanalyzer</module> @@ -58,6 +60,8 @@ <module>pim</module> <module>mlb</module> <module>openstackswitching</module> + <module>pathpainter</module> + <module>cpman</module> </modules> <properties> diff --git a/framework/src/onos/apps/sdnip/src/main/java/org/onosproject/sdnip/IntentSynchronizer.java b/framework/src/onos/apps/sdnip/src/main/java/org/onosproject/sdnip/IntentSynchronizer.java index 2eb5d0f3..09d4a436 100644 --- a/framework/src/onos/apps/sdnip/src/main/java/org/onosproject/sdnip/IntentSynchronizer.java +++ b/framework/src/onos/apps/sdnip/src/main/java/org/onosproject/sdnip/IntentSynchronizer.java @@ -30,6 +30,7 @@ import org.onosproject.core.ApplicationId; import org.onosproject.net.intent.Intent; import org.onosproject.net.intent.IntentService; import org.onosproject.net.intent.IntentState; +import org.onosproject.net.intent.IntentUtils; import org.onosproject.net.intent.Key; import org.onosproject.routing.IntentSynchronizationService; import org.slf4j.Logger; diff --git a/framework/src/onos/apps/sdnip/src/main/java/org/onosproject/sdnip/IntentUtils.java b/framework/src/onos/apps/sdnip/src/main/java/org/onosproject/sdnip/IntentUtils.java deleted file mode 100644 index 863de12a..00000000 --- a/framework/src/onos/apps/sdnip/src/main/java/org/onosproject/sdnip/IntentUtils.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2015 Open Networking Laboratory - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.onosproject.sdnip; - -import org.onosproject.net.intent.Intent; -import org.onosproject.net.intent.MultiPointToSinglePointIntent; -import org.onosproject.net.intent.PointToPointIntent; -import org.onosproject.net.intent.SinglePointToMultiPointIntent; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.Objects; - -/** - * Utilities for dealing with intents. - */ -public final class IntentUtils { - - private static final Logger log = LoggerFactory.getLogger(IntentUtils.class); - - private IntentUtils() { - - } - - /** - * Checks if two intents represent the same value. - * - * <p>({@link Intent#equals(Object)} only checks ID equality)</p> - * - * <p>Both intents must be of the same type.</p> - * - * @param one first intent - * @param two second intent - * @return true if the two intents represent the same value, otherwise false - */ - public static boolean equals(Intent one, Intent two) { - if (one.getClass() != two.getClass()) { - return false; - } - - if (!(Objects.equals(one.appId(), two.appId()) && - Objects.equals(one.key(), two.key()))) { - return false; - } - - if (one instanceof SinglePointToMultiPointIntent) { - SinglePointToMultiPointIntent intent1 = (SinglePointToMultiPointIntent) one; - SinglePointToMultiPointIntent intent2 = (SinglePointToMultiPointIntent) two; - - return Objects.equals(intent1.selector(), intent2.selector()) && - Objects.equals(intent1.treatment(), intent2.treatment()) && - Objects.equals(intent1.ingressPoint(), intent2.ingressPoint()) && - Objects.equals(intent1.egressPoints(), intent2.egressPoints()); - } else if (one instanceof MultiPointToSinglePointIntent) { - MultiPointToSinglePointIntent intent1 = (MultiPointToSinglePointIntent) one; - MultiPointToSinglePointIntent intent2 = (MultiPointToSinglePointIntent) two; - - return Objects.equals(intent1.selector(), intent2.selector()) && - Objects.equals(intent1.treatment(), intent2.treatment()) && - Objects.equals(intent1.ingressPoints(), intent2.ingressPoints()) && - Objects.equals(intent1.egressPoint(), intent2.egressPoint()); - } else if (one instanceof PointToPointIntent) { - PointToPointIntent intent1 = (PointToPointIntent) one; - PointToPointIntent intent2 = (PointToPointIntent) two; - - return Objects.equals(intent1.selector(), intent2.selector()) && - Objects.equals(intent1.treatment(), intent2.treatment()) && - Objects.equals(intent1.ingressPoint(), intent2.ingressPoint()) && - Objects.equals(intent1.egressPoint(), intent2.egressPoint()); - } else { - log.error("Unimplemented intent type"); - return false; - } - } -} diff --git a/framework/src/onos/apps/sdnip/src/main/java/org/onosproject/sdnip/PeerConnectivityManager.java b/framework/src/onos/apps/sdnip/src/main/java/org/onosproject/sdnip/PeerConnectivityManager.java index fb008aad..edc2df4d 100644 --- a/framework/src/onos/apps/sdnip/src/main/java/org/onosproject/sdnip/PeerConnectivityManager.java +++ b/framework/src/onos/apps/sdnip/src/main/java/org/onosproject/sdnip/PeerConnectivityManager.java @@ -33,6 +33,7 @@ import org.onosproject.net.flow.DefaultTrafficTreatment; import org.onosproject.net.flow.TrafficSelector; import org.onosproject.net.flow.TrafficTreatment; import org.onosproject.net.host.InterfaceIpAddress; +import org.onosproject.net.intent.IntentUtils; import org.onosproject.net.intent.Key; import org.onosproject.net.intent.PointToPointIntent; import org.onosproject.routing.IntentSynchronizationService; diff --git a/framework/src/onos/apps/sdnip/src/test/java/org/onosproject/sdnip/IntentSyncTest.java b/framework/src/onos/apps/sdnip/src/test/java/org/onosproject/sdnip/IntentSyncTest.java index 6dc3ce10..4736aa1d 100644 --- a/framework/src/onos/apps/sdnip/src/test/java/org/onosproject/sdnip/IntentSyncTest.java +++ b/framework/src/onos/apps/sdnip/src/test/java/org/onosproject/sdnip/IntentSyncTest.java @@ -45,6 +45,7 @@ import org.onosproject.net.intent.IntentService; import org.onosproject.net.intent.IntentState; import org.onosproject.net.intent.Key; import org.onosproject.net.intent.MultiPointToSinglePointIntent; +import org.onosproject.net.intent.IntentUtils; import org.onosproject.routing.RouteEntry; import java.util.Collections; diff --git a/framework/src/onos/apps/sdnip/src/test/java/org/onosproject/sdnip/TestIntentServiceHelper.java b/framework/src/onos/apps/sdnip/src/test/java/org/onosproject/sdnip/TestIntentServiceHelper.java index 7f825e81..4df7f9de 100644 --- a/framework/src/onos/apps/sdnip/src/test/java/org/onosproject/sdnip/TestIntentServiceHelper.java +++ b/framework/src/onos/apps/sdnip/src/test/java/org/onosproject/sdnip/TestIntentServiceHelper.java @@ -17,6 +17,7 @@ package org.onosproject.sdnip; import org.easymock.IArgumentMatcher; import org.onosproject.net.intent.Intent; +import org.onosproject.net.intent.IntentUtils; import static org.easymock.EasyMock.reportMatcher; diff --git a/framework/src/onos/apps/segmentrouting/pom.xml b/framework/src/onos/apps/segmentrouting/pom.xml index 83ae76db..d170a7ab 100644 --- a/framework/src/onos/apps/segmentrouting/pom.xml +++ b/framework/src/onos/apps/segmentrouting/pom.xml @@ -89,6 +89,11 @@ <groupId>org.osgi</groupId> <artifactId>org.osgi.core</artifactId> </dependency> + <dependency> + <groupId>org.onosproject</groupId> + <artifactId>onlab-junit</artifactId> + <scope>test</scope> + </dependency> </dependencies> <build> diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/ArpHandler.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/ArpHandler.java index 2c6412cf..7f4bcb15 100644 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/ArpHandler.java +++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/ArpHandler.java @@ -107,7 +107,7 @@ public class ArpHandler { vlanId); // ARP request for router. Send ARP reply. - if (isArpReqForRouter(deviceId, arpRequest)) { + if (isArpForRouter(deviceId, arpRequest)) { Ip4Address targetAddress = Ip4Address.valueOf(arpRequest.getTargetProtocolAddress()); sendArpResponse(arpRequest, config.getRouterMacForAGatewayIp(targetAddress), vlanId); } else { @@ -130,7 +130,7 @@ public class ArpHandler { vlanId); // ARP reply for router. Process all pending IP packets. - if (isArpReqForRouter(deviceId, arpReply)) { + if (isArpForRouter(deviceId, arpReply)) { Ip4Address hostIpAddress = Ip4Address.valueOf(arpReply.getSenderProtocolAddress()); srManager.ipHandler.forwardPackets(deviceId, hostIpAddress); } else { @@ -141,7 +141,8 @@ public class ArpHandler { // ARP reply for unknown host, Flood in the subnet. } else { // Don't flood to non-edge ports - if (vlanId.equals(VlanId.vlanId(srManager.ASSIGNED_VLAN_NO_SUBNET))) { + if (vlanId.equals( + VlanId.vlanId(SegmentRoutingManager.ASSIGNED_VLAN_NO_SUBNET))) { return; } removeVlanAndFlood(payload, inPort); @@ -150,14 +151,21 @@ public class ArpHandler { } - private boolean isArpReqForRouter(DeviceId deviceId, ARP arpRequest) { - Set<Ip4Address> gatewayIpAddresses = config.getPortIPs(deviceId); - if (gatewayIpAddresses != null) { - Ip4Address targetProtocolAddress = Ip4Address.valueOf(arpRequest - .getTargetProtocolAddress()); - if (gatewayIpAddresses.contains(targetProtocolAddress)) { + private boolean isArpForRouter(DeviceId deviceId, ARP arpMsg) { + Ip4Address targetProtocolAddress = Ip4Address.valueOf( + arpMsg.getTargetProtocolAddress()); + Set<Ip4Address> gatewayIpAddresses = null; + try { + if (targetProtocolAddress.equals(config.getRouterIp(deviceId))) { return true; } + gatewayIpAddresses = config.getPortIPs(deviceId); + } catch (DeviceConfigNotFoundException e) { + log.warn(e.getMessage() + " Aborting check for router IP in processing arp"); + } + if (gatewayIpAddresses != null && + gatewayIpAddresses.contains(targetProtocolAddress)) { + return true; } return false; } diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/DefaultRoutingHandler.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/DefaultRoutingHandler.java index 99225874..e6451653 100644 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/DefaultRoutingHandler.java +++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/DefaultRoutingHandler.java @@ -513,6 +513,7 @@ public class DefaultRoutingHandler { public void populatePortAddressingRules(DeviceId deviceId) { rulePopulator.populateRouterMacVlanFilters(deviceId); rulePopulator.populateRouterIpPunts(deviceId); + rulePopulator.populateArpPunts(deviceId); } /** diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/IcmpHandler.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/IcmpHandler.java index eb3b3fd5..d1dc8ddc 100644 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/IcmpHandler.java +++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/IcmpHandler.java @@ -88,10 +88,10 @@ public class IcmpHandler { (destinationAddress.equals(routerIpAddress) || gatewayIpAddresses.contains(destinationAddress))) { sendICMPResponse(ethernet, connectPoint); - // TODO: do we need to set the flow rule again ?? // ICMP for any known host } else if (!srManager.hostService.getHostsByIp(destinationAddress).isEmpty()) { + // TODO: known host packet should not be coming to controller - resend flows? srManager.ipHandler.forwardPackets(deviceId, destinationAddress); // ICMP for an unknown host in the subnet of the router diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/IpHandler.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/IpHandler.java index b1682e77..d6a9dcfc 100644 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/IpHandler.java +++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/IpHandler.java @@ -98,7 +98,7 @@ public class IpHandler { */ public void addToPacketBuffer(IPv4 ipPacket) { - // Better not buffer TPC packets due to out-of-order packet transfer + // Better not buffer TCP packets due to out-of-order packet transfer if (ipPacket.getProtocol() == IPv4.PROTOCOL_TCP) { return; } diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java index a07a15d2..d4aa770c 100644 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java +++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java @@ -147,20 +147,34 @@ public class RoutingRulePopulator { TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder(); TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder(); - sbuilder.matchIPDst(IpPrefix.valueOf(hostIp, IpPrefix.MAX_INET_MASK_LENGTH)); sbuilder.matchEthType(Ethernet.TYPE_IPV4); + sbuilder.matchIPDst(IpPrefix.valueOf(hostIp, IpPrefix.MAX_INET_MASK_LENGTH)); + TrafficSelector selector = sbuilder.build(); tbuilder.deferred() .setEthDst(hostMac) .setEthSrc(deviceMac) .setOutput(outPort); - TrafficTreatment treatment = tbuilder.build(); - TrafficSelector selector = sbuilder.build(); + + // All forwarding is via Groups. Drivers can re-purpose to flow-actions if needed. + // for switch pipelines that need it, provide outgoing vlan as metadata + VlanId outvlan = null; + Ip4Prefix subnet = srManager.deviceConfiguration.getPortSubnet(deviceId, outPort); + if (subnet == null) { + outvlan = VlanId.vlanId(SegmentRoutingManager.ASSIGNED_VLAN_NO_SUBNET); + } else { + outvlan = srManager.getSubnetAssignedVlanId(deviceId, subnet); + } + TrafficSelector meta = DefaultTrafficSelector.builder() + .matchVlanId(outvlan).build(); + int portNextObjId = srManager.getPortNextObjectiveId(deviceId, outPort, + treatment, meta); return DefaultForwardingObjective.builder() + .withSelector(selector) + .nextStep(portNextObjId) .fromApp(srManager.appId).makePermanent() - .withSelector(selector).withTreatment(treatment) .withPriority(100).withFlag(ForwardingObjective.Flag.SPECIFIC); } @@ -454,7 +468,7 @@ public class RoutingRulePopulator { if (srManager.mastershipService.isLocalMaster(deviceId)) { TrafficTreatment tt = DefaultTrafficTreatment.builder() .pushVlan().setVlanId(assignedVlan).build(); - fob.setMeta(tt); + fob.withMeta(tt); } fob.permit().fromApp(srManager.appId); srManager.flowObjectiveService. @@ -511,6 +525,39 @@ public class RoutingRulePopulator { } /** + * Creates a forwarding objective to punt all IP packets, destined to the + * router's port IP addresses, to the controller. Note that the input + * port should not be matched on, as these packets can come from any input. + * Furthermore, these are applied only by the master instance. + * + * @param deviceId the switch dpid for the router + */ + public void populateArpPunts(DeviceId deviceId) { + if (!srManager.mastershipService.isLocalMaster(deviceId)) { + log.debug("Not installing port-IP punts - not the master for dev:{} ", + deviceId); + return; + } + + ForwardingObjective.Builder puntArp = DefaultForwardingObjective.builder(); + TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder(); + TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder(); + sbuilder.matchEthType(Ethernet.TYPE_ARP); + tbuilder.setOutput(PortNumber.CONTROLLER); + puntArp.withSelector(sbuilder.build()); + puntArp.withTreatment(tbuilder.build()); + puntArp.withFlag(Flag.VERSATILE) + .withPriority(HIGHEST_PRIORITY) + .makePermanent() + .fromApp(srManager.appId); + log.debug("Installing forwarding objective to punt ARPs"); + srManager.flowObjectiveService. + forward(deviceId, + puntArp.add(new SRObjectiveContext(deviceId, + SRObjectiveContext.ObjectiveType.FORWARDING))); + } + + /** * Populates a forwarding objective to send packets that miss other high * priority Bridging Table entries to a group that contains all ports of * its subnet. @@ -526,6 +573,12 @@ public class RoutingRulePopulator { int nextId = srManager.getSubnetNextObjectiveId(deviceId, subnet); VlanId vlanId = srManager.getSubnetAssignedVlanId(deviceId, subnet); + if (nextId < 0 || vlanId == null) { + log.error("Cannot install subnet broadcast rule in dev:{} due" + + "to vlanId:{} or nextId:{}", vlanId, nextId); + return; + } + /* Driver should treat objective with MacAddress.NONE as the * subnet broadcast rule */ diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java index f6bf649c..62722f02 100644 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java +++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java @@ -57,6 +57,7 @@ import org.onosproject.segmentrouting.config.SegmentRoutingConfig; import org.onosproject.segmentrouting.grouphandler.DefaultGroupHandler; import org.onosproject.segmentrouting.grouphandler.NeighborSet; import org.onosproject.segmentrouting.grouphandler.NeighborSetNextObjectiveStoreKey; +import org.onosproject.segmentrouting.grouphandler.PortNextObjectiveStoreKey; import org.onosproject.mastership.MastershipService; import org.onosproject.net.Device; import org.onosproject.net.DeviceId; @@ -97,7 +98,6 @@ import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; -@SuppressWarnings("ALL") @Service @Component(immediate = true) public class SegmentRoutingManager implements SegmentRoutingService { @@ -150,21 +150,27 @@ public class SegmentRoutingManager implements SegmentRoutingService { private ScheduledExecutorService executorService = Executors .newScheduledThreadPool(1); + @SuppressWarnings("unused") private static ScheduledFuture<?> eventHandlerFuture = null; + @SuppressWarnings("rawtypes") private ConcurrentLinkedQueue<Event> eventQueue = new ConcurrentLinkedQueue<Event>(); private Map<DeviceId, DefaultGroupHandler> groupHandlerMap = new ConcurrentHashMap<DeviceId, DefaultGroupHandler>(); // Per device next objective ID store with (device id + neighbor set) as key private EventuallyConsistentMap<NeighborSetNextObjectiveStoreKey, Integer> nsNextObjStore = null; + // Per device next objective ID store with (device id + subnet) as key private EventuallyConsistentMap<SubnetNextObjectiveStoreKey, Integer> subnetNextObjStore = null; - private EventuallyConsistentMap<String, Tunnel> tunnelStore = null; - private EventuallyConsistentMap<String, Policy> policyStore = null; + // Per device next objective ID store with (device id + port) as key + private EventuallyConsistentMap<PortNextObjectiveStoreKey, Integer> + portNextObjStore = null; // Per device, per-subnet assigned-vlans store, with (device id + subnet // IPv4 prefix) as key private EventuallyConsistentMap<SubnetAssignedVidStoreKey, VlanId> subnetVidStore = null; + private EventuallyConsistentMap<String, Tunnel> tunnelStore = null; + private EventuallyConsistentMap<String, Policy> policyStore = null; @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) protected StorageService storageService; @@ -175,6 +181,7 @@ public class SegmentRoutingManager implements SegmentRoutingService { private final InternalConfigListener cfgListener = new InternalConfigListener(this); + @SuppressWarnings({ "unchecked", "rawtypes" }) private final ConfigFactory cfgFactory = new ConfigFactory(SubjectFactories.DEVICE_SUBJECT_FACTORY, SegmentRoutingConfig.class, @@ -185,7 +192,7 @@ public class SegmentRoutingManager implements SegmentRoutingService { } }; - private final HostListener hostListener = new InternalHostListener(); + private final InternalHostListener hostListener = new InternalHostListener(); private Object threadSchedulerLock = new Object(); private static int numOfEventsQueued = 0; @@ -228,7 +235,6 @@ public class SegmentRoutingManager implements SegmentRoutingService { log.debug("Creating EC map nsnextobjectivestore"); EventuallyConsistentMapBuilder<NeighborSetNextObjectiveStoreKey, Integer> nsNextObjMapBuilder = storageService.eventuallyConsistentMapBuilder(); - nsNextObjStore = nsNextObjMapBuilder .withName("nsnextobjectivestore") .withSerializer(kryoBuilder) @@ -239,16 +245,23 @@ public class SegmentRoutingManager implements SegmentRoutingService { log.debug("Creating EC map subnetnextobjectivestore"); EventuallyConsistentMapBuilder<SubnetNextObjectiveStoreKey, Integer> subnetNextObjMapBuilder = storageService.eventuallyConsistentMapBuilder(); - subnetNextObjStore = subnetNextObjMapBuilder .withName("subnetnextobjectivestore") .withSerializer(kryoBuilder) .withTimestampProvider((k, v) -> new WallClockTimestamp()) .build(); + log.debug("Creating EC map subnetnextobjectivestore"); + EventuallyConsistentMapBuilder<PortNextObjectiveStoreKey, Integer> + portNextObjMapBuilder = storageService.eventuallyConsistentMapBuilder(); + portNextObjStore = portNextObjMapBuilder + .withName("portnextobjectivestore") + .withSerializer(kryoBuilder) + .withTimestampProvider((k, v) -> new WallClockTimestamp()) + .build(); + EventuallyConsistentMapBuilder<String, Tunnel> tunnelMapBuilder = storageService.eventuallyConsistentMapBuilder(); - tunnelStore = tunnelMapBuilder .withName("tunnelstore") .withSerializer(kryoBuilder) @@ -257,7 +270,6 @@ public class SegmentRoutingManager implements SegmentRoutingService { EventuallyConsistentMapBuilder<String, Policy> policyMapBuilder = storageService.eventuallyConsistentMapBuilder(); - policyStore = policyMapBuilder .withName("policystore") .withSerializer(kryoBuilder) @@ -266,7 +278,6 @@ public class SegmentRoutingManager implements SegmentRoutingService { EventuallyConsistentMapBuilder<SubnetAssignedVidStoreKey, VlanId> subnetVidStoreMapBuilder = storageService.eventuallyConsistentMapBuilder(); - subnetVidStore = subnetVidStoreMapBuilder .withName("subnetvidstore") .withSerializer(kryoBuilder) @@ -425,8 +436,7 @@ public class SegmentRoutingManager implements SegmentRoutingService { /** * Returns the next objective ID for the given NeighborSet. * If the nextObjective does not exist, a new one is created and - * it's id is returned. - * TODO move the side-effect creation of a Next Objective into a new method + * its id is returned. * * @param deviceId Device ID * @param ns NegighborSet @@ -441,18 +451,19 @@ public class SegmentRoutingManager implements SegmentRoutingService { return groupHandlerMap .get(deviceId).getNextObjectiveId(ns, meta); } else { - log.warn("getNextObjectiveId query in device {} not found", deviceId); + log.warn("getNextObjectiveId query - groupHandler for device {} " + + "not found", deviceId); return -1; } } /** - * Returns the next objective ID for the Subnet given. If the nextObjectiveID does not exist, - * a new one is created and returned. + * Returns the next objective ID for the given subnet prefix. It is expected + * that the next-objective has been pre-created from configuration. * * @param deviceId Device ID * @param prefix Subnet - * @return next objective ID + * @return next objective ID or -1 if it was not found */ public int getSubnetNextObjectiveId(DeviceId deviceId, IpPrefix prefix) { if (groupHandlerMap.get(deviceId) != null) { @@ -460,7 +471,33 @@ public class SegmentRoutingManager implements SegmentRoutingService { return groupHandlerMap .get(deviceId).getSubnetNextObjectiveId(prefix); } else { - log.warn("getSubnetNextObjectiveId query in device {} not found", deviceId); + log.warn("getSubnetNextObjectiveId query - groupHandler for " + + "device {} not found", deviceId); + return -1; + } + } + + /** + * Returns the next objective ID for the given portNumber, given the treatment. + * There could be multiple different treatments to the same outport, which + * would result in different objectives. If the next object + * does not exist, a new one is created and its id is returned. + * + * @param deviceId Device ID + * @param portNum port number on device for which NextObjective is queried + * @param treatment the actions to apply on the packets (should include outport) + * @param meta metadata passed into the creation of a Next Objective if necessary + * @return next objective ID or -1 if it was not found + */ + public int getPortNextObjectiveId(DeviceId deviceId, PortNumber portNum, + TrafficTreatment treatment, + TrafficSelector meta) { + DefaultGroupHandler ghdlr = groupHandlerMap.get(deviceId); + if (ghdlr != null) { + return ghdlr.getPortNextObjectiveId(portNum, treatment, meta); + } else { + log.warn("getPortNextObjectiveId query - groupHandler for device {}" + + " not found", deviceId); return -1; } } @@ -475,7 +512,7 @@ public class SegmentRoutingManager implements SegmentRoutingService { InboundPacket pkt = context.inPacket(); Ethernet ethernet = pkt.parsed(); - + log.trace("Rcvd pktin: {}", ethernet); if (ethernet.getEtherType() == Ethernet.TYPE_ARP) { arpHandler.processPacketIn(pkt); } else if (ethernet.getEtherType() == Ethernet.TYPE_IPV4) { @@ -517,6 +554,7 @@ public class SegmentRoutingManager implements SegmentRoutingService { } } + @SuppressWarnings("rawtypes") private void scheduleEventHandlerIfNotScheduled(Event event) { synchronized (threadSchedulerLock) { eventQueue.add(event); @@ -539,6 +577,7 @@ public class SegmentRoutingManager implements SegmentRoutingService { public void run() { try { while (true) { + @SuppressWarnings("rawtypes") Event event = null; synchronized (threadSchedulerLock) { if (!eventQueue.isEmpty()) { @@ -647,7 +686,8 @@ public class SegmentRoutingManager implements SegmentRoutingService { linkService, flowObjectiveService, nsNextObjStore, - subnetNextObjStore); + subnetNextObjStore, + portNextObjStore); } catch (DeviceConfigNotFoundException e) { log.warn(e.getMessage() + " Aborting processDeviceAdded."); return; @@ -658,6 +698,7 @@ public class SegmentRoutingManager implements SegmentRoutingService { // port addressing rules to the driver as well irrespective of whether // this instance is the master or not. defaultRoutingHandler.populatePortAddressingRules(device.id()); + hostListener.readInitialHosts(); } if (mastershipService.isLocalMaster(device.id())) { DefaultGroupHandler groupHandler = groupHandlerMap.get(device.id()); @@ -713,7 +754,8 @@ public class SegmentRoutingManager implements SegmentRoutingService { linkService, flowObjectiveService, nsNextObjStore, - subnetNextObjStore); + subnetNextObjStore, + portNextObjStore); } catch (DeviceConfigNotFoundException e) { log.warn(e.getMessage() + " Aborting configureNetwork."); return; @@ -725,6 +767,7 @@ public class SegmentRoutingManager implements SegmentRoutingService { // port addressing rules to the driver as well, irrespective of whether // this instance is the master or not. defaultRoutingHandler.populatePortAddressingRules(device.id()); + hostListener.readInitialHosts(); } if (mastershipService.isLocalMaster(device.id())) { DefaultGroupHandler groupHandler = groupHandlerMap.get(device.id()); @@ -751,22 +794,66 @@ public class SegmentRoutingManager implements SegmentRoutingService { } } + // TODO Move bridging table population to a separate class private class InternalHostListener implements HostListener { + private void readInitialHosts() { + hostService.getHosts().forEach(host -> { + MacAddress mac = host.mac(); + VlanId vlanId = host.vlan(); + DeviceId deviceId = host.location().deviceId(); + PortNumber port = host.location().port(); + Set<IpAddress> ips = host.ipAddresses(); + log.debug("Host {}/{} is added at {}:{}", mac, vlanId, deviceId, port); + + // Populate bridging table entry + ForwardingObjective.Builder fob = + getForwardingObjectiveBuilder(deviceId, mac, vlanId, port); + flowObjectiveService.forward(deviceId, fob.add( + new BridgingTableObjectiveContext(mac, vlanId) + )); + + // Populate IP table entry + ips.forEach(ip -> { + if (ip.isIp4()) { + routingRulePopulator.populateIpRuleForHost( + deviceId, ip.getIp4Address(), mac, port); + } + }); + }); + } + private ForwardingObjective.Builder getForwardingObjectiveBuilder( - MacAddress mac, VlanId vlanId, PortNumber port) { + DeviceId deviceId, MacAddress mac, VlanId vlanId, + PortNumber outport) { + // match rule TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder(); sbuilder.matchEthDst(mac); sbuilder.matchVlanId(vlanId); TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder(); - // TODO Move popVlan from flow action to group action tbuilder.immediate().popVlan(); - tbuilder.immediate().setOutput(port); + tbuilder.immediate().setOutput(outport); + + // for switch pipelines that need it, provide outgoing vlan as metadata + VlanId outvlan = null; + Ip4Prefix subnet = deviceConfiguration.getPortSubnet(deviceId, outport); + if (subnet == null) { + outvlan = VlanId.vlanId(ASSIGNED_VLAN_NO_SUBNET); + } else { + outvlan = getSubnetAssignedVlanId(deviceId, subnet); + } + TrafficSelector meta = DefaultTrafficSelector.builder() + .matchVlanId(outvlan).build(); + + // All forwarding is via Groups. Drivers can re-purpose to flow-actions if needed. + int portNextObjId = getPortNextObjectiveId(deviceId, outport, + tbuilder.build(), + meta); return DefaultForwardingObjective.builder() .withFlag(ForwardingObjective.Flag.SPECIFIC) .withSelector(sbuilder.build()) - .withTreatment(tbuilder.build()) + .nextStep(portNextObjId) .withPriority(100) .fromApp(appId) .makePermanent(); @@ -778,12 +865,13 @@ public class SegmentRoutingManager implements SegmentRoutingService { DeviceId deviceId = event.subject().location().deviceId(); PortNumber port = event.subject().location().port(); Set<IpAddress> ips = event.subject().ipAddresses(); - log.debug("Host {}/{} is added at {}:{}", mac, vlanId, deviceId, port); + log.info("Host {}/{} is added at {}:{}", mac, vlanId, deviceId, port); - // TODO Move bridging table population to a separate class // Populate bridging table entry + log.debug("Populate L2 table entry for host {} at {}:{}", + mac, deviceId, port); ForwardingObjective.Builder fob = - getForwardingObjectiveBuilder(mac, vlanId, port); + getForwardingObjectiveBuilder(deviceId, mac, vlanId, port); flowObjectiveService.forward(deviceId, fob.add( new BridgingTableObjectiveContext(mac, vlanId) )); @@ -807,7 +895,7 @@ public class SegmentRoutingManager implements SegmentRoutingService { // Revoke bridging table entry ForwardingObjective.Builder fob = - getForwardingObjectiveBuilder(mac, vlanId, port); + getForwardingObjectiveBuilder(deviceId, mac, vlanId, port); flowObjectiveService.forward(deviceId, fob.remove( new BridgingTableObjectiveContext(mac, vlanId) )); @@ -835,7 +923,7 @@ public class SegmentRoutingManager implements SegmentRoutingService { // Revoke previous bridging table entry ForwardingObjective.Builder prevFob = - getForwardingObjectiveBuilder(mac, vlanId, prevPort); + getForwardingObjectiveBuilder(prevDeviceId, mac, vlanId, prevPort); flowObjectiveService.forward(prevDeviceId, prevFob.remove( new BridgingTableObjectiveContext(mac, vlanId) )); @@ -850,7 +938,7 @@ public class SegmentRoutingManager implements SegmentRoutingService { // Populate new bridging table entry ForwardingObjective.Builder newFob = - getForwardingObjectiveBuilder(mac, vlanId, prevPort); + getForwardingObjectiveBuilder(newDeviceId, mac, vlanId, newPort); flowObjectiveService.forward(newDeviceId, newFob.add( new BridgingTableObjectiveContext(mac, vlanId) )); diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/TunnelHandler.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/TunnelHandler.java index b86adada..5a82e712 100644 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/TunnelHandler.java +++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/TunnelHandler.java @@ -158,7 +158,7 @@ public class TunnelHandler { private int createGroupsForTunnel(Tunnel tunnel) { - List<Integer> portNumbers; + Set<Integer> portNumbers; final int groupError = -1; DeviceId deviceId = config.getDeviceId(tunnel.labelIds().get(0)); diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/DeviceConfiguration.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/DeviceConfiguration.java index 0ad00679..dbac596d 100644 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/DeviceConfiguration.java +++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/DeviceConfiguration.java @@ -16,7 +16,6 @@ package org.onosproject.segmentrouting.config; import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Lists; import org.onlab.packet.Ip4Address; import org.onlab.packet.Ip4Prefix; import org.onlab.packet.MacAddress; @@ -26,7 +25,6 @@ import org.onosproject.incubator.net.intf.Interface; import org.onosproject.net.ConnectPoint; import org.onosproject.net.config.NetworkConfigRegistry; import org.onosproject.net.host.InterfaceIpAddress; -import org.onosproject.segmentrouting.config.SegmentRoutingConfig.AdjacencySid; import org.onosproject.net.DeviceId; import org.onosproject.net.PortNumber; import org.slf4j.Logger; @@ -34,6 +32,7 @@ import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -60,7 +59,7 @@ public class DeviceConfiguration implements DeviceProperties { boolean isEdge; HashMap<PortNumber, Ip4Address> gatewayIps; HashMap<PortNumber, Ip4Prefix> subnets; - List<AdjacencySid> adjacencySids; + Map<Integer, Set<Integer>> adjacencySids; public SegmentRouterInfo() { this.gatewayIps = new HashMap<>(); @@ -83,11 +82,11 @@ public class DeviceConfiguration implements DeviceProperties { cfgService.getConfig(subject, SegmentRoutingConfig.class); SegmentRouterInfo info = new SegmentRouterInfo(); info.deviceId = subject; - info.nodeSid = config.getSid(); - info.ip = config.getIp(); - info.mac = config.getMac(); + info.nodeSid = config.nodeSid(); + info.ip = config.routerIp(); + info.mac = config.routerMac(); info.isEdge = config.isEdgeRouter(); - info.adjacencySids = config.getAdjacencySids(); + info.adjacencySids = config.adjacencySids(); this.deviceConfigMap.put(info.deviceId, info); this.allSegmentIds.add(info.nodeSid); @@ -410,19 +409,13 @@ public class DeviceConfiguration implements DeviceProperties { * * @param deviceId device identification of the router * @param sid adjacency Sid - * @return list of port numbers + * @return set of port numbers */ - public List<Integer> getPortsForAdjacencySid(DeviceId deviceId, int sid) { + public Set<Integer> getPortsForAdjacencySid(DeviceId deviceId, int sid) { SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId); - if (srinfo != null) { - for (AdjacencySid asid : srinfo.adjacencySids) { - if (asid.getAsid() == sid) { - return asid.getPorts(); - } - } - } - - return Lists.newArrayList(); + return srinfo != null ? + ImmutableSet.copyOf(srinfo.adjacencySids.get(sid)) : + ImmutableSet.copyOf(new HashSet<>()); } /** @@ -435,20 +428,6 @@ public class DeviceConfiguration implements DeviceProperties { */ public boolean isAdjacencySid(DeviceId deviceId, int sid) { SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId); - if (srinfo != null) { - if (srinfo.adjacencySids.isEmpty()) { - return false; - } else { - for (AdjacencySid asid: - srinfo.adjacencySids) { - if (asid.getAsid() == sid) { - return true; - } - } - return false; - } - } - - return false; + return srinfo != null && srinfo.adjacencySids.containsKey(sid); } }
\ No newline at end of file diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/SegmentRoutingConfig.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/SegmentRoutingConfig.java index 6dc3f0db..f788925c 100644 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/SegmentRoutingConfig.java +++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/SegmentRoutingConfig.java @@ -16,113 +16,210 @@ package org.onosproject.segmentrouting.config; +import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.google.common.collect.ImmutableMap; import org.onlab.packet.Ip4Address; import org.onlab.packet.MacAddress; import org.onosproject.net.DeviceId; import org.onosproject.net.config.Config; -import org.onosproject.net.config.basics.BasicElementConfig; -import java.util.ArrayList; -import java.util.List; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; import java.util.Optional; +import java.util.Set; /** * Configuration object for Segment Routing Application. */ public class SegmentRoutingConfig extends Config<DeviceId> { - private static final String NAME = "name"; - private static final String IP = "routerIp"; - private static final String MAC = "routerMac"; - private static final String SID = "nodeSid"; - private static final String EDGE = "isEdgeRouter"; - private static final String ADJSID = "adjacencySids"; - - public Optional<String> getName() { + public static final String NAME = "name"; + public static final String IP = "routerIp"; + public static final String MAC = "routerMac"; + public static final String SID = "nodeSid"; + public static final String EDGE = "isEdgeRouter"; + public static final String ADJSIDS = "adjacencySids"; + public static final String ADJSID = "adjSid"; + public static final String PORTS = "ports"; + + @Override + public boolean isValid() { + return hasOnlyFields(NAME, IP, MAC, SID, EDGE, ADJSIDS, ADJSID, PORTS) && + this.name() != null && + this.routerIp() != null && + this.routerMac() != null && + this.nodeSid() != -1 && + this.isEdgeRouter() != null && + this.adjacencySids() != null; + } + + /** + * Gets the name of the router. + * + * @return Optional name of the router. May be empty if not configured. + */ + public Optional<String> name() { String name = get(NAME, null); return name != null ? Optional.of(name) : Optional.empty(); } - public BasicElementConfig setName(String name) { - return (BasicElementConfig) setOrClear(NAME, name); + /** + * Sets the name of the router. + * + * @param name name of the router. + * @return the config of the router. + */ + public SegmentRoutingConfig setName(String name) { + return (SegmentRoutingConfig) setOrClear(NAME, name); } - public Ip4Address getIp() { + /** + * Gets the IP address of the router. + * + * @return IP address of the router. Or null if not configured. + */ + public Ip4Address routerIp() { String ip = get(IP, null); return ip != null ? Ip4Address.valueOf(ip) : null; } - public BasicElementConfig setIp(String ip) { - return (BasicElementConfig) setOrClear(IP, ip); + /** + * Sets the IP address of the router. + * + * @param ip IP address of the router. + * @return the config of the router. + */ + public SegmentRoutingConfig setRouterIp(String ip) { + return (SegmentRoutingConfig) setOrClear(IP, ip); } - public MacAddress getMac() { + /** + * Gets the MAC address of the router. + * + * @return MAC address of the router. Or null if not configured. + */ + public MacAddress routerMac() { String mac = get(MAC, null); return mac != null ? MacAddress.valueOf(mac) : null; } - public BasicElementConfig setMac(String mac) { - return (BasicElementConfig) setOrClear(MAC, mac); + /** + * Sets the MAC address of the router. + * + * @param mac MAC address of the router. + * @return the config of the router. + */ + public SegmentRoutingConfig setRouterMac(String mac) { + return (SegmentRoutingConfig) setOrClear(MAC, mac); } - public int getSid() { + /** + * Gets the node SID of the router. + * + * @return node SID of the router. Or -1 if not configured. + */ + public int nodeSid() { return get(SID, -1); } - public BasicElementConfig setSid(int sid) { - return (BasicElementConfig) setOrClear(SID, sid); + /** + * Sets the node SID of the router. + * + * @param sid node SID of the router. + * @return the config of the router. + */ + public SegmentRoutingConfig setNodeSid(int sid) { + return (SegmentRoutingConfig) setOrClear(SID, sid); } - public boolean isEdgeRouter() { - return get(EDGE, false); + /** + * Checks if the router is an edge router. + * + * @return true if the router is an edge router. + * false if the router is not an edge router. + * null if the value is not configured. + */ + public Boolean isEdgeRouter() { + String isEdgeRouter = get(EDGE, null); + return isEdgeRouter != null ? + Boolean.valueOf(isEdgeRouter) : + null; } - public BasicElementConfig setEdgeRouter(boolean isEdgeRouter) { - return (BasicElementConfig) setOrClear(EDGE, isEdgeRouter); + /** + * Specifies if the router is an edge router. + * + * @param isEdgeRouter true if the router is an edge router. + * @return the config of the router. + */ + public SegmentRoutingConfig setIsEdgeRouter(boolean isEdgeRouter) { + return (SegmentRoutingConfig) setOrClear(EDGE, isEdgeRouter); } - public List<AdjacencySid> getAdjacencySids() { - ArrayList<AdjacencySid> adjacencySids = new ArrayList<>(); - - if (!object.has(ADJSID)) { - return adjacencySids; + /** + * Gets the adjacency SIDs of the router. + * + * @return adjacency SIDs of the router. Or null if not configured. + */ + public Map<Integer, Set<Integer>> adjacencySids() { + if (!object.has(ADJSIDS)) { + return null; } - ArrayNode adjacencySidNodes = (ArrayNode) object.path(ADJSID); - adjacencySidNodes.forEach(adjacencySidNode -> { - int asid = adjacencySidNode.path(AdjacencySid.ASID).asInt(); - - ArrayList<Integer> ports = new ArrayList<Integer>(); - ArrayNode portsNodes = (ArrayNode) adjacencySidNode.path(AdjacencySid.PORTS); - portsNodes.forEach(portNode -> { - ports.add(portNode.asInt()); - }); - - AdjacencySid adjacencySid = new AdjacencySid(asid, ports); - adjacencySids.add(adjacencySid); - }); + Map<Integer, Set<Integer>> adjacencySids = new HashMap<>(); + ArrayNode adjacencySidsNode = (ArrayNode) object.path(ADJSIDS); + for (JsonNode adjacencySidNode : adjacencySidsNode) { + int asid = adjacencySidNode.path(ADJSID).asInt(-1); + if (asid == -1) { + return null; + } + + HashSet<Integer> ports = new HashSet<>(); + ArrayNode portsNode = (ArrayNode) adjacencySidNode.path(PORTS); + for (JsonNode portNode : portsNode) { + int port = portNode.asInt(-1); + if (port == -1) { + return null; + } + ports.add(port); + } + adjacencySids.put(asid, ports); + } - return adjacencySids; + return ImmutableMap.copyOf(adjacencySids); } - public class AdjacencySid { - private static final String ASID = "adjSid"; - private static final String PORTS = "ports"; - - int asid; - List<Integer> ports; - - public AdjacencySid(int asid, List<Integer> ports) { - this.asid = asid; - this.ports = ports; - } + /** + * Sets the adjacency SIDs of the router. + * + * @param adjacencySids adjacency SIDs of the router. + * @return the config of the router. + */ + public SegmentRoutingConfig setAdjacencySids(Map<Integer, Set<Integer>> adjacencySids) { + if (adjacencySids == null) { + object.remove(ADJSIDS); + } else { + ArrayNode adjacencySidsNode = mapper.createArrayNode(); + + adjacencySids.forEach((sid, ports) -> { + ObjectNode adjacencySidNode = mapper.createObjectNode(); + + adjacencySidNode.put(ADJSID, sid); + + ArrayNode portsNode = mapper.createArrayNode(); + ports.forEach(port -> { + portsNode.add(port.toString()); + }); + adjacencySidNode.set(PORTS, portsNode); + + adjacencySidsNode.add(adjacencySidNode); + }); - public int getAsid() { - return asid; + object.set(ADJSIDS, adjacencySidsNode); } - public List<Integer> getPorts() { - return ports; - } + return this; } }
\ No newline at end of file diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultEdgeGroupHandler.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultEdgeGroupHandler.java index 6b6d960a..32c53654 100644 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultEdgeGroupHandler.java +++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultEdgeGroupHandler.java @@ -56,9 +56,11 @@ public class DefaultEdgeGroupHandler extends DefaultGroupHandler { NeighborSetNextObjectiveStoreKey, Integer> nsNextObjStore, EventuallyConsistentMap<SubnetNextObjectiveStoreKey, - Integer> subnetNextObjStore) { + Integer> subnetNextObjStore, + EventuallyConsistentMap<PortNextObjectiveStoreKey, + Integer> portNextObjStore) { super(deviceId, appId, config, linkService, flowObjService, - nsNextObjStore, subnetNextObjStore); + nsNextObjStore, subnetNextObjStore, portNextObjStore); } @Override diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultGroupHandler.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultGroupHandler.java index e792bf66..bc394b84 100644 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultGroupHandler.java +++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultGroupHandler.java @@ -80,6 +80,8 @@ public class DefaultGroupHandler { NeighborSetNextObjectiveStoreKey, Integer> nsNextObjStore = null; protected EventuallyConsistentMap< SubnetNextObjectiveStoreKey, Integer> subnetNextObjStore = null; + protected EventuallyConsistentMap< + PortNextObjectiveStoreKey, Integer> portNextObjStore = null; protected KryoNamespace.Builder kryo = new KryoNamespace.Builder() .register(URI.class).register(HashSet.class) @@ -93,11 +95,12 @@ public class DefaultGroupHandler { DeviceProperties config, LinkService linkService, FlowObjectiveService flowObjService, - EventuallyConsistentMap< - NeighborSetNextObjectiveStoreKey, + EventuallyConsistentMap<NeighborSetNextObjectiveStoreKey, Integer> nsNextObjStore, EventuallyConsistentMap<SubnetNextObjectiveStoreKey, - Integer> subnetNextObjStore) { + Integer> subnetNextObjStore, + EventuallyConsistentMap<PortNextObjectiveStoreKey, + Integer> portNextObjStore) { this.deviceId = checkNotNull(deviceId); this.appId = checkNotNull(appId); this.deviceConfig = checkNotNull(config); @@ -114,6 +117,7 @@ public class DefaultGroupHandler { this.flowObjectiveService = flowObjService; this.nsNextObjStore = nsNextObjStore; this.subnetNextObjStore = subnetNextObjStore; + this.portNextObjStore = portNextObjStore; populateNeighborMaps(); } @@ -133,30 +137,34 @@ public class DefaultGroupHandler { * @throws DeviceConfigNotFoundException if the device configuration is not found * @return default group handler type */ - public static DefaultGroupHandler createGroupHandler(DeviceId deviceId, - ApplicationId appId, - DeviceProperties config, - LinkService linkService, - FlowObjectiveService flowObjService, - EventuallyConsistentMap< - NeighborSetNextObjectiveStoreKey, - Integer> nsNextObjStore, - EventuallyConsistentMap<SubnetNextObjectiveStoreKey, - Integer> subnetNextObjStore) - throws DeviceConfigNotFoundException { + public static DefaultGroupHandler createGroupHandler( + DeviceId deviceId, + ApplicationId appId, + DeviceProperties config, + LinkService linkService, + FlowObjectiveService flowObjService, + EventuallyConsistentMap<NeighborSetNextObjectiveStoreKey, + Integer> nsNextObjStore, + EventuallyConsistentMap<SubnetNextObjectiveStoreKey, + Integer> subnetNextObjStore, + EventuallyConsistentMap<PortNextObjectiveStoreKey, + Integer> portNextObjStore) + throws DeviceConfigNotFoundException { // handle possible exception in the caller if (config.isEdgeDevice(deviceId)) { return new DefaultEdgeGroupHandler(deviceId, appId, config, linkService, flowObjService, nsNextObjStore, - subnetNextObjStore); + subnetNextObjStore, + portNextObjStore); } else { return new DefaultTransitGroupHandler(deviceId, appId, config, linkService, flowObjService, nsNextObjStore, - subnetNextObjStore); + subnetNextObjStore, + portNextObjStore); } } @@ -231,25 +239,21 @@ public class DefaultGroupHandler { Integer nextId = nsNextObjStore. get(new NeighborSetNextObjectiveStoreKey(deviceId, ns)); - if (nextId != null) { + if (nextId != null && isMaster) { NextObjective.Builder nextObjBuilder = DefaultNextObjective .builder().withId(nextId) .withType(NextObjective.Type.HASHED).fromApp(appId); nextObjBuilder.addTreatment(tBuilder.build()); - log.info("**linkUp in device {}: Adding Bucket " - + "with Port {} to next object id {} and amIMaster:{}", + + "with Port {} to next object id {}", deviceId, newLink.src().port(), - nextId, isMaster); - - if (isMaster) { - NextObjective nextObjective = nextObjBuilder. - addToExisting(new SRNextObjectiveContext(deviceId)); - flowObjectiveService.next(deviceId, nextObjective); - } - } else { + nextId); + NextObjective nextObjective = nextObjBuilder. + addToExisting(new SRNextObjectiveContext(deviceId)); + flowObjectiveService.next(deviceId, nextObjective); + } else if (isMaster) { log.warn("linkUp in device {}, but global store has no record " + "for neighbor-set {}", deviceId, ns); } @@ -331,8 +335,8 @@ public class DefaultGroupHandler { } /** - * Returns the next objective associated with the neighborset. - * If there is no next objective for this neighborset, this API + * Returns the next objective of type hashed associated with the neighborset. + * If there is no next objective for this neighborset, this method * would create a next objective and return. Optionally metadata can be * passed in for the creation of the next objective. * @@ -372,9 +376,10 @@ public class DefaultGroupHandler { } /** - * Returns the next objective associated with the subnet. - * If there is no next objective for this subnet, this API - * would create a next objective and return. + * Returns the next objective of type broadcast associated with the subnet, + * or -1 if no such objective exists. Note that this method does NOT create + * the next objective as a side-effect. It is expected that is objective is + * created at startup from network configuration. * * @param prefix subnet information * @return int if found or -1 @@ -387,6 +392,38 @@ public class DefaultGroupHandler { } /** + * Returns the next objective of type simple associated with the port on the + * device, given the treatment. Different treatments to the same port result + * in different next objectives. If no such objective exists, this method + * creates one and returns the id. Optionally metadata can be passed in for + * the creation of the objective. + * + * @param portNum the port number for the simple next objective + * @param treatment the actions to apply on the packets (should include outport) + * @param meta optional metadata passed into the creation of the next objective + * @return int if found or created, -1 if there are errors during the + * creation of the next objective. + */ + public int getPortNextObjectiveId(PortNumber portNum, TrafficTreatment treatment, + TrafficSelector meta) { + Integer nextId = portNextObjStore. + get(new PortNextObjectiveStoreKey(deviceId, portNum, treatment)); + if (nextId == null) { + log.trace("getPortNextObjectiveId in device{}: Next objective id " + + "not found for {} and {} creating", deviceId, portNum); + createGroupFromPort(portNum, treatment, meta); + nextId = portNextObjStore.get( + new PortNextObjectiveStoreKey(deviceId, portNum, treatment)); + if (nextId == null) { + log.warn("getPortNextObjectiveId: unable to create next obj" + + "for dev:{} port{}", deviceId, portNum); + return -1; + } + } + return nextId; + } + + /** * Checks if the next objective ID (group) for the neighbor set exists or not. * * @param ns neighbor set to check @@ -561,7 +598,7 @@ public class DefaultGroupHandler { } } if (meta != null) { - nextObjBuilder.setMeta(meta); + nextObjBuilder.withMeta(meta); } NextObjective nextObj = nextObjBuilder. add(new SRNextObjectiveContext(deviceId)); @@ -574,7 +611,10 @@ public class DefaultGroupHandler { } } - + /** + * Creates broadcast groups for all ports in the same configured subnet. + * + */ public void createGroupsFromSubnetConfig() { Map<Ip4Prefix, List<PortNumber>> subnetPortMap = this.deviceConfig.getSubnetPortsMap(this.deviceId); @@ -612,6 +652,37 @@ public class DefaultGroupHandler { }); } + + /** + * Create simple next objective for a single port. The treatments can include + * all outgoing actions that need to happen on the packet. + * + * @param portNum the outgoing port on the device + * @param treatment the actions to apply on the packets (should include outport) + * @param meta optional data to pass to the driver + */ + public void createGroupFromPort(PortNumber portNum, TrafficTreatment treatment, + TrafficSelector meta) { + int nextId = flowObjectiveService.allocateNextId(); + PortNextObjectiveStoreKey key = new PortNextObjectiveStoreKey( + deviceId, portNum, treatment); + + NextObjective.Builder nextObjBuilder = DefaultNextObjective + .builder().withId(nextId) + .withType(NextObjective.Type.SIMPLE) + .addTreatment(treatment) + .fromApp(appId) + .withMeta(meta); + + NextObjective nextObj = nextObjBuilder.add(); + flowObjectiveService.next(deviceId, nextObj); + log.debug("createGroupFromPort: Submited next objective {} in device {} " + + "for port {}", nextId, deviceId, portNum); + + portNextObjStore.put(key, nextId); + } + + public GroupKey getGroupKey(Object obj) { return new DefaultGroupKey(kryo.build().serialize(obj)); } diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultTransitGroupHandler.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultTransitGroupHandler.java index 14d77ba6..7a43e73d 100644 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultTransitGroupHandler.java +++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultTransitGroupHandler.java @@ -50,9 +50,11 @@ public class DefaultTransitGroupHandler extends DefaultGroupHandler { NeighborSetNextObjectiveStoreKey, Integer> nsNextObjStore, EventuallyConsistentMap<SubnetNextObjectiveStoreKey, - Integer> subnetNextObjStore) { + Integer> subnetNextObjStore, + EventuallyConsistentMap<PortNextObjectiveStoreKey, + Integer> portNextObjStore) { super(deviceId, appId, config, linkService, flowObjService, - nsNextObjStore, subnetNextObjStore); + nsNextObjStore, subnetNextObjStore, portNextObjStore); } @Override diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/PolicyGroupHandler.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/PolicyGroupHandler.java index 55142078..ef143dc7 100644 --- a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/PolicyGroupHandler.java +++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/PolicyGroupHandler.java @@ -68,9 +68,11 @@ public class PolicyGroupHandler extends DefaultGroupHandler { EventuallyConsistentMap<NeighborSetNextObjectiveStoreKey, Integer> nsNextObjStore, EventuallyConsistentMap<SubnetNextObjectiveStoreKey, - Integer> subnetNextObjStore) { + Integer> subnetNextObjStore, + EventuallyConsistentMap<PortNextObjectiveStoreKey, + Integer> portNextObjStore) { super(deviceId, appId, config, linkService, flowObjService, - nsNextObjStore, subnetNextObjStore); + nsNextObjStore, subnetNextObjStore, portNextObjStore); } public PolicyGroupIdentifier createPolicyGroupChain(String id, diff --git a/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/PortNextObjectiveStoreKey.java b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/PortNextObjectiveStoreKey.java new file mode 100644 index 00000000..5555565c --- /dev/null +++ b/framework/src/onos/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/PortNextObjectiveStoreKey.java @@ -0,0 +1,77 @@ +package org.onosproject.segmentrouting.grouphandler; + +import org.onosproject.net.DeviceId; +import org.onosproject.net.PortNumber; +import org.onosproject.net.flow.TrafficTreatment; + +import java.util.Objects; + +/** + * Class definition of Key for Device/Port to NextObjective store. Since there + * can be multiple next objectives to the same physical port, we differentiate + * between them by including the treatment in the key. + */ +public class PortNextObjectiveStoreKey { + private final DeviceId deviceId; + private final PortNumber portNum; + private final TrafficTreatment treatment; + + public PortNextObjectiveStoreKey(DeviceId deviceId, PortNumber portNum, + TrafficTreatment treatment) { + this.deviceId = deviceId; + this.portNum = portNum; + this.treatment = treatment; + } + + /** + * Gets device id in this PortNextObjectiveStoreKey. + * + * @return device id + */ + public DeviceId deviceId() { + return deviceId; + } + + /** + * Gets port information in this PortNextObjectiveStoreKey. + * + * @return port information + */ + public PortNumber portNumber() { + return portNum; + } + + /** + * Gets treatment information in this PortNextObjectiveStoreKey. + * + * @return treatment information + */ + public TrafficTreatment treatment() { + return treatment; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof PortNextObjectiveStoreKey)) { + return false; + } + PortNextObjectiveStoreKey that = + (PortNextObjectiveStoreKey) o; + return (Objects.equals(this.deviceId, that.deviceId) && + Objects.equals(this.portNum, that.portNum) && + Objects.equals(this.treatment, that.treatment)); + } + + @Override + public int hashCode() { + return Objects.hash(deviceId, portNum, treatment); + } + + @Override + public String toString() { + return "Device: " + deviceId + " Port: " + portNum + " Treatment: " + treatment; + } +} diff --git a/framework/src/onos/apps/segmentrouting/src/test/java/org/onosproject/segmentrouting/config/SegmentRoutingConfigTest.java b/framework/src/onos/apps/segmentrouting/src/test/java/org/onosproject/segmentrouting/config/SegmentRoutingConfigTest.java new file mode 100644 index 00000000..3e5daa5b --- /dev/null +++ b/framework/src/onos/apps/segmentrouting/src/test/java/org/onosproject/segmentrouting/config/SegmentRoutingConfigTest.java @@ -0,0 +1,157 @@ +/* + * Copyright 2014-2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onosproject.segmentrouting.config; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.Before; +import org.junit.Test; +import org.onlab.packet.IpAddress; +import org.onlab.packet.MacAddress; +import org.onosproject.net.DeviceId; +import org.onosproject.net.config.Config; +import org.onosproject.net.config.ConfigApplyDelegate; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import static org.junit.Assert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertTrue; + +/** + * Tests for class {@link SegmentRoutingConfig}. + */ +public class SegmentRoutingConfigTest { + private SegmentRoutingConfig config; + private Map<Integer, Set<Integer>> adjacencySids1; + private Map<Integer, Set<Integer>> adjacencySids2; + + @Before + public void setUp() throws Exception { + String jsonString = "{" + + "\"name\" : \"Leaf-R1\"," + + "\"nodeSid\" : 101," + + "\"routerIp\" : \"10.0.1.254\"," + + "\"routerMac\" : \"00:00:00:00:01:80\"," + + "\"isEdgeRouter\" : true," + + "\"adjacencySids\" : [" + + " { \"adjSid\" : 100, \"ports\" : [2, 3] }," + + " { \"adjSid\" : 200, \"ports\" : [4, 5] }" + + "]}"; + + adjacencySids1 = new HashMap<>(); + Set<Integer> ports1 = new HashSet<>(); + ports1.add(2); + ports1.add(3); + adjacencySids1.put(100, ports1); + Set<Integer> ports2 = new HashSet<>(); + ports2.add(4); + ports2.add(5); + adjacencySids1.put(200, ports2); + + adjacencySids2 = new HashMap<>(); + Set<Integer> ports3 = new HashSet<>(); + ports3.add(6); + adjacencySids2.put(300, ports3); + + DeviceId subject = DeviceId.deviceId("of:0000000000000001"); + String key = "org.onosproject.segmentrouting"; + ObjectMapper mapper = new ObjectMapper(); + JsonNode jsonNode = mapper.readTree(jsonString); + ConfigApplyDelegate delegate = new MockDelegate(); + + config = new SegmentRoutingConfig(); + config.init(subject, key, jsonNode, mapper, delegate); + } + + @Test + public void testName() throws Exception { + assertTrue(config.name().isPresent()); + assertThat(config.name().get(), is("Leaf-R1")); + } + + @Test + public void testSetName() throws Exception { + config.setName("Spine-R1"); + assertTrue(config.name().isPresent()); + assertThat(config.name().get(), is("Spine-R1")); + } + + @Test + public void testRouterIp() throws Exception { + assertThat(config.routerIp(), is(IpAddress.valueOf("10.0.1.254"))); + } + + @Test + public void testSetRouterIp() throws Exception { + config.setRouterIp("10.0.2.254"); + assertThat(config.routerIp(), is(IpAddress.valueOf("10.0.2.254"))); + } + + @Test + public void testRouterMac() throws Exception { + assertThat(config.routerMac(), is(MacAddress.valueOf("00:00:00:00:01:80"))); + } + + @Test + public void testSetRouterMac() throws Exception { + config.setRouterMac("00:00:00:00:02:80"); + assertThat(config.routerMac(), is(MacAddress.valueOf("00:00:00:00:02:80"))); + } + + @Test + public void testNodeSid() throws Exception { + assertThat(config.nodeSid(), is(101)); + } + + @Test + public void testSetNodeSid() throws Exception { + config.setNodeSid(200); + assertThat(config.nodeSid(), is(200)); + } + + @Test + public void testIsEdgeRouter() throws Exception { + assertThat(config.isEdgeRouter(), is(true)); + } + + @Test + public void testSetIsEdgeRouter() throws Exception { + config.setIsEdgeRouter(false); + assertThat(config.isEdgeRouter(), is(false)); + } + + @Test + public void testAdjacencySids() throws Exception { + assertThat(config.adjacencySids(), is(adjacencySids1)); + } + + @Test + public void testSetAdjacencySids() throws Exception { + config.setAdjacencySids(adjacencySids2); + assertThat(config.adjacencySids(), is(adjacencySids2)); + } + + private class MockDelegate implements ConfigApplyDelegate { + @Override + public void onApply(Config config) { + } + } +}
\ No newline at end of file diff --git a/framework/src/onos/apps/test/intent-perf/src/main/java/org/onosproject/intentperf/IntentPerfCollector.java b/framework/src/onos/apps/test/intent-perf/src/main/java/org/onosproject/intentperf/IntentPerfCollector.java index 8c160e85..cae5455d 100644 --- a/framework/src/onos/apps/test/intent-perf/src/main/java/org/onosproject/intentperf/IntentPerfCollector.java +++ b/framework/src/onos/apps/test/intent-perf/src/main/java/org/onosproject/intentperf/IntentPerfCollector.java @@ -106,7 +106,7 @@ public class IntentPerfCollector { /** * Clears all previously accumulated data. */ - public void clearSamples() { + public synchronized void clearSamples() { newestTime = 0; overall = new Sample(0, nodes.length); current = new Sample(0, nodes.length); diff --git a/framework/src/onos/apps/vtn/pom.xml b/framework/src/onos/apps/vtn/pom.xml index a42f91a0..e4528517 100644 --- a/framework/src/onos/apps/vtn/pom.xml +++ b/framework/src/onos/apps/vtn/pom.xml @@ -61,6 +61,12 @@ <scope>test</scope> </dependency> <dependency> + <groupId>org.onosproject</groupId> + <artifactId>onos-api</artifactId> + <scope>test</scope> + <classifier>tests</classifier> + </dependency> + <dependency> <groupId>com.sun.jersey</groupId> <artifactId>jersey-servlet</artifactId> </dependency> diff --git a/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/forwarder/ServiceFunctionForwarder.java b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/forwarder/ServiceFunctionForwarderService.java index e91e6b69..0ed42fcf 100644 --- a/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/forwarder/ServiceFunctionForwarder.java +++ b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/forwarder/ServiceFunctionForwarderService.java @@ -15,29 +15,37 @@ */ package org.onosproject.sfc.forwarder; -import org.onosproject.core.ApplicationId; import org.onosproject.net.flowobjective.Objective; +import org.onosproject.net.NshServicePathId; import org.onosproject.vtnrsc.PortChain; /** * Abstraction of an entity which provides Service function forwarder. */ -public interface ServiceFunctionForwarder { +public interface ServiceFunctionForwarderService { /** - * Install Service function chain. + * Install Forwarding rule. * - * @param portChain Port chain + * @param portChain port-chain + * @param nshSPI nsh spi */ - void install(PortChain portChain); + void installForwardingRule(PortChain portChain, NshServicePathId nshSPI); /** - * Programs forwarding object for Service Function. + * Uninstall Forwarding rule. * - * @param portChain port chain - * @param appid application id + * @param portChain port-chain + * @param nshSPI nsh spi + */ + void unInstallForwardingRule(PortChain portChain, NshServicePathId nshSPI); + + /** + * Prepare forwarding object for Service Function. + * + * @param portChain port-chain + * @param nshSPI nsh spi * @param type forwarding objective operation type */ - void programServiceFunctionForwarder(PortChain portChain, ApplicationId appid, - Objective.Operation type); + void prepareServiceFunctionForwarder(PortChain portChain, NshServicePathId nshSPI, Objective.Operation type); } diff --git a/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/forwarder/impl/ServiceFunctionForwarderImpl.java b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/forwarder/impl/ServiceFunctionForwarderImpl.java new file mode 100644 index 00000000..2846ee01 --- /dev/null +++ b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/forwarder/impl/ServiceFunctionForwarderImpl.java @@ -0,0 +1,293 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.sfc.forwarder.impl; + +import static org.slf4j.LoggerFactory.getLogger; +import static org.onosproject.net.flow.criteria.ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_NSH_SPI; +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.List; +import java.util.ListIterator; + +import org.apache.felix.scr.annotations.Reference; +import org.apache.felix.scr.annotations.ReferenceCardinality; +import org.onlab.osgi.DefaultServiceDirectory; +import org.onlab.osgi.ServiceDirectory; +import org.onlab.packet.MacAddress; +import org.onlab.packet.VlanId; +import org.onosproject.core.ApplicationId; +import org.onosproject.net.behaviour.ExtensionSelectorResolver; +import org.onosproject.net.DeviceId; +import org.onosproject.net.NshServicePathId; +import org.onosproject.net.driver.DriverHandler; +import org.onosproject.net.driver.DriverService; +import org.onosproject.net.flow.DefaultTrafficSelector; +import org.onosproject.net.flow.DefaultTrafficTreatment; +import org.onosproject.net.flow.criteria.ExtensionSelector; +import org.onosproject.net.flow.TrafficSelector; +import org.onosproject.net.flow.TrafficTreatment; +import org.onosproject.net.flowobjective.DefaultForwardingObjective; +import org.onosproject.net.flowobjective.FlowObjectiveService; +import org.onosproject.net.flowobjective.ForwardingObjective; +import org.onosproject.net.flowobjective.Objective; +import org.onosproject.net.flowobjective.ForwardingObjective.Flag; +import org.onosproject.vtnrsc.VirtualPortId; +import org.onosproject.vtnrsc.service.VtnRscService; +import org.onosproject.vtnrsc.PortChain; +import org.onosproject.vtnrsc.PortPair; +import org.onosproject.vtnrsc.PortPairGroup; +import org.onosproject.vtnrsc.PortPairGroupId; +import org.onosproject.vtnrsc.PortPairId; +import org.onosproject.vtnrsc.virtualport.VirtualPortService; +import org.onosproject.vtnrsc.portpair.PortPairService; +import org.onosproject.vtnrsc.portpairgroup.PortPairGroupService; +import org.onosproject.vtnrsc.flowclassifier.FlowClassifierService; +import org.onosproject.vtnrsc.portchain.PortChainService; +import org.onosproject.sfc.forwarder.ServiceFunctionForwarderService; + +import org.slf4j.Logger; + +/** + * Provides Service Function Forwarder implementation. + */ +public class ServiceFunctionForwarderImpl implements ServiceFunctionForwarderService { + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected DriverService driverService; + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected VirtualPortService virtualPortService; + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected VtnRscService vtnRscService; + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected PortPairService portPairService; + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected PortPairGroupService portPairGroupService; + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected FlowClassifierService flowClassifierService; + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected PortChainService portChainService; + + private final Logger log = getLogger(getClass()); + protected ApplicationId appId; + protected FlowObjectiveService flowObjectiveService; + + private static final String DRIVER_NAME = "onosfw"; + private static final String PORT_CHAIN_NOT_NULL = "Port-Chain cannot be null"; + private static final String PORT_CHAIN_ID_NOT_NULL = "Port-Chain-Id cannot be null"; + private static final String APP_ID_NOT_NULL = "Application-Id cannot be null"; + private static final int NULL = 0; + + /** + * Default constructor. + */ + public ServiceFunctionForwarderImpl() { + } + + /** + * Explicit constructor. + */ + public ServiceFunctionForwarderImpl(ApplicationId appId) { + this.appId = checkNotNull(appId, APP_ID_NOT_NULL); + ServiceDirectory serviceDirectory = new DefaultServiceDirectory(); + this.flowObjectiveService = serviceDirectory.get(FlowObjectiveService.class); + } + + @Override + public void installForwardingRule(PortChain portChain, NshServicePathId nshSPI) { + checkNotNull(portChain, PORT_CHAIN_NOT_NULL); + prepareServiceFunctionForwarder(portChain, nshSPI, Objective.Operation.ADD); + } + + @Override + public void unInstallForwardingRule(PortChain portChain, NshServicePathId nshSPI) { + checkNotNull(portChain, PORT_CHAIN_NOT_NULL); + prepareServiceFunctionForwarder(portChain, nshSPI, Objective.Operation.REMOVE); + } + + @Override + public void prepareServiceFunctionForwarder(PortChain portChain, NshServicePathId nshSPI, + Objective.Operation type) { + + // Go through the port pair group list + List<PortPairGroupId> portPairGrpList = portChain.portPairGroups(); + ListIterator<PortPairGroupId> listGrpIterator = portPairGrpList.listIterator(); + + // Get source port pair group + if (!listGrpIterator.hasNext()) { + return; + } + PortPairGroupId portPairGrpId = listGrpIterator.next(); + PortPairGroup currentPortPairGroup = portPairGroupService.getPortPairGroup(portPairGrpId); + + // Get destination port pair group + if (!listGrpIterator.hasNext()) { + return; + } + portPairGrpId = listGrpIterator.next(); + PortPairGroup nextPortPairGroup = portPairGroupService.getPortPairGroup(portPairGrpId); + + // push SFF to OVS + pushServiceFunctionForwarder(currentPortPairGroup, nextPortPairGroup, listGrpIterator, nshSPI, type); + } + + /** + * Push service-function-forwarder to OVS. + * + * @param currentPortPairGroup current port-pair-group + * @param nextPortPairGroup next port-pair-group + * @param listGrpIterator pointer to port-pair-group list + */ + public void pushServiceFunctionForwarder(PortPairGroup currentPortPairGroup, PortPairGroup nextPortPairGroup, + ListIterator<PortPairGroupId> listGrpIterator, NshServicePathId nshSPI, Objective.Operation type) { + MacAddress srcMacAddress = null; + MacAddress dstMacAddress = null; + DeviceId deviceId = null; + DeviceId currentDeviceId = null; + DeviceId nextDeviceId = null; + PortPairGroupId portPairGrpId = null; + + // Travel from SF to SF. + do { + // Get the required information on port pairs from source port pair + // group + List<PortPairId> portPairList = currentPortPairGroup.portPairs(); + ListIterator<PortPairId> portPLIterator = portPairList.listIterator(); + if (!portPLIterator.hasNext()) { + break; + } + + PortPairId portPairId = portPLIterator.next(); + PortPair portPair = portPairService.getPortPair(portPairId); + + currentDeviceId = vtnRscService.getSFToSFFMaping(VirtualPortId.portId(portPair.ingress())); + if (deviceId == null) { + deviceId = currentDeviceId; + } + srcMacAddress = virtualPortService.getPort(VirtualPortId.portId(portPair.ingress())).macAddress(); + dstMacAddress = virtualPortService.getPort(VirtualPortId.portId(portPair.egress())).macAddress(); + + // pack traffic selector + TrafficSelector.Builder selector = packTrafficSelector(deviceId, srcMacAddress, dstMacAddress, nshSPI); + + // Get the required information on port pairs from destination port + // pair group + portPairList = nextPortPairGroup.portPairs(); + portPLIterator = portPairList.listIterator(); + if (!portPLIterator.hasNext()) { + break; + } + + portPairId = portPLIterator.next(); + portPair = portPairService.getPortPair(portPairId); + + nextDeviceId = vtnRscService.getSFToSFFMaping(VirtualPortId.portId(portPair.ingress())); + + // pack traffic treatment + TrafficTreatment.Builder treatment = packTrafficTreatment(currentDeviceId, nextDeviceId, portPair); + + // Send SFF to OVS + sendServiceFunctionForwarder(selector, treatment, deviceId, type); + + // Replace source port pair group with destination port pair group + // for moving to next SFF processing. + currentPortPairGroup = nextPortPairGroup; + if (!listGrpIterator.hasNext()) { + break; + } + portPairGrpId = listGrpIterator.next(); + nextPortPairGroup = portPairGroupService.getPortPairGroup(portPairGrpId); + } while (true); + } + + /** + * Pack Traffic selector. + * + * @param deviceId device id + * @param srcMacAddress source mac-address + * @param dstMacAddress destination mac-address + * @param nshSPI nsh spi + * @return traffic treatment + */ + public TrafficSelector.Builder packTrafficSelector(DeviceId deviceId, MacAddress srcMacAddress, + MacAddress dstMacAddress, NshServicePathId nshSPI) { + TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); + selector.matchEthSrc(srcMacAddress); + selector.matchEthDst(dstMacAddress); + + DriverHandler handler = driverService.createHandler(deviceId); + ExtensionSelectorResolver resolver = handler.behaviour(ExtensionSelectorResolver.class); + ExtensionSelector nspSpiSelector = resolver.getExtensionSelector(NICIRA_MATCH_NSH_SPI.type()); + + try { + nspSpiSelector.setPropertyValue("nshSpi", nshSPI); + } catch (Exception e) { + log.error("Failed to get extension instruction to set Nsh Spi Id {}", deviceId); + } + + selector.extension(nspSpiSelector, deviceId); + return selector; + } + + /** + * Pack Traffic treatment. + * + * @param currentDeviceId current device id + * @param nextDeviceId next device id + * @param portPair port-pair + * @return traffic treatment + */ + public TrafficTreatment.Builder packTrafficTreatment(DeviceId currentDeviceId, DeviceId nextDeviceId, + PortPair portPair) { + MacAddress srcMacAddress = null; + MacAddress dstMacAddress = null; + + // Check the treatment whether destination SF is on same OVS or in + // different OVS. + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); + if (currentDeviceId.equals(nextDeviceId)) { + srcMacAddress = virtualPortService.getPort(VirtualPortId.portId(portPair.ingress())).macAddress(); + dstMacAddress = virtualPortService.getPort(VirtualPortId.portId(portPair.egress())).macAddress(); + treatment.setEthSrc(srcMacAddress); + treatment.setEthDst(dstMacAddress); + } else { + treatment.setVlanId(VlanId.vlanId(Short.parseShort((vtnRscService.getL3vni(portPair + .tenantId()).toString())))); + } + + return treatment; + } + + /** + * Send service function forwarder to OVS. + * + * @param selector traffic selector + * @param treatment traffic treatment + * @param deviceId device id + * @param type operation type + */ + public void sendServiceFunctionForwarder(TrafficSelector.Builder selector, TrafficTreatment.Builder treatment, + DeviceId deviceId, Objective.Operation type) { + ForwardingObjective.Builder objective = DefaultForwardingObjective.builder().withTreatment(treatment.build()) + .withSelector(selector.build()).fromApp(appId).makePermanent().withFlag(Flag.SPECIFIC); + if (type.equals(Objective.Operation.ADD)) { + log.debug("ADD"); + flowObjectiveService.forward(deviceId, objective.add()); + } else { + log.debug("REMOVE"); + flowObjectiveService.forward(deviceId, objective.remove()); + } + } +} diff --git a/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/forwarder/impl/package-info.java b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/forwarder/impl/package-info.java new file mode 100644 index 00000000..02221196 --- /dev/null +++ b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/forwarder/impl/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * SFC Service manager for interacting with SFC. + */ +package org.onosproject.sfc.forwarder.impl; diff --git a/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/manager/NshSpiIdGenerators.java b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/manager/NshSpiIdGenerators.java new file mode 100644 index 00000000..1dbe8c8f --- /dev/null +++ b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/manager/NshSpiIdGenerators.java @@ -0,0 +1,51 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.sfc.manager; + +import java.util.concurrent.atomic.AtomicInteger; + +/** + * Unique NSH SPI Id generator for NSH header. + */ +public final class NshSpiIdGenerators { + + private static final AtomicInteger NSH_SPI_ID_GEN = new AtomicInteger(); + private static final int MAX_NSH_SPI_ID = 0x7FFFFFFF; + private static int nshSpiId; + + /** + * Default constructor. + */ + private NshSpiIdGenerators() { + } + + /** + * Get the next NSH SPI id. + * + * @return NSH SPI id + */ + public static int create() { + do { + if (nshSpiId >= MAX_NSH_SPI_ID) { + if (NSH_SPI_ID_GEN.get() >= MAX_NSH_SPI_ID) { + NSH_SPI_ID_GEN.set(0); + } + } + nshSpiId = NSH_SPI_ID_GEN.incrementAndGet(); + } while (nshSpiId > MAX_NSH_SPI_ID); + return nshSpiId; + } +} diff --git a/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/manager/SfcService.java b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/manager/SfcService.java index ef5fc529..4af2d47c 100644 --- a/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/manager/SfcService.java +++ b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/manager/SfcService.java @@ -15,6 +15,11 @@ */ package org.onosproject.sfc.manager; +import org.onosproject.vtnrsc.PortPair; +import org.onosproject.vtnrsc.PortPairGroup; +import org.onosproject.vtnrsc.FlowClassifier; +import org.onosproject.vtnrsc.PortChain; + /** * SFC application that applies flows to the device. */ @@ -23,48 +28,64 @@ public interface SfcService { /** * When port-pair is created, check whether Forwarding Rule needs to be * updated in OVS. + * + * @param portPair port-pair */ - public void onPortPairCreated(); + void onPortPairCreated(PortPair portPair); /** * When port-pair is deleted, check whether Forwarding Rule needs to be * updated in OVS. + * + * @param portPair port-pair */ - public void onPortPairDeleted(); + void onPortPairDeleted(PortPair portPair); /** * When port-pair-group is created, check whether Forwarding Rule needs to * be updated in OVS. + * + * @param portPairGroup port-pair-group */ - public void onPortPairGroupCreated(); + void onPortPairGroupCreated(PortPairGroup portPairGroup); /** * When port-pair-group is deleted, check whether Forwarding Rule needs to * be updated in OVS. + * + * @param portPairGroup port-pair-group */ - public void onPortPairGroupDeleted(); + void onPortPairGroupDeleted(PortPairGroup portPairGroup); /** * When flow-classifier is created, check whether Forwarding Rule needs to * be updated in OVS. + * + * @param flowClassifier flow-classifier */ - public void onFlowClassifierCreated(); + void onFlowClassifierCreated(FlowClassifier flowClassifier); /** * When flow-classifier is deleted, check whether Forwarding Rule needs to * be updated in OVS. + * + * @param flowClassifier flow-classifier */ - public void onFlowClassifierDeleted(); + void onFlowClassifierDeleted(FlowClassifier flowClassifier); /** * When port-chain is created, check whether Forwarding Rule needs to be * updated in OVS. + * + * @param portChain port-chain */ - public void onPortChainCreated(); + void onPortChainCreated(PortChain portChain); /** * When port-chain is deleted, check whether Forwarding Rule needs to be * updated in OVS. + * + * @param portChain port-chain */ - public void onPortChainDeleted(); + void onPortChainDeleted(PortChain portChain); } diff --git a/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/manager/impl/SfcManager.java b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/manager/impl/SfcManager.java index 12d27c87..4df07929 100644 --- a/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/manager/impl/SfcManager.java +++ b/framework/src/onos/apps/vtn/sfcmgr/src/main/java/org/onosproject/sfc/manager/impl/SfcManager.java @@ -20,9 +20,26 @@ import static org.slf4j.LoggerFactory.getLogger; import org.apache.felix.scr.annotations.Activate; import org.apache.felix.scr.annotations.Component; import org.apache.felix.scr.annotations.Deactivate; +import org.apache.felix.scr.annotations.Reference; +import org.apache.felix.scr.annotations.ReferenceCardinality; import org.apache.felix.scr.annotations.Service; +import org.onlab.util.KryoNamespace; +import org.onosproject.core.ApplicationId; +import org.onosproject.core.CoreService; import org.onosproject.sfc.manager.SfcService; +import org.onosproject.vtnrsc.PortPair; +import org.onosproject.vtnrsc.PortPairId; +import org.onosproject.vtnrsc.PortPairGroup; +import org.onosproject.vtnrsc.PortPairGroupId; +import org.onosproject.vtnrsc.FlowClassifier; +import org.onosproject.vtnrsc.FlowClassifierId; import org.onosproject.vtnrsc.PortChain; +import org.onosproject.vtnrsc.PortChainId; +import org.onosproject.vtnrsc.TenantId; +import org.onosproject.vtnrsc.event.VtnRscEvent; +import org.onosproject.vtnrsc.event.VtnRscListener; +import org.onosproject.vtnrsc.service.VtnRscService; + import org.slf4j.Logger; /** @@ -33,93 +50,137 @@ import org.slf4j.Logger; public class SfcManager implements SfcService { private final Logger log = getLogger(getClass()); + private static final String APP_ID = "org.onosproject.app.vtn"; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected VtnRscService vtnRscService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected CoreService coreService; + + protected ApplicationId appId; + + private final VtnRscListener vtnRscListener = new InnerVtnRscListener(); @Activate public void activate() { + appId = coreService.registerApplication(APP_ID); + + vtnRscService.addListener(vtnRscListener); + + KryoNamespace.Builder serializer = KryoNamespace.newBuilder() + .register(TenantId.class) + .register(PortPairId.class) + .register(PortPairGroupId.class) + .register(FlowClassifierId.class) + .register(PortChainId.class); + log.info("Started"); } @Deactivate public void deactivate() { + vtnRscService.removeListener(vtnRscListener); + log.info("Stopped"); } + /* + * Handle events. + */ + private class InnerVtnRscListener implements VtnRscListener { + @Override + public void event(VtnRscEvent event) { + + if (VtnRscEvent.Type.PORT_PAIR_PUT == event.type()) { + PortPair portPair = (PortPair) event.subject(); + onPortPairCreated(portPair); + } else if (VtnRscEvent.Type.PORT_PAIR_DELETE == event.type()) { + PortPair portPair = (PortPair) event.subject(); + onPortPairDeleted(portPair); + } else if (VtnRscEvent.Type.PORT_PAIR_UPDATE == event.type()) { + PortPair portPair = (PortPair) event.subject(); + onPortPairDeleted(portPair); + onPortPairCreated(portPair); + } else if (VtnRscEvent.Type.PORT_PAIR_GROUP_PUT == event.type()) { + PortPairGroup portPairGroup = (PortPairGroup) event.subject(); + onPortPairGroupCreated(portPairGroup); + } else if (VtnRscEvent.Type.PORT_PAIR_GROUP_DELETE == event.type()) { + PortPairGroup portPairGroup = (PortPairGroup) event.subject(); + onPortPairGroupDeleted(portPairGroup); + } else if (VtnRscEvent.Type.PORT_PAIR_GROUP_UPDATE == event.type()) { + PortPairGroup portPairGroup = (PortPairGroup) event.subject(); + onPortPairGroupDeleted(portPairGroup); + onPortPairGroupCreated(portPairGroup); + } else if (VtnRscEvent.Type.FLOW_CLASSIFIER_PUT == event.type()) { + FlowClassifier flowClassifier = (FlowClassifier) event.subject(); + onFlowClassifierCreated(flowClassifier); + } else if (VtnRscEvent.Type.FLOW_CLASSIFIER_DELETE == event.type()) { + FlowClassifier flowClassifier = (FlowClassifier) event.subject(); + onFlowClassifierDeleted(flowClassifier); + } else if (VtnRscEvent.Type.FLOW_CLASSIFIER_UPDATE == event.type()) { + FlowClassifier flowClassifier = (FlowClassifier) event.subject(); + onFlowClassifierDeleted(flowClassifier); + onFlowClassifierCreated(flowClassifier); + } else if (VtnRscEvent.Type.PORT_CHAIN_PUT == event.type()) { + PortChain portChain = (PortChain) event.subject(); + onPortChainCreated(portChain); + } else if (VtnRscEvent.Type.PORT_CHAIN_DELETE == event.type()) { + PortChain portChain = (PortChain) event.subject(); + onPortChainDeleted(portChain); + } else if (VtnRscEvent.Type.PORT_CHAIN_UPDATE == event.type()) { + PortChain portChain = (PortChain) event.subject(); + onPortChainDeleted(portChain); + onPortChainCreated(portChain); + } + } + } + @Override - public void onPortPairCreated() { + public void onPortPairCreated(PortPair portPair) { log.debug("onPortPairCreated"); - // TODO: Process port-pair on creation. - // TODO: Parameter also needs to be modified. + // TODO: Modify forwarding rule on port-pair creation. } @Override - public void onPortPairDeleted() { + public void onPortPairDeleted(PortPair portPair) { log.debug("onPortPairDeleted"); - // TODO: Process port-pair on deletion. - // TODO: Parameter also needs to be modified. + // TODO: Modify forwarding rule on port-pair deletion. } @Override - public void onPortPairGroupCreated() { + public void onPortPairGroupCreated(PortPairGroup portPairGroup) { log.debug("onPortPairGroupCreated"); - // TODO: Process port-pair-group on creation. - // TODO: Parameter also needs to be modified. + // TODO: Modify forwarding rule on port-pair-group creation. } @Override - public void onPortPairGroupDeleted() { + public void onPortPairGroupDeleted(PortPairGroup portPairGroup) { log.debug("onPortPairGroupDeleted"); - // TODO: Process port-pair-group on deletion. - // TODO: Parameter also needs to be modified. + // TODO: Modify forwarding rule on port-pair-group deletion. } @Override - public void onFlowClassifierCreated() { + public void onFlowClassifierCreated(FlowClassifier flowClassifier) { log.debug("onFlowClassifierCreated"); - // TODO: Process flow-classifier on creation. - // TODO: Parameter also needs to be modified. + // TODO: Modify forwarding rule on flow-classifier creation. } @Override - public void onFlowClassifierDeleted() { + public void onFlowClassifierDeleted(FlowClassifier flowClassifier) { log.debug("onFlowClassifierDeleted"); - // TODO: Process flow-classifier on deletion. - // TODO: Parameter also needs to be modified. + // TODO: Modify forwarding rule on flow-classifier deletion. } @Override - public void onPortChainCreated() { - log.debug("onPortChainCreated"); - // TODO: Process port-chain on creation. - // TODO: Parameter also needs to be modified. - + public void onPortChainCreated(PortChain portChain) { + log.debug("onPortChainCreated"); + //TODO: Apply forwarding rule on port-chain creation. } @Override - public void onPortChainDeleted() { + public void onPortChainDeleted(PortChain portChain) { log.debug("onPortChainDeleted"); - // TODO: Process port-chain on deletion. - // TODO: Parameter also needs to be modified. - } - - /** - * Install SF Forwarding rule into OVS. - * - * @param portChain - * port chain - */ - public void installForwardingRule(PortChain portChain) { - log.debug("installForwardingRule"); - // TODO: Installation of SF Forwarding rule into OVS. - } - - /** - * Uninstall SF Forwarding rule from OVS. - * - * @param portChain - * port chain - */ - public void unInstallForwardingRule(PortChain portChain) { - log.debug("unInstallForwardingRule"); - // TODO: Uninstallation of SF Forwarding rule from OVS. + //TODO: Apply forwarding rule on port-chain deletion. } -}
\ No newline at end of file +} diff --git a/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/manager/impl/SfcManagerTest.java b/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/manager/impl/SfcManagerTest.java new file mode 100644 index 00000000..e4f31f98 --- /dev/null +++ b/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/manager/impl/SfcManagerTest.java @@ -0,0 +1,269 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.sfc.manager.impl; + +import org.junit.Test; + +import java.util.List; +import java.util.LinkedList; + +import org.onlab.packet.IpPrefix; +import org.onosproject.sfc.manager.SfcService; +import org.onosproject.vtnrsc.DefaultPortChain; +import org.onosproject.vtnrsc.DefaultPortPair; +import org.onosproject.vtnrsc.DefaultPortPairGroup; +import org.onosproject.vtnrsc.PortChain; +import org.onosproject.vtnrsc.PortChainId; +import org.onosproject.vtnrsc.PortPair; +import org.onosproject.vtnrsc.PortPairGroup; +import org.onosproject.vtnrsc.PortPairGroupId; +import org.onosproject.vtnrsc.PortPairId; +import org.onosproject.vtnrsc.TenantId; +import org.onosproject.vtnrsc.DefaultFlowClassifier; +import org.onosproject.vtnrsc.FlowClassifierId; +import org.onosproject.vtnrsc.VirtualPortId; +import org.onosproject.vtnrsc.FlowClassifier; + +/** + * Unit tests for SfcManager class. + */ +public class SfcManagerTest { + /** + * Checks the operation of onPortPairCreated() method. + */ + @Test + public void testOnPortPairCreated() { + final PortPairId portPairId = PortPairId.of("78888888-fc23-aeb6-f44b-56dc5e2fb3ae"); + final TenantId tenantId = TenantId.tenantId("1"); + final String name = "PortPair"; + final String description = "PortPair"; + final String ingress = "d3333333-24fc-4fae-af4b-321c5e2eb3d1"; + final String egress = "a4444444-4a56-2a6e-cd3a-9dee4e2ec345"; + DefaultPortPair.Builder portPairBuilder = new DefaultPortPair.Builder(); + PortPair portPair = null; + SfcService sfcService = new SfcManager(); + + // create port pair + portPair = portPairBuilder.setId(portPairId).setTenantId(tenantId).setName(name).setDescription(description) + .setIngress(ingress).setEgress(egress).build(); + sfcService.onPortPairCreated(portPair); + } + + /** + * Checks the operation of onPortPairDeleted() method. + */ + @Test + public void testOnPortPairDeleted() { + final PortPairId portPairId = PortPairId.of("78888888-fc23-aeb6-f44b-56dc5e2fb3ae"); + final TenantId tenantId = TenantId.tenantId("1"); + final String name = "PortPair"; + final String description = "PortPair"; + final String ingress = "d3333333-24fc-4fae-af4b-321c5e2eb3d1"; + final String egress = "a4444444-4a56-2a6e-cd3a-9dee4e2ec345"; + DefaultPortPair.Builder portPairBuilder = new DefaultPortPair.Builder(); + PortPair portPair = null; + SfcService sfcService = new SfcManager(); + + // create port pair + portPair = portPairBuilder.setId(portPairId).setTenantId(tenantId).setName(name).setDescription(description) + .setIngress(ingress).setEgress(egress).build(); + sfcService.onPortPairDeleted(portPair); + } + + /** + * Checks the operation of onPortPairGroupCreated() method. + */ + @Test + public void testOnPortPairGroupCreated() { + final PortPairGroupId portPairGroupId = PortPairGroupId.of("78888888-fc23-aeb6-f44b-56dc5e2fb3ae"); + final TenantId tenantId = TenantId.tenantId("1"); + final String name = "PortPairGroup"; + final String description = "PortPairGroup"; + final List<PortPairId> portPairIdList = new LinkedList<PortPairId>(); + DefaultPortPairGroup.Builder portPairGroupBuilder = new DefaultPortPairGroup.Builder(); + PortPairGroup portPairGroup = null; + SfcService sfcService = new SfcManager(); + + // create port-pair-id list + PortPairId portPairId = PortPairId.of("73333333-fc23-aeb6-f44b-56dc5e2fb3ae"); + portPairIdList.add(portPairId); + portPairId = PortPairId.of("74444444-fc23-aeb6-f44b-56dc5e2fb3ae"); + portPairIdList.add(portPairId); + + // create port pair + portPairGroup = portPairGroupBuilder.setId(portPairGroupId).setTenantId(tenantId).setName(name) + .setDescription(description).setPortPairs(portPairIdList).build(); + sfcService.onPortPairGroupCreated(portPairGroup); + } + + /** + * Checks the operation of onPortPairGroupDeleted() method. + */ + @Test + public void testOnPortPairGroupDeleted() { + final PortPairGroupId portPairGroupId = PortPairGroupId.of("78888888-fc23-aeb6-f44b-56dc5e2fb3ae"); + final TenantId tenantId = TenantId.tenantId("1"); + final String name = "PortPairGroup"; + final String description = "PortPairGroup"; + final List<PortPairId> portPairIdList = new LinkedList<PortPairId>(); + DefaultPortPairGroup.Builder portPairGroupBuilder = new DefaultPortPairGroup.Builder(); + PortPairGroup portPairGroup = null; + SfcService sfcService = new SfcManager(); + + // create port-pair-id list + PortPairId portPairId = PortPairId.of("73333333-fc23-aeb6-f44b-56dc5e2fb3ae"); + portPairIdList.add(portPairId); + portPairId = PortPairId.of("74444444-fc23-aeb6-f44b-56dc5e2fb3ae"); + portPairIdList.add(portPairId); + + // create port pair + portPairGroup = portPairGroupBuilder.setId(portPairGroupId).setTenantId(tenantId).setName(name) + .setDescription(description).setPortPairs(portPairIdList).build(); + sfcService.onPortPairGroupDeleted(portPairGroup); + } + + /** + * Checks the operation of onFlowClassifierCreated() method. + */ + @Test + public void testOnFlowClassifierCreated() { + final String name = "FlowClassifier"; + final String description = "FlowClassifier"; + final String ethType = "IPv4"; + final String protocol = "udp"; + final int minSrcPortRange = 1024; + final int maxSrcPortRange = 5000; + final int minDstPortRange = 1024; + final int maxDstPortRange = 5000; + final FlowClassifierId flowClassifierId = FlowClassifierId.of("71111111-fc23-aeb6-f44b-56dc5e2fb3ae"); + final TenantId tenantId = TenantId.tenantId("8"); + final IpPrefix srcIpPrefix = IpPrefix.valueOf("0.0.0.0/0"); + final IpPrefix dstIpPrefix = IpPrefix.valueOf("100.100.100.100/0"); + final VirtualPortId virtualSrcPort = VirtualPortId.portId("100"); + final VirtualPortId virtualDstPort = VirtualPortId.portId("200"); + DefaultFlowClassifier.Builder flowClassifierBuilder = new DefaultFlowClassifier.Builder(); + FlowClassifier flowClassifier = null; + SfcService sfcService = new SfcManager(); + + // create flow classifier + flowClassifier = flowClassifierBuilder.setFlowClassifierId(flowClassifierId).setTenantId(tenantId) + .setName(name).setDescription(description).setEtherType(ethType).setProtocol(protocol) + .setMinSrcPortRange(minSrcPortRange).setMaxSrcPortRange(maxSrcPortRange) + .setMinDstPortRange(minDstPortRange).setMaxDstPortRange(maxDstPortRange).setSrcIpPrefix(srcIpPrefix) + .setDstIpPrefix(dstIpPrefix).setSrcPort(virtualSrcPort).setDstPort(virtualDstPort).build(); + sfcService.onFlowClassifierCreated(flowClassifier); + } + + /** + * Checks the operation of onFlowClassifierDeleted() method. + */ + @Test + public void testOnFlowClassifierDeleted() { + final String name = "FlowClassifier"; + final String description = "FlowClassifier"; + final String ethType = "IPv4"; + final String protocol = "udp"; + final int minSrcPortRange = 1024; + final int maxSrcPortRange = 5000; + final int minDstPortRange = 1024; + final int maxDstPortRange = 5000; + final FlowClassifierId flowClassifierId = FlowClassifierId.of("71111111-fc23-aeb6-f44b-56dc5e2fb3ae"); + final TenantId tenantId = TenantId.tenantId("8"); + final IpPrefix srcIpPrefix = IpPrefix.valueOf("0.0.0.0/0"); + final IpPrefix dstIpPrefix = IpPrefix.valueOf("100.100.100.100/0"); + final VirtualPortId virtualSrcPort = VirtualPortId.portId("100"); + final VirtualPortId virtualDstPort = VirtualPortId.portId("200"); + DefaultFlowClassifier.Builder flowClassifierBuilder = new DefaultFlowClassifier.Builder(); + FlowClassifier flowClassifier = null; + SfcService sfcService = new SfcManager(); + + // create flow classifier + flowClassifier = flowClassifierBuilder.setFlowClassifierId(flowClassifierId).setTenantId(tenantId) + .setName(name).setDescription(description).setEtherType(ethType).setProtocol(protocol) + .setMinSrcPortRange(minSrcPortRange).setMaxSrcPortRange(maxSrcPortRange) + .setMinDstPortRange(minDstPortRange).setMaxDstPortRange(maxDstPortRange).setSrcIpPrefix(srcIpPrefix) + .setDstIpPrefix(dstIpPrefix).setSrcPort(virtualSrcPort).setDstPort(virtualDstPort).build(); + sfcService.onFlowClassifierDeleted(flowClassifier); + } + + /** + * Checks the operation of onPortChainCreated() method. + */ + @Test + public void testOnPortChainCreated() { + final PortChainId portChainId = PortChainId.of("78888888-fc23-aeb6-f44b-56dc5e2fb3ae"); + final TenantId tenantId = TenantId.tenantId("1"); + final String name = "PortChain"; + final String description = "PortChain"; + final List<PortPairGroupId> portPairGroupList = new LinkedList<PortPairGroupId>(); + final List<FlowClassifierId> flowClassifierList = new LinkedList<FlowClassifierId>(); + DefaultPortChain.Builder portChainBuilder = new DefaultPortChain.Builder(); + DefaultFlowClassifier.Builder flowClassifierBuilder = new DefaultFlowClassifier.Builder(); + PortChain portChain = null; + SfcService sfcService = new SfcManager(); + + // create list of Port Pair Groups. + PortPairGroupId portPairGroupId = PortPairGroupId.of("73333333-fc23-aeb6-f44b-56dc5e2fb3ae"); + portPairGroupList.add(portPairGroupId); + portPairGroupId = PortPairGroupId.of("73333333-fc23-aeb6-f44b-56dc5e2fb3af"); + portPairGroupList.add(portPairGroupId); + + // create list of Flow classifiers. + FlowClassifierId flowClassifierId = FlowClassifierId.of("74444444-fc23-aeb6-f44b-56dc5e2fb3ae"); + flowClassifierList.add(flowClassifierId); + flowClassifierId = FlowClassifierId.of("74444444-fc23-aeb6-f44b-56dc5e2fb3af"); + flowClassifierList.add(flowClassifierId); + + // create port chain + portChain = portChainBuilder.setId(portChainId).setTenantId(tenantId).setName(name).setDescription(description) + .setPortPairGroups(portPairGroupList).setFlowClassifiers(flowClassifierList).build(); + sfcService.onPortChainCreated(portChain); + } + + /** + * Checks the operation of onPortChainDeleted() method. + */ + @Test + public void testOnPortChainDeleted() { + final PortChainId portChainId = PortChainId.of("78888888-fc23-aeb6-f44b-56dc5e2fb3ae"); + final TenantId tenantId = TenantId.tenantId("1"); + final String name = "PortChain"; + final String description = "PortChain"; + final List<PortPairGroupId> portPairGroupList = new LinkedList<PortPairGroupId>(); + final List<FlowClassifierId> flowClassifierList = new LinkedList<FlowClassifierId>(); + DefaultPortChain.Builder portChainBuilder = new DefaultPortChain.Builder(); + DefaultFlowClassifier.Builder flowClassifierBuilder = new DefaultFlowClassifier.Builder(); + PortChain portChain = null; + SfcService sfcService = new SfcManager(); + + // create list of Port Pair Groups. + PortPairGroupId portPairGroupId = PortPairGroupId.of("73333333-fc23-aeb6-f44b-56dc5e2fb3ae"); + portPairGroupList.add(portPairGroupId); + portPairGroupId = PortPairGroupId.of("73333333-fc23-aeb6-f44b-56dc5e2fb3af"); + portPairGroupList.add(portPairGroupId); + + // create list of Flow classifiers. + FlowClassifierId flowClassifierId = FlowClassifierId.of("74444444-fc23-aeb6-f44b-56dc5e2fb3ae"); + flowClassifierList.add(flowClassifierId); + flowClassifierId = FlowClassifierId.of("74444444-fc23-aeb6-f44b-56dc5e2fb3af"); + flowClassifierList.add(flowClassifierId); + + // create port chain + portChain = portChainBuilder.setId(portChainId).setTenantId(tenantId).setName(name).setDescription(description) + .setPortPairGroups(portPairGroupList).setFlowClassifiers(flowClassifierList).build(); + sfcService.onPortChainDeleted(portChain); + } +} diff --git a/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/FlowClassifierManagerTestImpl.java b/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/FlowClassifierManagerTestImpl.java new file mode 100644 index 00000000..fe5babbd --- /dev/null +++ b/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/FlowClassifierManagerTestImpl.java @@ -0,0 +1,93 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.sfc.util; + +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.ConcurrentHashMap; + +import org.onosproject.vtnrsc.FlowClassifierId; +import org.onosproject.vtnrsc.FlowClassifier; +import org.onosproject.vtnrsc.flowclassifier.FlowClassifierListener; +import org.onosproject.vtnrsc.flowclassifier.FlowClassifierService; + +import com.google.common.collect.ImmutableList; + +/** + * Provides implementation of the Flow Classifier Service. + */ +public class FlowClassifierManagerTestImpl implements FlowClassifierService { + + private final ConcurrentMap<FlowClassifierId, FlowClassifier> flowClassifierStore = new ConcurrentHashMap<>(); + + @Override + public boolean exists(FlowClassifierId id) { + return flowClassifierStore.containsKey(id); + } + + @Override + public int getFlowClassifierCount() { + return flowClassifierStore.size(); + } + + @Override + public Iterable<FlowClassifier> getFlowClassifiers() { + return ImmutableList.copyOf(flowClassifierStore.values()); + } + + @Override + public FlowClassifier getFlowClassifier(FlowClassifierId id) { + return flowClassifierStore.get(id); + } + + @Override + public boolean createFlowClassifier(FlowClassifier flowClassifier) { + FlowClassifierId id = flowClassifier.flowClassifierId(); + + flowClassifierStore.put(id, flowClassifier); + if (!flowClassifierStore.containsKey(id)) { + return false; + } + return true; + } + + @Override + public boolean updateFlowClassifier(FlowClassifier flowClassifier) { + + if (!flowClassifierStore.containsKey(flowClassifier.flowClassifierId())) { + return false; + } + + flowClassifierStore.put(flowClassifier.flowClassifierId(), flowClassifier); + + if (!flowClassifier.equals(flowClassifierStore.get(flowClassifier.flowClassifierId()))) { + return false; + } + return true; + } + + @Override + public boolean removeFlowClassifier(FlowClassifierId id) { + return true; + } + + @Override + public void addListener(FlowClassifierListener listener) { + } + + @Override + public void removeListener(FlowClassifierListener listener) { + } +} diff --git a/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/FlowObjectiveServiceTestImpl.java b/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/FlowObjectiveServiceTestImpl.java new file mode 100644 index 00000000..9da9ee94 --- /dev/null +++ b/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/FlowObjectiveServiceTestImpl.java @@ -0,0 +1,53 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.sfc.util; + +import org.onosproject.net.DeviceId; +import org.onosproject.net.flowobjective.FlowObjectiveService; +import org.onosproject.net.flowobjective.FilteringObjective; +import org.onosproject.net.flowobjective.ForwardingObjective; +import org.onosproject.net.flowobjective.NextObjective; + +/** + * Testing version of implementation on FlowObjectiveService. + */ +public class FlowObjectiveServiceTestImpl implements FlowObjectiveService { + + @Override + public void filter(DeviceId deviceId, FilteringObjective filteringObjective) { + + } + + @Override + public void forward(DeviceId deviceId, ForwardingObjective forwardingObjective) { + + } + + @Override + public void next(DeviceId deviceId, NextObjective nextObjective) { + + } + + @Override + public int allocateNextId() { + return 0; + } + + @Override + public void initPolicy(String policy) { + + } +} diff --git a/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/PortChainManagerTestImpl.java b/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/PortChainManagerTestImpl.java new file mode 100644 index 00000000..4a3ba03d --- /dev/null +++ b/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/PortChainManagerTestImpl.java @@ -0,0 +1,85 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.sfc.util; + +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.ConcurrentHashMap; +import java.util.Collections; + +import org.onosproject.vtnrsc.PortChain; +import org.onosproject.vtnrsc.PortChainId; +import org.onosproject.vtnrsc.portchain.PortChainService; +import org.onosproject.vtnrsc.portchain.PortChainEvent; +import org.onosproject.vtnrsc.portchain.PortChainListener; +import org.onosproject.event.AbstractListenerManager; + +/** + * Provides implementation of the portChainService. + */ +public class PortChainManagerTestImpl + extends AbstractListenerManager<PortChainEvent, PortChainListener> + implements PortChainService { + + private ConcurrentMap<PortChainId, PortChain> portChainStore = new ConcurrentHashMap<>(); + + @Override + public boolean exists(PortChainId portChainId) { + return portChainStore.containsKey(portChainId); + } + + @Override + public int getPortChainCount() { + return portChainStore.size(); + } + + @Override + public Iterable<PortChain> getPortChains() { + return Collections.unmodifiableCollection(portChainStore.values()); + } + + @Override + public PortChain getPortChain(PortChainId portChainId) { + return portChainStore.get(portChainId); + } + + @Override + public boolean createPortChain(PortChain portChain) { + portChainStore.put(portChain.portChainId(), portChain); + if (!portChainStore.containsKey(portChain.portChainId())) { + return false; + } + return true; + } + + @Override + public boolean updatePortChain(PortChain portChain) { + if (!portChainStore.containsKey(portChain.portChainId())) { + return false; + } + + portChainStore.put(portChain.portChainId(), portChain); + + if (!portChain.equals(portChainStore.get(portChain.portChainId()))) { + return false; + } + return true; + } + + @Override + public boolean removePortChain(PortChainId portChainId) { + return true; + } +} diff --git a/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/PortPairGroupManagerTestImpl.java b/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/PortPairGroupManagerTestImpl.java new file mode 100644 index 00000000..ba31cd60 --- /dev/null +++ b/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/PortPairGroupManagerTestImpl.java @@ -0,0 +1,89 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.sfc.util; + +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.ConcurrentHashMap; +import java.util.Collections; + +import org.onosproject.vtnrsc.PortPairGroup; +import org.onosproject.vtnrsc.PortPairGroupId; +import org.onosproject.vtnrsc.portpairgroup.PortPairGroupListener; +import org.onosproject.vtnrsc.portpairgroup.PortPairGroupService; + +/** + * Provides implementation of the portPairGroupService. + */ +public class PortPairGroupManagerTestImpl implements PortPairGroupService { + + private ConcurrentMap<PortPairGroupId, PortPairGroup> portPairGroupStore = new ConcurrentHashMap<>(); + + @Override + public boolean exists(PortPairGroupId portPairGroupId) { + return portPairGroupStore.containsKey(portPairGroupId); + } + + @Override + public int getPortPairGroupCount() { + return portPairGroupStore.size(); + } + + @Override + public Iterable<PortPairGroup> getPortPairGroups() { + return Collections.unmodifiableCollection(portPairGroupStore.values()); + } + + @Override + public PortPairGroup getPortPairGroup(PortPairGroupId portPairGroupId) { + return portPairGroupStore.get(portPairGroupId); + } + + @Override + public boolean createPortPairGroup(PortPairGroup portPairGroup) { + portPairGroupStore.put(portPairGroup.portPairGroupId(), portPairGroup); + if (!portPairGroupStore.containsKey(portPairGroup.portPairGroupId())) { + return false; + } + return true; + } + + @Override + public boolean updatePortPairGroup(PortPairGroup portPairGroup) { + if (!portPairGroupStore.containsKey(portPairGroup.portPairGroupId())) { + return false; + } + + portPairGroupStore.put(portPairGroup.portPairGroupId(), portPairGroup); + + if (!portPairGroup.equals(portPairGroupStore.get(portPairGroup.portPairGroupId()))) { + return false; + } + return true; + } + + @Override + public boolean removePortPairGroup(PortPairGroupId portPairGroupId) { + return true; + } + + @Override + public void addListener(PortPairGroupListener listener) { + } + + @Override + public void removeListener(PortPairGroupListener listener) { + } +} diff --git a/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/PortPairManagerTestImpl.java b/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/PortPairManagerTestImpl.java new file mode 100644 index 00000000..aff58823 --- /dev/null +++ b/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/PortPairManagerTestImpl.java @@ -0,0 +1,89 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.sfc.util; + +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.ConcurrentHashMap; +import java.util.Collections; + +import org.onosproject.vtnrsc.PortPair; +import org.onosproject.vtnrsc.PortPairId; +import org.onosproject.vtnrsc.portpair.PortPairListener; +import org.onosproject.vtnrsc.portpair.PortPairService; + +/** + * Provides implementation of the portPairService. + */ +public class PortPairManagerTestImpl implements PortPairService { + + private ConcurrentMap<PortPairId, PortPair> portPairStore = new ConcurrentHashMap<>(); + + @Override + public boolean exists(PortPairId portPairId) { + return portPairStore.containsKey(portPairId); + } + + @Override + public int getPortPairCount() { + return portPairStore.size(); + } + + @Override + public Iterable<PortPair> getPortPairs() { + return Collections.unmodifiableCollection(portPairStore.values()); + } + + @Override + public PortPair getPortPair(PortPairId portPairId) { + return portPairStore.get(portPairId); + } + + @Override + public boolean createPortPair(PortPair portPair) { + portPairStore.put(portPair.portPairId(), portPair); + if (!portPairStore.containsKey(portPair.portPairId())) { + return false; + } + return true; + } + + @Override + public boolean updatePortPair(PortPair portPair) { + if (!portPairStore.containsKey(portPair.portPairId())) { + return false; + } + + portPairStore.put(portPair.portPairId(), portPair); + + if (!portPair.equals(portPairStore.get(portPair.portPairId()))) { + return false; + } + return true; + } + + @Override + public boolean removePortPair(PortPairId portPairId) { + return true; + } + + @Override + public void addListener(PortPairListener listener) { + } + + @Override + public void removeListener(PortPairListener listener) { + } +} diff --git a/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/VirtualPortManagerTestImpl.java b/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/VirtualPortManagerTestImpl.java new file mode 100644 index 00000000..de056a78 --- /dev/null +++ b/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/VirtualPortManagerTestImpl.java @@ -0,0 +1,98 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.sfc.util; + +import java.util.Collection; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.ConcurrentHashMap; + +import org.onlab.packet.IpAddress; +import org.onosproject.net.DeviceId; +import org.onosproject.vtnrsc.FixedIp; +import org.onosproject.vtnrsc.TenantId; +import org.onosproject.vtnrsc.VirtualPort; +import org.onosproject.vtnrsc.VirtualPortId; +import org.onosproject.vtnrsc.TenantNetworkId; +import org.onosproject.vtnrsc.virtualport.VirtualPortService; + +/** + * Provides implementation of the VirtualPort APIs. + */ +public class VirtualPortManagerTestImpl implements VirtualPortService { + + protected ConcurrentMap<VirtualPortId, VirtualPort> vPortStore = new ConcurrentHashMap<>(); + + @Override + public boolean exists(VirtualPortId vPortId) { + return vPortStore.containsKey(vPortId); + } + + @Override + public VirtualPort getPort(VirtualPortId vPortId) { + return vPortStore.get(vPortId); + } + + @Override + public VirtualPort getPort(FixedIp fixedIP) { + return null; + } + + @Override + public Collection<VirtualPort> getPorts() { + return null; + } + + @Override + public Collection<VirtualPort> getPorts(TenantNetworkId networkId) { + return null; + } + + @Override + public Collection<VirtualPort> getPorts(TenantId tenantId) { + return null; + } + + @Override + public Collection<VirtualPort> getPorts(DeviceId deviceId) { + return null; + } + + @Override + public VirtualPort getPort(TenantNetworkId networkId, IpAddress ipAddress) { + return null; + } + + @Override + public boolean createPorts(Iterable<VirtualPort> vPorts) { + for (VirtualPort vPort : vPorts) { + vPortStore.put(vPort.portId(), vPort); + if (!vPortStore.containsKey(vPort.portId())) { + return false; + } + } + return true; + } + + @Override + public boolean updatePorts(Iterable<VirtualPort> vPorts) { + return true; + } + + @Override + public boolean removePorts(Iterable<VirtualPortId> vPortIds) { + return true; + } +} diff --git a/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/VtnRscManagerTestImpl.java b/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/VtnRscManagerTestImpl.java new file mode 100644 index 00000000..4188cee6 --- /dev/null +++ b/framework/src/onos/apps/vtn/sfcmgr/src/test/java/org/onosproject/sfc/util/VtnRscManagerTestImpl.java @@ -0,0 +1,72 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.sfc.util; + +import java.util.Iterator; + +import org.onlab.packet.MacAddress; +import org.onosproject.net.Device; +import org.onosproject.net.DeviceId; +import org.onosproject.net.HostId; +import org.onosproject.vtnrsc.SegmentationId; +import org.onosproject.vtnrsc.TenantId; +import org.onosproject.vtnrsc.VirtualPortId; +import org.onosproject.vtnrsc.event.VtnRscListener; +import org.onosproject.vtnrsc.service.VtnRscService; + +/** + * Provides implementation of the VtnRsc service. + */ +public class VtnRscManagerTestImpl implements VtnRscService { + @Override + public void addListener(VtnRscListener listener) { + } + + @Override + public void removeListener(VtnRscListener listener) { + } + + @Override + public SegmentationId getL3vni(TenantId tenantId) { + return null; + } + + @Override + public Iterator<Device> getClassifierOfTenant(TenantId tenantId) { + return null; + } + + @Override + public Iterator<Device> getSFFOfTenant(TenantId tenantId) { + return null; + } + + @Override + public MacAddress getGatewayMac(HostId hostId) { + return null; + } + + @Override + public boolean isServiceFunction(VirtualPortId portId) { + // TODO Auto-generated method stub + return false; + } + + @Override + public DeviceId getSFToSFFMaping(VirtualPortId portId) { + return DeviceId.deviceId("www.google.com"); + } +} diff --git a/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/manager/VTNService.java b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/manager/VTNService.java index a104e529..d7ee3607 100644 --- a/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/manager/VTNService.java +++ b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/manager/VTNService.java @@ -17,6 +17,7 @@ package org.onosproject.vtn.manager; import org.onosproject.net.Device; import org.onosproject.net.Host; +import org.onosproject.vtnrsc.event.VtnRscEventFeedback; /** * VTN application that applies configuration and flows to the device. @@ -67,4 +68,32 @@ public interface VTNService { */ void onHostVanished(Host host); + /** + * Applies east west flows when neutron created router interface. + * + * @param l3Feedback VtnrscEventFeedback + */ + void onRouterInterfaceDetected(VtnRscEventFeedback l3Feedback); + + /** + * Remove east west flows when neutron removed router interface. + * + * @param l3Feedback VtnrscEventFeedback + */ + void onRouterInterfaceVanished(VtnRscEventFeedback l3Feedback); + + /** + * Applies north south flows when neutron bind floating ip. + * + * @param l3Feedback VtnrscEventFeedback + */ + void onFloatingIpDetected(VtnRscEventFeedback l3Feedback); + + /** + * Applies north south flows when neutron unbind floating ip. + * + * @param l3Feedback VtnrscEventFeedback + */ + void onFloatingIpVanished(VtnRscEventFeedback l3Feedback); + } diff --git a/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/manager/impl/VTNManager.java b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/manager/impl/VTNManager.java index be6b9364..6429314e 100644 --- a/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/manager/impl/VTNManager.java +++ b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/manager/impl/VTNManager.java @@ -18,6 +18,7 @@ package org.onosproject.vtn.manager.impl; import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_TUNNEL_DST; import static org.slf4j.LoggerFactory.getLogger; +import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; @@ -25,6 +26,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.stream.Collectors; import org.apache.felix.scr.annotations.Activate; import org.apache.felix.scr.annotations.Component; @@ -39,9 +41,11 @@ import org.onlab.util.KryoNamespace; import org.onosproject.core.ApplicationId; import org.onosproject.core.CoreService; import org.onosproject.mastership.MastershipService; +import org.onosproject.net.AnnotationKeys; import org.onosproject.net.Device; import org.onosproject.net.DeviceId; import org.onosproject.net.Host; +import org.onosproject.net.HostId; import org.onosproject.net.Port; import org.onosproject.net.PortNumber; import org.onosproject.net.behaviour.BridgeConfig; @@ -74,8 +78,12 @@ import org.onosproject.store.service.EventuallyConsistentMap; import org.onosproject.store.service.LogicalClockService; import org.onosproject.store.service.StorageService; import org.onosproject.vtn.manager.VTNService; +import org.onosproject.vtn.table.ArpService; import org.onosproject.vtn.table.ClassifierService; +import org.onosproject.vtn.table.DnatService; import org.onosproject.vtn.table.L2ForwardService; +import org.onosproject.vtn.table.L3ForwardService; +import org.onosproject.vtn.table.SnatService; import org.onosproject.vtn.table.impl.ClassifierServiceImpl; import org.onosproject.vtn.table.impl.L2ForwardServiceImpl; import org.onosproject.vtn.util.DataPathIdGenerator; @@ -85,6 +93,11 @@ import org.onosproject.vtnrsc.AllowedAddressPair; import org.onosproject.vtnrsc.BindingHostId; import org.onosproject.vtnrsc.DefaultVirtualPort; import org.onosproject.vtnrsc.FixedIp; +import org.onosproject.vtnrsc.FloatingIp; +import org.onosproject.vtnrsc.Router; +import org.onosproject.vtnrsc.RouterGateway; +import org.onosproject.vtnrsc.RouterId; +import org.onosproject.vtnrsc.RouterInterface; import org.onosproject.vtnrsc.SecurityGroup; import org.onosproject.vtnrsc.SegmentationId; import org.onosproject.vtnrsc.SubnetId; @@ -93,6 +106,14 @@ import org.onosproject.vtnrsc.TenantNetwork; import org.onosproject.vtnrsc.TenantNetworkId; import org.onosproject.vtnrsc.VirtualPort; import org.onosproject.vtnrsc.VirtualPortId; +import org.onosproject.vtnrsc.event.VtnRscEvent; +import org.onosproject.vtnrsc.event.VtnRscEventFeedback; +import org.onosproject.vtnrsc.event.VtnRscListener; +import org.onosproject.vtnrsc.floatingip.FloatingIpService; +import org.onosproject.vtnrsc.router.RouterService; +import org.onosproject.vtnrsc.routerinterface.RouterInterfaceService; +import org.onosproject.vtnrsc.service.VtnRscService; +import org.onosproject.vtnrsc.subnet.SubnetService; import org.onosproject.vtnrsc.tenantnetwork.TenantNetworkService; import org.onosproject.vtnrsc.virtualport.VirtualPortService; import org.slf4j.Logger; @@ -142,12 +163,32 @@ public class VTNManager implements VTNService { @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) protected GroupService groupService; + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected SubnetService subnetService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected VtnRscService vtnRscService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected FloatingIpService floatingIpService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected RouterService routerService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected RouterInterfaceService routerInterfaceService; + private ApplicationId appId; private ClassifierService classifierService; private L2ForwardService l2ForwardService; + private ArpService arpService; + private L3ForwardService l3ForwardService; + private SnatService snatService; + private DnatService dnatService; private final HostListener hostListener = new InnerHostListener(); private final DeviceListener deviceListener = new InnerDeviceListener(); + private final VtnRscListener l3EventListener = new VtnL3EventListener(); private static final String IFACEID = "ifaceid"; private static final String CONTROLLER_IP_KEY = "ipaddress"; @@ -156,11 +197,19 @@ public class VTNManager implements VTNService { private static final String VIRTUALPORT = "vtn-virtual-port"; private static final String SWITCHES_OF_CONTROLLER = "switchesOfController"; private static final String SWITCH_OF_LOCAL_HOST_PORTS = "switchOfLocalHostPorts"; + private static final String ROUTERINF_FLAG_OF_TENANT = "routerInfFlagOfTenant"; + private static final String HOSTS_OF_SUBNET = "hostsOfSubnet"; + private static final String EX_PORT_OF_DEVICE = "exPortOfDevice"; private static final String DEFAULT_IP = "0.0.0.0"; + private static final String PORT_MAC = "portMac"; + private static final int SUBNET_NUM = 2; private EventuallyConsistentMap<VirtualPortId, VirtualPort> vPortStore; private EventuallyConsistentMap<IpAddress, Boolean> switchesOfController; private EventuallyConsistentMap<DeviceId, NetworkOfLocalHostPorts> switchOfLocalHostPorts; + private EventuallyConsistentMap<SubnetId, Map<HostId, Host>> hostsOfSubnet; + private EventuallyConsistentMap<TenantId, Boolean> routerInfFlagOfTenant; + private EventuallyConsistentMap<DeviceId, Port> exPortOfDevice; @Activate public void activate() { @@ -206,6 +255,24 @@ public class VTNManager implements VTNService { .withTimestampProvider((k, v) -> clockService.getTimestamp()) .build(); + hostsOfSubnet = storageService + .<SubnetId, Map<HostId, Host>>eventuallyConsistentMapBuilder() + .withName(HOSTS_OF_SUBNET).withSerializer(serializer) + .withTimestampProvider((k, v) -> clockService.getTimestamp()) + .build(); + + routerInfFlagOfTenant = storageService + .<TenantId, Boolean>eventuallyConsistentMapBuilder() + .withName(ROUTERINF_FLAG_OF_TENANT).withSerializer(serializer) + .withTimestampProvider((k, v) -> clockService.getTimestamp()) + .build(); + + exPortOfDevice = storageService + .<DeviceId, Port>eventuallyConsistentMapBuilder() + .withName(EX_PORT_OF_DEVICE).withSerializer(serializer) + .withTimestampProvider((k, v) -> clockService.getTimestamp()) + .build(); + log.info("Started"); } @@ -213,6 +280,7 @@ public class VTNManager implements VTNService { public void deactivate() { deviceService.removeListener(deviceListener); hostService.removeListener(hostListener); + vtnRscService.removeListener(l3EventListener); log.info("Stopped"); } @@ -278,14 +346,36 @@ public class VTNManager implements VTNService { @Override public void onHostDetected(Host host) { + DeviceId deviceId = host.location().deviceId(); + if (!mastershipService.isLocalMaster(deviceId)) { + return; + } + String ifaceId = host.annotations().value(IFACEID); + if (ifaceId == null) { + log.error("The ifaceId of Host is null"); + return; + } // apply L2 openflow rules applyHostMonitoredL2Rules(host, Objective.Operation.ADD); + // apply L3 openflow rules + applyHostMonitoredL3Rules(host, Objective.Operation.ADD); } @Override public void onHostVanished(Host host) { + DeviceId deviceId = host.location().deviceId(); + if (!mastershipService.isLocalMaster(deviceId)) { + return; + } + String ifaceId = host.annotations().value(IFACEID); + if (ifaceId == null) { + log.error("The ifaceId of Host is null"); + return; + } // apply L2 openflow rules applyHostMonitoredL2Rules(host, Objective.Operation.REMOVE); + // apply L3 openflow rules + applyHostMonitoredL3Rules(host, Objective.Operation.REMOVE); } private void programTunnelConfig(DeviceId localDeviceId, IpAddress localIp, @@ -376,7 +466,7 @@ public class VTNManager implements VTNService { VirtualPortId virtualPortId = VirtualPortId.portId(ifaceId); VirtualPort virtualPort = virtualPortService.getPort(virtualPortId); if (virtualPort == null) { - virtualPort = vPortStore.get(virtualPortId); + virtualPort = VtnData.getPort(vPortStore, virtualPortId); } Iterable<Device> devices = deviceService.getAvailableDevices(); @@ -582,4 +672,388 @@ public class VTNManager implements VTNService { appid); groupService.addGroup(groupDescription); } + + private class VtnL3EventListener implements VtnRscListener { + @Override + public void event(VtnRscEvent event) { + VtnRscEventFeedback l3Feedback = event.subject(); + if (VtnRscEvent.Type.ROUTER_INTERFACE_PUT == event.type()) { + onRouterInterfaceDetected(l3Feedback); + } else + if (VtnRscEvent.Type.ROUTER_INTERFACE_DELETE == event.type()) { + onRouterInterfaceVanished(l3Feedback); + } else if (VtnRscEvent.Type.FLOATINGIP_PUT == event.type()) { + onFloatingIpDetected(l3Feedback); + } else if (VtnRscEvent.Type.FLOATINGIP_DELETE == event.type()) { + onFloatingIpVanished(l3Feedback); + } + } + + } + + @Override + public void onRouterInterfaceDetected(VtnRscEventFeedback l3Feedback) { + Objective.Operation operation = Objective.Operation.ADD; + RouterInterface routerInf = l3Feedback.routerInterface(); + Iterable<RouterInterface> interfaces = routerInterfaceService + .getRouterInterfaces(); + Set<RouterInterface> interfacesSet = Sets.newHashSet(interfaces) + .stream().filter(r -> r.tenantId().equals(routerInf.tenantId())) + .collect(Collectors.toSet()); + if (routerInfFlagOfTenant.get(routerInf.tenantId()) != null) { + programRouterInterface(routerInf, operation); + } else { + if (interfacesSet.size() >= SUBNET_NUM) { + programInterfacesSet(interfacesSet, operation); + } + } + } + + @Override + public void onRouterInterfaceVanished(VtnRscEventFeedback l3Feedback) { + Objective.Operation operation = Objective.Operation.REMOVE; + RouterInterface routerInf = l3Feedback.routerInterface(); + Iterable<RouterInterface> interfaces = routerInterfaceService + .getRouterInterfaces(); + Set<RouterInterface> interfacesSet = Sets.newHashSet(interfaces) + .stream().filter(r -> r.tenantId().equals(routerInf.tenantId())) + .collect(Collectors.toSet()); + if (routerInfFlagOfTenant.get(routerInf.tenantId()) != null) { + programRouterInterface(routerInf, operation); + if (interfacesSet.size() == 1) { + routerInfFlagOfTenant.remove(routerInf.tenantId()); + interfacesSet.stream().forEach(r -> { + programRouterInterface(r, operation); + }); + } + } + } + + @Override + public void onFloatingIpDetected(VtnRscEventFeedback l3Feedback) { + programFloatingIpEvent(l3Feedback, VtnRscEvent.Type.FLOATINGIP_PUT); + } + + @Override + public void onFloatingIpVanished(VtnRscEventFeedback l3Feedback) { + programFloatingIpEvent(l3Feedback, VtnRscEvent.Type.FLOATINGIP_DELETE); + } + + private void programInterfacesSet(Set<RouterInterface> interfacesSet, + Objective.Operation operation) { + int subnetVmNum = 0; + for (RouterInterface r : interfacesSet) { + // Get all the host of the subnet + Map<HostId, Host> hosts = hostsOfSubnet.get(r.subnetId()); + if (hosts.size() > 0) { + subnetVmNum++; + if (subnetVmNum >= SUBNET_NUM) { + routerInfFlagOfTenant.put(r.tenantId(), true); + interfacesSet.stream().forEach(f -> { + programRouterInterface(f, operation); + }); + break; + } + } + } + } + + private void programRouterInterface(RouterInterface routerInf, + Objective.Operation operation) { + SegmentationId l3vni = vtnRscService.getL3vni(routerInf.tenantId()); + // Get all the host of the subnet + Map<HostId, Host> hosts = hostsOfSubnet.get(routerInf.subnetId()); + hosts.values().stream().forEach(h -> { + applyEastWestL3Flows(h, l3vni, operation); + }); + } + + private void applyEastWestL3Flows(Host h, SegmentationId l3vni, + Objective.Operation operation) { + if (!mastershipService.isLocalMaster(h.location().deviceId())) { + log.debug("not master device:{}", h.location().deviceId()); + return; + } + String ifaceId = h.annotations().value(IFACEID); + VirtualPort hPort = virtualPortService + .getPort(VirtualPortId.portId(ifaceId)); + if (hPort == null) { + hPort = VtnData.getPort(vPortStore, VirtualPortId.portId(ifaceId)); + } + IpAddress srcIp = null; + IpAddress srcGwIp = null; + MacAddress srcVmGwMac = null; + SubnetId srcSubnetId = null; + Iterator<FixedIp> srcIps = hPort.fixedIps().iterator(); + if (srcIps.hasNext()) { + FixedIp fixedIp = srcIps.next(); + srcIp = fixedIp.ip(); + srcSubnetId = fixedIp.subnetId(); + srcGwIp = subnetService.getSubnet(srcSubnetId).gatewayIp(); + FixedIp fixedGwIp = FixedIp.fixedIp(srcSubnetId, srcGwIp); + VirtualPort gwPort = virtualPortService.getPort(fixedGwIp); + if (gwPort == null) { + gwPort = VtnData.getPort(vPortStore, fixedGwIp); + } + srcVmGwMac = gwPort.macAddress(); + } + TenantNetwork network = tenantNetworkService + .getNetwork(hPort.networkId()); + // Classifier rules + classifierService + .programL3InPortClassifierRules(h.location().deviceId(), + h.location().port(), h.mac(), + srcVmGwMac, l3vni, operation); + // Arp rules + if (operation == Objective.Operation.ADD) { + classifierService.programArpClassifierRules(h.location().deviceId(), + srcGwIp, + network.segmentationId(), + operation); + DriverHandler handler = driverService.createHandler(h.location().deviceId()); + arpService.programArpRules(handler, h.location().deviceId(), srcGwIp, + network.segmentationId(), srcVmGwMac, + operation); + } + Iterable<Device> devices = deviceService.getAvailableDevices(); + IpAddress srcArpIp = srcIp; + MacAddress srcArpGwMac = srcVmGwMac; + Sets.newHashSet(devices).stream() + .filter(d -> Device.Type.SWITCH == d.type()).forEach(d -> { + // L3FWD rules + l3ForwardService.programRouteRules(d.id(), l3vni, srcArpIp, + network.segmentationId(), + srcArpGwMac, h.mac(), + operation); + }); + } + + private void programFloatingIpEvent(VtnRscEventFeedback l3Feedback, + VtnRscEvent.Type type) { + FloatingIp floaingIp = l3Feedback.floatingIp(); + if (floaingIp != null) { + VirtualPortId vmPortId = floaingIp.portId(); + VirtualPort vmPort = virtualPortService.getPort(vmPortId); + VirtualPort fipPort = virtualPortService + .getPort(floaingIp.networkId(), floaingIp.floatingIp()); + if (vmPort == null) { + vmPort = VtnData.getPort(vPortStore, vmPortId); + } + if (fipPort == null) { + fipPort = VtnData.getPort(vPortStore, floaingIp.networkId(), + floaingIp.floatingIp()); + } + Set<Host> hostSet = hostService.getHostsByMac(vmPort.macAddress()); + Host host = null; + for (Host h : hostSet) { + String ifaceid = h.annotations().value(IFACEID); + if (ifaceid != null && ifaceid.equals(vmPortId.portId())) { + host = h; + break; + } + } + if (host != null && vmPort != null && fipPort != null) { + DeviceId deviceId = host.location().deviceId(); + Port exPort = exPortOfDevice.get(deviceId); + SegmentationId l3vni = vtnRscService + .getL3vni(vmPort.tenantId()); + // Floating ip BIND + if (type == VtnRscEvent.Type.FLOATINGIP_PUT) { + applyNorthSouthL3Flows(deviceId, host, vmPort, fipPort, + floaingIp, l3vni, exPort, + Objective.Operation.ADD); + } else if (type == VtnRscEvent.Type.FLOATINGIP_DELETE) { + // Floating ip UNBIND + applyNorthSouthL3Flows(deviceId, host, vmPort, fipPort, + floaingIp, l3vni, exPort, + Objective.Operation.REMOVE); + } + } + } + } + + private void applyNorthSouthL3Flows(DeviceId deviceId, Host host, + VirtualPort vmPort, VirtualPort fipPort, + FloatingIp floatingIp, + SegmentationId l3Vni, Port exPort, + Objective.Operation operation) { + if (!mastershipService.isLocalMaster(deviceId)) { + log.debug("not master device:{}", deviceId); + return; + } + List gwIpMac = getGwIpAndMac(vmPort); + IpAddress dstVmGwIp = (IpAddress) gwIpMac.get(0); + MacAddress dstVmGwMac = (MacAddress) gwIpMac.get(1); + FixedIp fixedGwIp = getGwFixedIp(floatingIp); + MacAddress fGwMac = null; + if (fixedGwIp != null) { + VirtualPort gwPort = virtualPortService.getPort(fixedGwIp); + if (gwPort == null) { + gwPort = VtnData.getPort(vPortStore, fixedGwIp); + } + fGwMac = gwPort.macAddress(); + } + TenantNetwork vmNetwork = tenantNetworkService + .getNetwork(vmPort.networkId()); + TenantNetwork fipNetwork = tenantNetworkService + .getNetwork(fipPort.networkId()); + // L3 downlink traffic flow + MacAddress exPortMac = MacAddress.valueOf(exPort.annotations().value(PORT_MAC)); + classifierService.programArpClassifierRules(deviceId, floatingIp.floatingIp(), + fipNetwork.segmentationId(), + operation); + classifierService.programL3ExPortClassifierRules(deviceId, exPort.number(), + floatingIp.floatingIp(), operation); + DriverHandler handler = driverService.createHandler(deviceId); + arpService.programArpRules(handler, deviceId, floatingIp.floatingIp(), + fipNetwork.segmentationId(), exPortMac, + operation); + dnatService.programRules(deviceId, floatingIp.floatingIp(), + fGwMac, floatingIp.fixedIp(), + l3Vni, operation); + l3ForwardService + .programRouteRules(deviceId, l3Vni, floatingIp.fixedIp(), + vmNetwork.segmentationId(), dstVmGwMac, + vmPort.macAddress(), operation); + + // L3 uplink traffic flow + classifierService.programL3InPortClassifierRules(deviceId, + host.location().port(), + host.mac(), dstVmGwMac, + l3Vni, operation); + snatService.programRules(deviceId, l3Vni, floatingIp.fixedIp(), + fGwMac, exPortMac, + floatingIp.floatingIp(), + fipNetwork.segmentationId(), operation); + if (operation == Objective.Operation.ADD) { + classifierService.programArpClassifierRules(deviceId, dstVmGwIp, + vmNetwork.segmentationId(), + operation); + arpService.programArpRules(handler, deviceId, dstVmGwIp, + vmNetwork.segmentationId(), dstVmGwMac, + operation); + l2ForwardService.programLocalOut(deviceId, + fipNetwork.segmentationId(), + exPort.number(), fGwMac, operation); + } + } + + private Port getExPort(DeviceId deviceId) { + List<Port> ports = deviceService.getPorts(deviceId); + Port exPort = null; + for (Port port : ports) { + String portName = port.annotations().value(AnnotationKeys.PORT_NAME); + if (portName != null && portName.equals(EX_PORT_NAME)) { + exPort = port; + break; + } + } + return exPort; + } + + private List getGwIpAndMac(VirtualPort port) { + List list = new ArrayList(); + MacAddress gwMac = null; + SubnetId subnetId = null; + IpAddress gwIp = null; + Iterator<FixedIp> fixips = port.fixedIps().iterator(); + if (fixips.hasNext()) { + FixedIp fixip = fixips.next(); + subnetId = fixip.subnetId(); + gwIp = subnetService.getSubnet(subnetId).gatewayIp(); + FixedIp fixedGwIp = FixedIp.fixedIp(fixip.subnetId(), gwIp); + VirtualPort gwPort = virtualPortService.getPort(fixedGwIp); + if (gwPort == null) { + gwPort = VtnData.getPort(vPortStore, fixedGwIp); + } + gwMac = gwPort.macAddress(); + } + list.add(gwIp); + list.add(gwMac); + return list; + } + + private FixedIp getGwFixedIp(FloatingIp floatingIp) { + RouterId routerId = floatingIp.routerId(); + Router router = routerService.getRouter(routerId); + RouterGateway routerGateway = router.externalGatewayInfo(); + Iterable<FixedIp> externalFixedIps = routerGateway.externalFixedIps(); + FixedIp fixedGwIp = null; + if (externalFixedIps != null) { + Iterator<FixedIp> exFixedIps = externalFixedIps.iterator(); + if (exFixedIps.hasNext()) { + fixedGwIp = exFixedIps.next(); + } + } + return fixedGwIp; + } + + private void applyHostMonitoredL3Rules(Host host, + Objective.Operation operation) { + String ifaceId = host.annotations().value(IFACEID); + DeviceId deviceId = host.location().deviceId(); + VirtualPortId portId = VirtualPortId.portId(ifaceId); + VirtualPort port = virtualPortService.getPort(portId); + if (port == null) { + port = VtnData.getPort(vPortStore, portId); + } + TenantId tenantId = port.tenantId(); + Port exPort = exPortOfDevice.get(deviceId); + SegmentationId l3vni = vtnRscService.getL3vni(tenantId); + Iterator<FixedIp> fixips = port.fixedIps().iterator(); + SubnetId sid = null; + IpAddress hostIp = null; + if (fixips.hasNext()) { + FixedIp fixip = fixips.next(); + sid = fixip.subnetId(); + hostIp = fixip.ip(); + } + final SubnetId subnetId = sid; + // L3 internal network access to each other + Iterable<RouterInterface> interfaces = routerInterfaceService + .getRouterInterfaces(); + Set<RouterInterface> interfacesSet = Sets.newHashSet(interfaces) + .stream().filter(r -> r.tenantId().equals(tenantId)) + .collect(Collectors.toSet()); + long count = interfacesSet.stream() + .filter(r -> !r.subnetId().equals(subnetId)).count(); + if (count > 0) { + if (operation == Objective.Operation.ADD) { + if (routerInfFlagOfTenant.get(tenantId) != null) { + applyEastWestL3Flows(host, l3vni, operation); + } else { + if (interfacesSet.size() > 1) { + programInterfacesSet(interfacesSet, operation); + } + } + } else if (operation == Objective.Operation.REMOVE) { + if (routerInfFlagOfTenant.get(tenantId) != null) { + applyEastWestL3Flows(host, l3vni, operation); + } + } + } + // L3 external and internal network access to each other + FloatingIp floatingIp = null; + Iterable<FloatingIp> floatingIps = floatingIpService.getFloatingIps(); + Set<FloatingIp> floatingIpSet = Sets.newHashSet(floatingIps).stream() + .filter(f -> f.tenantId().equals(tenantId)) + .collect(Collectors.toSet()); + for (FloatingIp f : floatingIpSet) { + IpAddress fixedIp = f.fixedIp(); + if (fixedIp.equals(hostIp)) { + floatingIp = f; + break; + } + } + if (floatingIp != null) { + VirtualPort fipPort = virtualPortService + .getPort(floatingIp.networkId(), floatingIp.floatingIp()); + if (fipPort == null) { + fipPort = VtnData.getPort(vPortStore, floatingIp.networkId(), + floatingIp.floatingIp()); + } + applyNorthSouthL3Flows(deviceId, host, port, fipPort, floatingIp, + l3vni, exPort, operation); + } + } } diff --git a/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/ArpService.java b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/ArpService.java index b548938b..ebb9ac3b 100644 --- a/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/ArpService.java +++ b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/ArpService.java @@ -17,10 +17,13 @@ package org.onosproject.vtn.table; import org.onlab.packet.IpAddress; import org.onlab.packet.MacAddress; + import org.onosproject.net.DeviceId; +import org.onosproject.net.driver.DriverHandler; import org.onosproject.net.flowobjective.Objective; import org.onosproject.vtnrsc.SegmentationId; + /** * ArpService interface providing the rules in ARP table which is Table(10). */ @@ -32,13 +35,14 @@ public interface ArpService { * Action: set arp_operation, move arp_eth_src to arp_eth_dst, set arp_eth_src, * move arp_ip_src to arp_ip_dst, set arp_ip_src, set output port. * + * @param hander DriverHandler * @param deviceId Device Id * @param dstIP destination ip * @param matchVni the vni of the source network (l2vni) * @param dstMac destination mac * @param type the operation type of the flow rules */ - void programArpRules(DeviceId deviceId, IpAddress dstIP, + void programArpRules(DriverHandler hander, DeviceId deviceId, IpAddress dstIP, SegmentationId matchVni, MacAddress dstMac, Objective.Operation type); } diff --git a/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/impl/ArpServiceImpl.java b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/impl/ArpServiceImpl.java new file mode 100644 index 00000000..574d15a7 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/impl/ArpServiceImpl.java @@ -0,0 +1,113 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtn.table.impl; + +import static com.google.common.base.Preconditions.checkNotNull; +import static org.slf4j.LoggerFactory.getLogger; + +import org.onlab.osgi.DefaultServiceDirectory; +import org.onlab.osgi.ServiceDirectory; +import org.onlab.packet.EthType.EtherType; +import org.onlab.packet.Ip4Address; +import org.onlab.packet.IpAddress; +import org.onlab.packet.MacAddress; +import org.onosproject.core.ApplicationId; +import org.onosproject.net.DeviceId; +import org.onosproject.net.PortNumber; +import org.onosproject.net.behaviour.ExtensionTreatmentResolver; +import org.onosproject.net.driver.DriverHandler; +import org.onosproject.net.flow.DefaultTrafficSelector; +import org.onosproject.net.flow.DefaultTrafficTreatment; +import org.onosproject.net.flow.TrafficSelector; +import org.onosproject.net.flow.TrafficTreatment; +import org.onosproject.net.flow.instructions.ExtensionTreatment; +import org.onosproject.net.flow.instructions.ExtensionTreatmentType; +import org.onosproject.net.flowobjective.DefaultForwardingObjective; +import org.onosproject.net.flowobjective.FlowObjectiveService; +import org.onosproject.net.flowobjective.ForwardingObjective; +import org.onosproject.net.flowobjective.ForwardingObjective.Flag; +import org.onosproject.net.flowobjective.Objective; +import org.onosproject.net.flowobjective.Objective.Operation; +import org.onosproject.vtn.table.ArpService; +import org.onosproject.vtnrsc.SegmentationId; +import org.slf4j.Logger; + +/** + * ArpTable class providing the rules in ARP table. + */ +public class ArpServiceImpl implements ArpService { + private final Logger log = getLogger(getClass()); + + private static final int ARP_PRIORITY = 0xffff; + private static final short ARP_RESPONSE = 0x2; + private static final EtherType ARP_TYPE = EtherType.ARP; + + private final FlowObjectiveService flowObjectiveService; + private final ApplicationId appId; + + /** + * Construct a ArpServiceImpl object. + * + * @param appId the application id of vtn + */ + public ArpServiceImpl(ApplicationId appId) { + this.appId = checkNotNull(appId, "ApplicationId can not be null"); + ServiceDirectory serviceDirectory = new DefaultServiceDirectory(); + this.flowObjectiveService = serviceDirectory.get(FlowObjectiveService.class); + } + + @Override + public void programArpRules(DriverHandler hander, DeviceId deviceId, + IpAddress dstIP, SegmentationId srcVni, + MacAddress dstMac, Operation type) { + TrafficSelector selector = DefaultTrafficSelector.builder() + .matchEthType(ARP_TYPE.ethType().toShort()) + .matchArpTpa(Ip4Address.valueOf(dstIP.toString())) + .matchTunnelId(Long.parseLong(srcVni.segmentationId())).build(); + + ExtensionTreatmentResolver resolver = hander + .behaviour(ExtensionTreatmentResolver.class); + ExtensionTreatment ethSrcToDst = resolver + .getExtensionInstruction(ExtensionTreatmentType.ExtensionTreatmentTypes + .NICIRA_MOV_ETH_SRC_TO_DST.type()); + ExtensionTreatment arpShaToTha = resolver + .getExtensionInstruction(ExtensionTreatmentType.ExtensionTreatmentTypes + .NICIRA_MOV_ARP_SHA_TO_THA.type()); + ExtensionTreatment arpSpaToTpa = resolver + .getExtensionInstruction(ExtensionTreatmentType.ExtensionTreatmentTypes + .NICIRA_MOV_ARP_SPA_TO_TPA.type()); + TrafficTreatment treatment = DefaultTrafficTreatment.builder() + .extension(ethSrcToDst, deviceId) + .setEthSrc(dstMac).setArpOp(ARP_RESPONSE) + .extension(arpShaToTha, deviceId) + .extension(arpSpaToTpa, deviceId) + .setArpSha(dstMac).setArpSpa(dstIP) + .setOutput(PortNumber.IN_PORT).build(); + + ForwardingObjective.Builder objective = DefaultForwardingObjective + .builder().withTreatment(treatment).withSelector(selector) + .fromApp(appId).withFlag(Flag.SPECIFIC) + .withPriority(ARP_PRIORITY); + + if (type.equals(Objective.Operation.ADD)) { + log.debug("PrivateArpRules-->ADD"); + flowObjectiveService.forward(deviceId, objective.add()); + } else { + log.debug("PrivateArpRules-->REMOVE"); + flowObjectiveService.forward(deviceId, objective.remove()); + } + } +} diff --git a/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/util/VtnData.java b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/util/VtnData.java index a8562e7f..cca905c2 100644 --- a/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/util/VtnData.java +++ b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/util/VtnData.java @@ -17,12 +17,20 @@ package org.onosproject.vtn.util; import java.util.ArrayList; import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import org.onlab.packet.IpAddress; import org.onosproject.net.AnnotationKeys; import org.onosproject.net.Device; import org.onosproject.net.DeviceId; import org.onosproject.net.Port; import org.onosproject.net.PortNumber; +import org.onosproject.store.service.EventuallyConsistentMap; +import org.onosproject.vtnrsc.FixedIp; +import org.onosproject.vtnrsc.TenantNetworkId; +import org.onosproject.vtnrsc.VirtualPort; +import org.onosproject.vtnrsc.VirtualPortId; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -94,4 +102,78 @@ public final class VtnData { return localTunnelPorts; } + /** + * Get VirtualPort. + * + * @param vPortStore EventuallyConsistentMap of VirtualPort + * @param vPortId VirtualPortId of the VirtualPort + * @return VirtualPort + */ + public static VirtualPort getPort(EventuallyConsistentMap<VirtualPortId, VirtualPort> vPortStore, + VirtualPortId vPortId) { + if (vPortStore != null) { + return vPortStore.get(vPortId); + } + return null; + } + + /** + * Get VirtualPort. + * + * @param vPortStore EventuallyConsistentMap of VirtualPort + * @param fixedIP FixedIp of the VirtualPort + * @return VirtualPort + */ + public static VirtualPort getPort(EventuallyConsistentMap<VirtualPortId, VirtualPort> vPortStore, + FixedIp fixedIP) { + if (vPortStore != null) { + List<VirtualPort> vPorts = new ArrayList<>(); + vPortStore.values().stream().forEach(p -> { + Iterator<FixedIp> fixedIps = p.fixedIps().iterator(); + while (fixedIps.hasNext()) { + if (fixedIps.next().equals(fixedIP)) { + vPorts.add(p); + break; + } + } + }); + if (vPorts.size() == 0) { + return null; + } + return vPorts.get(0); + } + return null; + } + + /** + * Get VirtualPort. + * + * @param vPortStore EventuallyConsistentMap of VirtualPort + * @param networkId TenantNetworkId of the VirtualPort + * @param ip IpAddress of the VirtualPort + * @return VirtualPort + */ + public static VirtualPort getPort(EventuallyConsistentMap<VirtualPortId, VirtualPort> vPortStore, + TenantNetworkId networkId, IpAddress ip) { + if (vPortStore != null) { + List<VirtualPort> vPorts = new ArrayList<>(); + vPortStore.values().stream() + .filter(p -> p.networkId().equals(networkId)) + .forEach(p -> { + Iterator<FixedIp> fixedIps = p.fixedIps().iterator(); + while (fixedIps.hasNext()) { + if (fixedIps.next().ip().equals(ip)) { + vPorts.add(p); + break; + } + } + }); + if (vPorts.size() == 0) { + return null; + } + return vPorts.get(0); + } + return null; + } + } diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/classifier/ClassifierService.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/classifier/ClassifierService.java new file mode 100644 index 00000000..a15da3ef --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/classifier/ClassifierService.java @@ -0,0 +1,41 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc.classifier; + +import org.onosproject.net.DeviceId; + +/** + * Provides Services for Classifier. + */ +public interface ClassifierService { + + /** + * Get Classifier devices for sfc. + * + * @return list of device id's for classifiers + */ + Iterable<DeviceId> getClassifiers(); + + /** + * Add Classifier device for sfc. + */ + void addClassifier(DeviceId deviceId); + + /** + * Remove Classifier device for sfc. + */ + void removeClassifier(DeviceId deviceId); +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/classifier/impl/ClassifierManager.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/classifier/impl/ClassifierManager.java new file mode 100644 index 00000000..a12d6221 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/classifier/impl/ClassifierManager.java @@ -0,0 +1,78 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc.classifier.impl; + +import static org.slf4j.LoggerFactory.getLogger; + +import org.apache.felix.scr.annotations.Activate; +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Deactivate; +import org.apache.felix.scr.annotations.Reference; +import org.apache.felix.scr.annotations.ReferenceCardinality; +import org.apache.felix.scr.annotations.Service; +import org.onosproject.net.DeviceId; +import org.onosproject.store.serializers.KryoNamespaces; +import org.onosproject.store.service.DistributedSet; +import org.onosproject.store.service.Serializer; +import org.onosproject.store.service.StorageService; +import org.onosproject.vtnrsc.classifier.ClassifierService; +import org.slf4j.Logger; + +import com.google.common.collect.ImmutableList; + +/** + * Provides implementation of the Classifier Service. + */ +@Component(immediate = true) +@Service +public class ClassifierManager implements ClassifierService { + + private final Logger log = getLogger(ClassifierManager.class); + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected StorageService storageService; + + private DistributedSet<DeviceId> classifierList; + + @Activate + protected void activate() { + classifierList = storageService.<DeviceId>setBuilder() + .withName("classifier") + .withSerializer(Serializer.using(KryoNamespaces.API)) + .build(); + log.info("Started"); + } + + @Deactivate + protected void deactivate() { + log.info("Stopped"); + } + + @Override + public void addClassifier(DeviceId deviceId) { + classifierList.add(deviceId); + } + + @Override + public Iterable<DeviceId> getClassifiers() { + return ImmutableList.copyOf(classifierList); + } + + @Override + public void removeClassifier(DeviceId deviceId) { + classifierList.remove(deviceId); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/classifier/impl/package-info.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/classifier/impl/package-info.java new file mode 100644 index 00000000..dc72e806 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/classifier/impl/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Provides implementation of the Classifier service. + */ +package org.onosproject.vtnrsc.classifier.impl; diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/classifier/package-info.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/classifier/package-info.java new file mode 100644 index 00000000..56976d96 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/classifier/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Service for interacting with Classifier of SFC. + */ +package org.onosproject.vtnrsc.classifier; diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/subnet/SubnetCreateCommand.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/subnet/SubnetCreateCommand.java index 56236408..de8cfe53 100644 --- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/subnet/SubnetCreateCommand.java +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/subnet/SubnetCreateCommand.java @@ -98,7 +98,7 @@ public class SubnetCreateCommand extends AbstractShellCommand { protected void execute() { SubnetService service = get(SubnetService.class); if (id == null || networkId == null || tenantId == null) { - print(null, "id,networkId,tenantId can not be null"); + print("id,networkId,tenantId can not be null"); return; } Subnet subnet = new DefaultSubnet(SubnetId.subnetId(id), subnetName, diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/subnet/SubnetUpdateCommand.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/subnet/SubnetUpdateCommand.java index b0578a1e..c76ca5b2 100644 --- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/subnet/SubnetUpdateCommand.java +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/cli/subnet/SubnetUpdateCommand.java @@ -98,7 +98,7 @@ public class SubnetUpdateCommand extends AbstractShellCommand { protected void execute() { SubnetService service = get(SubnetService.class); if (id == null || networkId == null || tenantId == null) { - print(null, "id,networkId,tenantId can not be null"); + print("id,networkId,tenantId can not be null"); return; } Subnet subnet = new DefaultSubnet(SubnetId.subnetId(id), subnetName, diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/event/VtnRscEvent.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/event/VtnRscEvent.java index 3bac158b..ce3faae7 100644 --- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/event/VtnRscEvent.java +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/event/VtnRscEvent.java @@ -51,7 +51,55 @@ public class VtnRscEvent /** * Signifies that router interface has remove. */ - ROUTER_INTERFACE_DELETE + ROUTER_INTERFACE_DELETE, + /** + * Signifies that port-pair has add. + */ + PORT_PAIR_PUT, + /** + * Signifies that port-pair has remove. + */ + PORT_PAIR_DELETE, + /** + * Signifies that port-pair has update. + */ + PORT_PAIR_UPDATE, + /** + * Signifies that port-pair-group has add. + */ + PORT_PAIR_GROUP_PUT, + /** + * Signifies that port-pair-group has remove. + */ + PORT_PAIR_GROUP_DELETE, + /** + * Signifies that port-pair-group has update. + */ + PORT_PAIR_GROUP_UPDATE, + /** + * Signifies that flow-classifier has add. + */ + FLOW_CLASSIFIER_PUT, + /** + * Signifies that flow-classifier has remove. + */ + FLOW_CLASSIFIER_DELETE, + /** + * Signifies that flow-classifier has update. + */ + FLOW_CLASSIFIER_UPDATE, + /** + * Signifies that port-chain has add. + */ + PORT_CHAIN_PUT, + /** + * Signifies that port-chain has remove. + */ + PORT_CHAIN_DELETE, + /** + * Signifies that port-chain has update. + */ + PORT_CHAIN_UPDATE } /** diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/event/VtnRscEventFeedback.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/event/VtnRscEventFeedback.java index 63dcaeee..112c6411 100644 --- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/event/VtnRscEventFeedback.java +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/event/VtnRscEventFeedback.java @@ -20,6 +20,10 @@ import java.util.Objects; import org.onosproject.vtnrsc.FloatingIp; import org.onosproject.vtnrsc.Router; import org.onosproject.vtnrsc.RouterInterface; +import org.onosproject.vtnrsc.PortPair; +import org.onosproject.vtnrsc.PortPairGroup; +import org.onosproject.vtnrsc.FlowClassifier; +import org.onosproject.vtnrsc.PortChain; import static com.google.common.base.MoreObjects.toStringHelper; import static com.google.common.base.Preconditions.checkNotNull; @@ -31,6 +35,10 @@ public class VtnRscEventFeedback { private final FloatingIp floaingtIp; private final Router router; private final RouterInterface routerInterface; + private final PortPair portPair; + private final PortPairGroup portPairGroup; + private final FlowClassifier flowClassifier; + private final PortChain portChain; /** * Creates VtnRscEventFeedback object. @@ -41,6 +49,10 @@ public class VtnRscEventFeedback { this.floaingtIp = checkNotNull(floatingIp, "floaintIp cannot be null"); this.router = null; this.routerInterface = null; + this.portPair = null; + this.portPairGroup = null; + this.flowClassifier = null; + this.portChain = null; } /** @@ -52,6 +64,10 @@ public class VtnRscEventFeedback { this.floaingtIp = null; this.router = checkNotNull(router, "router cannot be null"); this.routerInterface = null; + this.portPair = null; + this.portPairGroup = null; + this.flowClassifier = null; + this.portChain = null; } /** @@ -64,6 +80,74 @@ public class VtnRscEventFeedback { this.router = null; this.routerInterface = checkNotNull(routerInterface, "routerInterface cannot be null"); + this.portPair = null; + this.portPairGroup = null; + this.flowClassifier = null; + this.portChain = null; + } + + /** + * Creates VtnRscEventFeedback object. + * + * @param portPair the Port-Pair + */ + public VtnRscEventFeedback(PortPair portPair) { + this.floaingtIp = null; + this.router = null; + this.routerInterface = null; + this.portPair = checkNotNull(portPair, + "Port-Pair cannot be null"); + this.portPairGroup = null; + this.flowClassifier = null; + this.portChain = null; + } + + /** + * Creates VtnRscEventFeedback object. + * + * @param portPairGroup the Port-Pair-Group + */ + public VtnRscEventFeedback(PortPairGroup portPairGroup) { + this.floaingtIp = null; + this.router = null; + this.routerInterface = null; + this.portPair = null; + this.portPairGroup = checkNotNull(portPairGroup, + "Port-Pair-Group cannot be null"); + this.flowClassifier = null; + this.portChain = null; + } + + /** + * Creates VtnRscEventFeedback object. + * + * @param flowClassifier the Flow-Classifier + */ + public VtnRscEventFeedback(FlowClassifier flowClassifier) { + this.floaingtIp = null; + this.router = null; + this.routerInterface = null; + this.portPair = null; + this.portPairGroup = null; + this.flowClassifier = checkNotNull(flowClassifier, + "Flow-Classifier cannot be null"); + this.portChain = null; + } + + /** + * Creates VtnRscEventFeedback object. + * + * @param portChain the Port-Chain + */ + public VtnRscEventFeedback(PortChain portChain) { + this.floaingtIp = null; + this.router = null; + this.routerInterface = null; + this.portPair = null; + this.portPairGroup = null; + this.flowClassifier = null; + this.portChain = checkNotNull(portChain, + "Port-Chain cannot be null"); } /** @@ -93,9 +177,46 @@ public class VtnRscEventFeedback { return routerInterface; } + /** + * Returns Port-Pair. + * + * @return portPair the Port-Pair + */ + public PortPair portPair() { + return portPair; + } + + /** + * Returns Port-Pair-Group. + * + * @return portPairGroup the Port-Pair-Group + */ + public PortPairGroup portPairGroup() { + return portPairGroup; + } + + /** + * Returns Flow-Classifier. + * + * @return flowClassifier the Flow-Classifier + */ + public FlowClassifier flowClassifier() { + return flowClassifier; + } + + /** + * Returns Port-Chain. + * + * @return portChain the Port-Chain + */ + public PortChain portChain() { + return portChain; + } + @Override public int hashCode() { - return Objects.hash(floaingtIp, router, routerInterface); + return Objects.hash(floaingtIp, router, routerInterface, portPair, + portPairGroup, flowClassifier, portChain); } @Override @@ -107,7 +228,11 @@ public class VtnRscEventFeedback { final VtnRscEventFeedback that = (VtnRscEventFeedback) obj; return Objects.equals(this.floaingtIp, that.floaingtIp) && Objects.equals(this.router, that.router) - && Objects.equals(this.routerInterface, that.routerInterface); + && Objects.equals(this.routerInterface, that.routerInterface) + && Objects.equals(this.portPair, that.portPair) + && Objects.equals(this.portPairGroup, that.portPairGroup) + && Objects.equals(this.flowClassifier, that.flowClassifier) + && Objects.equals(this.portChain, that.portChain); } return false; } @@ -118,6 +243,10 @@ public class VtnRscEventFeedback { .add("router", router) .add("floaingtIp", floaingtIp) .add("routerInterface", routerInterface) + .add("portPair", portPair) + .add("portPairGroup", portPairGroup) + .add("flowClassifier", flowClassifier) + .add("portChain", portChain) .toString(); } } diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/floatingip/impl/FloatingIpManager.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/floatingip/impl/FloatingIpManager.java index 9f944da1..ce9bb21f 100644 --- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/floatingip/impl/FloatingIpManager.java +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/floatingip/impl/FloatingIpManager.java @@ -202,27 +202,24 @@ public class FloatingIpManager implements FloatingIpService { public boolean updateFloatingIps(Collection<FloatingIp> floatingIps) { checkNotNull(floatingIps, FLOATINGIP_NOT_NULL); boolean result = true; - if (floatingIps != null) { - for (FloatingIp floatingIp : floatingIps) { - verifyFloatingIpData(floatingIp); - if (floatingIp.portId() != null) { - floatingIpStore.put(floatingIp.id(), floatingIp); - if (!floatingIpStore.containsKey(floatingIp.id())) { + for (FloatingIp floatingIp : floatingIps) { + verifyFloatingIpData(floatingIp); + if (floatingIp.portId() != null) { + floatingIpStore.put(floatingIp.id(), floatingIp); + if (!floatingIpStore.containsKey(floatingIp.id())) { + log.debug("The floating Ip is updated failed whose identifier is {}", + floatingIp.id().toString()); + result = false; + } + } else { + FloatingIp oldFloatingIp = floatingIpStore.get(floatingIp.id()); + if (oldFloatingIp != null) { + floatingIpStore.remove(floatingIp.id(), oldFloatingIp); + if (floatingIpStore.containsKey(floatingIp.id())) { log.debug("The floating Ip is updated failed whose identifier is {}", floatingIp.id().toString()); result = false; } - } else { - FloatingIp oldFloatingIp = floatingIpStore.get(floatingIp - .id()); - if (oldFloatingIp != null) { - floatingIpStore.remove(floatingIp.id(), oldFloatingIp); - if (floatingIpStore.containsKey(floatingIp.id())) { - log.debug("The floating Ip is updated failed whose identifier is {}", - floatingIp.id().toString()); - result = false; - } - } } } } @@ -233,21 +230,19 @@ public class FloatingIpManager implements FloatingIpService { public boolean removeFloatingIps(Collection<FloatingIpId> floatingIpIds) { checkNotNull(floatingIpIds, FLOATINGIP_ID_NOT_NULL); boolean result = true; - if (floatingIpIds != null) { - for (FloatingIpId floatingIpId : floatingIpIds) { - if (!floatingIpStore.containsKey(floatingIpId)) { - log.debug("The floatingIp is not exist whose identifier is {}", - floatingIpId.toString()); - throw new IllegalArgumentException( - "FloatingIP ID doesn't exist"); - } - FloatingIp floatingIp = floatingIpStore.get(floatingIpId); - floatingIpStore.remove(floatingIpId, floatingIp); - if (floatingIpStore.containsKey(floatingIpId)) { - log.debug("The floating Ip is deleted failed whose identifier is {}", - floatingIpId.toString()); - result = false; - } + for (FloatingIpId floatingIpId : floatingIpIds) { + if (!floatingIpStore.containsKey(floatingIpId)) { + log.debug("The floatingIp is not exist whose identifier is {}", + floatingIpId.toString()); + throw new IllegalArgumentException( + "FloatingIP ID doesn't exist"); + } + FloatingIp floatingIp = floatingIpStore.get(floatingIpId); + floatingIpStore.remove(floatingIpId, floatingIp); + if (floatingIpStore.containsKey(floatingIpId)) { + log.debug("The floating Ip is deleted failed whose identifier is {}", + floatingIpId.toString()); + result = false; } } return result; diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowclassifier/FlowClassifierEvent.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowclassifier/FlowClassifierEvent.java new file mode 100644 index 00000000..d81ab48a --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowclassifier/FlowClassifierEvent.java @@ -0,0 +1,63 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc.flowclassifier; + +import org.onosproject.event.AbstractEvent; +import org.onosproject.vtnrsc.FlowClassifier; + +/** + * Describes network Flow-Classifier event. + */ +public class FlowClassifierEvent extends AbstractEvent<FlowClassifierEvent.Type, FlowClassifier> { + /** + * Type of flow-classifier events. + */ + public enum Type { + /** + * Signifies that flow-classifier has been created. + */ + FLOW_CLASSIFIER_PUT, + /** + * Signifies that flow-classifier has been deleted. + */ + FLOW_CLASSIFIER_DELETE, + /** + * Signifies that flow-classifier has been updated. + */ + FLOW_CLASSIFIER_UPDATE + } + + /** + * Creates an event of a given type and for the specified Flow-Classifier. + * + * @param type Flow-Classifier event type + * @param flowClassifier Flow-Classifier subject + */ + public FlowClassifierEvent(Type type, FlowClassifier flowClassifier) { + super(type, flowClassifier); + } + + /** + * Creates an event of a given type and for the specified Flow-Classifier. + * + * @param type Flow-Classifier event type + * @param flowClassifier Flow-Classifier subject + * @param time occurrence time + */ + public FlowClassifierEvent(Type type, FlowClassifier flowClassifier, long time) { + super(type, flowClassifier, time); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowclassifier/FlowClassifierListener.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowclassifier/FlowClassifierListener.java new file mode 100644 index 00000000..3c0409ad --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowclassifier/FlowClassifierListener.java @@ -0,0 +1,25 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc.flowclassifier; + +import org.onosproject.event.EventListener; + +/** + * Entity capable of Flow-Classifier related events. + */ +public interface FlowClassifierListener extends EventListener<FlowClassifierEvent> { + +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowclassifier/FlowClassifierService.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowclassifier/FlowClassifierService.java index c5911ff2..48438846 100644 --- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowclassifier/FlowClassifierService.java +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowclassifier/FlowClassifierService.java @@ -15,13 +15,14 @@ */ package org.onosproject.vtnrsc.flowclassifier; +import org.onosproject.event.ListenerService; import org.onosproject.vtnrsc.FlowClassifier; import org.onosproject.vtnrsc.FlowClassifierId; /** * Provides Services for Flow Classifier. */ -public interface FlowClassifierService { +public interface FlowClassifierService extends ListenerService<FlowClassifierEvent, FlowClassifierListener> { /** * Check whether Flow Classifier is present based on given Flow Classifier diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowclassifier/impl/FlowClassifierManager.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowclassifier/impl/FlowClassifierManager.java index 4a60cd34..18f63b30 100644 --- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowclassifier/impl/FlowClassifierManager.java +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/flowclassifier/impl/FlowClassifierManager.java @@ -15,6 +15,9 @@ */ package org.onosproject.vtnrsc.flowclassifier.impl; +import static org.slf4j.LoggerFactory.getLogger; +import static com.google.common.base.Preconditions.checkNotNull; + import org.apache.felix.scr.annotations.Activate; import org.apache.felix.scr.annotations.Component; import org.apache.felix.scr.annotations.Deactivate; @@ -22,6 +25,7 @@ import org.apache.felix.scr.annotations.Reference; import org.apache.felix.scr.annotations.ReferenceCardinality; import org.apache.felix.scr.annotations.Service; import org.onlab.util.KryoNamespace; +import org.onosproject.event.AbstractListenerManager; import org.onosproject.store.serializers.KryoNamespaces; import org.onosproject.store.service.EventuallyConsistentMap; import org.onosproject.store.service.MultiValuedTimestamp; @@ -29,12 +33,11 @@ import org.onosproject.store.service.StorageService; import org.onosproject.store.service.WallClockTimestamp; import org.onosproject.vtnrsc.FlowClassifierId; import org.onosproject.vtnrsc.FlowClassifier; +import org.onosproject.vtnrsc.flowclassifier.FlowClassifierEvent; +import org.onosproject.vtnrsc.flowclassifier.FlowClassifierListener; import org.onosproject.vtnrsc.flowclassifier.FlowClassifierService; import org.slf4j.Logger; -import static org.slf4j.LoggerFactory.getLogger; -import static com.google.common.base.Preconditions.checkNotNull; - import com.google.common.collect.ImmutableList; /** @@ -42,14 +45,17 @@ import com.google.common.collect.ImmutableList; */ @Component(immediate = true) @Service -public class FlowClassifierManager implements FlowClassifierService { - - private final Logger log = getLogger(FlowClassifierManager.class); +public class FlowClassifierManager extends AbstractListenerManager<FlowClassifierEvent, FlowClassifierListener> + implements FlowClassifierService { private static final String FLOW_CLASSIFIER_NOT_NULL = "Flow Classifier cannot be null"; private static final String FLOW_CLASSIFIER_ID_NOT_NULL = "Flow Classifier Id cannot be null"; + private static final String LISTENER_NOT_NULL = "Listener cannot be null"; + + private final Logger log = getLogger(FlowClassifierManager.class); private EventuallyConsistentMap<FlowClassifierId, FlowClassifier> flowClassifierStore; + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) protected StorageService storageService; diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portchain/PortChainEvent.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portchain/PortChainEvent.java new file mode 100644 index 00000000..44a4e8ed --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portchain/PortChainEvent.java @@ -0,0 +1,63 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc.portchain; + +import org.onosproject.event.AbstractEvent; +import org.onosproject.vtnrsc.PortChain; + +/** + * Describes network Port-Chain event. + */ +public class PortChainEvent extends AbstractEvent<PortChainEvent.Type, PortChain> { + /** + * Type of port-chain events. + */ + public enum Type { + /** + * Signifies that port-chain has been created. + */ + PORT_CHAIN_PUT, + /** + * Signifies that port-chain has been deleted. + */ + PORT_CHAIN_DELETE, + /** + * Signifies that port-chain has been updated. + */ + PORT_CHAIN_UPDATE + } + + /** + * Creates an event of a given type and for the specified Port-Chain. + * + * @param type Port-Chain event type + * @param portChain Port-Chain subject + */ + public PortChainEvent(Type type, PortChain portChain) { + super(type, portChain); + } + + /** + * Creates an event of a given type and for the specified Port-Chain. + * + * @param type Port-Chain event type + * @param portChain Port-Chain subject + * @param time occurrence time + */ + public PortChainEvent(Type type, PortChain portChain, long time) { + super(type, portChain, time); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portchain/PortChainListener.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portchain/PortChainListener.java new file mode 100644 index 00000000..27a498b5 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portchain/PortChainListener.java @@ -0,0 +1,25 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc.portchain; + +import org.onosproject.event.EventListener; + +/** + * Entity capable of Port-Chain related events. + */ +public interface PortChainListener extends EventListener<PortChainEvent> { + +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portchain/PortChainService.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portchain/PortChainService.java index b4ff917e..5b08262b 100644 --- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portchain/PortChainService.java +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portchain/PortChainService.java @@ -15,13 +15,14 @@ */ package org.onosproject.vtnrsc.portchain; +import org.onosproject.event.ListenerService; import org.onosproject.vtnrsc.PortChain; import org.onosproject.vtnrsc.PortChainId; /** * Service for interacting with the inventory of port chains. */ -public interface PortChainService { +public interface PortChainService extends ListenerService<PortChainEvent, PortChainListener> { /** * Returns if the port chain is existed. diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portchain/impl/PortChainManager.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portchain/impl/PortChainManager.java index 5201a2ca..0062db48 100644 --- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portchain/impl/PortChainManager.java +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portchain/impl/PortChainManager.java @@ -27,6 +27,7 @@ import org.apache.felix.scr.annotations.Reference; import org.apache.felix.scr.annotations.ReferenceCardinality; import org.apache.felix.scr.annotations.Service; import org.onlab.util.KryoNamespace; +import org.onosproject.event.AbstractListenerManager; import org.onosproject.store.serializers.KryoNamespaces; import org.onosproject.store.service.EventuallyConsistentMap; import org.onosproject.store.service.MultiValuedTimestamp; @@ -34,6 +35,8 @@ import org.onosproject.store.service.StorageService; import org.onosproject.store.service.WallClockTimestamp; import org.onosproject.vtnrsc.PortChain; import org.onosproject.vtnrsc.PortChainId; +import org.onosproject.vtnrsc.portchain.PortChainEvent; +import org.onosproject.vtnrsc.portchain.PortChainListener; import org.onosproject.vtnrsc.portchain.PortChainService; import org.slf4j.Logger; @@ -42,13 +45,14 @@ import org.slf4j.Logger; */ @Component(immediate = true) @Service -public class PortChainManager implements PortChainService { - - private final Logger log = getLogger(getClass()); +public class PortChainManager extends AbstractListenerManager<PortChainEvent, PortChainListener> implements + PortChainService { private static final String PORT_CHAIN_ID_NULL = "PortChain ID cannot be null"; private static final String PORT_CHAIN_NULL = "PortChain cannot be null"; + private static final String LISTENER_NOT_NULL = "Listener cannot be null"; + private final Logger log = getLogger(getClass()); private EventuallyConsistentMap<PortChainId, PortChain> portChainStore; @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpair/PortPairEvent.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpair/PortPairEvent.java new file mode 100644 index 00000000..31ecc737 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpair/PortPairEvent.java @@ -0,0 +1,63 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc.portpair; + +import org.onosproject.event.AbstractEvent; +import org.onosproject.vtnrsc.PortPair; + +/** + * Describes network Port-Pair event. + */ +public class PortPairEvent extends AbstractEvent<PortPairEvent.Type, PortPair> { + /** + * Type of port-pair events. + */ + public enum Type { + /** + * Signifies that port-pair has been created. + */ + PORT_PAIR_PUT, + /** + * Signifies that port-pair has been deleted. + */ + PORT_PAIR_DELETE, + /** + * Signifies that port-pair has been updated. + */ + PORT_PAIR_UPDATE + } + + /** + * Creates an event of a given type and for the specified Port-Pair. + * + * @param type Port-Pair event type + * @param portPair Port-Pair subject + */ + public PortPairEvent(Type type, PortPair portPair) { + super(type, portPair); + } + + /** + * Creates an event of a given type and for the specified Port-Pair. + * + * @param type Port-Pair event type + * @param portPair Port-Pair subject + * @param time occurrence time + */ + public PortPairEvent(Type type, PortPair portPair, long time) { + super(type, portPair, time); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpair/PortPairListener.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpair/PortPairListener.java new file mode 100644 index 00000000..3bdb9e4e --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpair/PortPairListener.java @@ -0,0 +1,25 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc.portpair; + +import org.onosproject.event.EventListener; + +/** + * Entity capable of Port-Pair related events. + */ +public interface PortPairListener extends EventListener<PortPairEvent> { + +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpair/PortPairService.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpair/PortPairService.java index f99cc2cf..e98a6a20 100644 --- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpair/PortPairService.java +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpair/PortPairService.java @@ -77,4 +77,18 @@ public interface PortPairService { * @return true if the give port pair is deleted successfully. */ boolean removePortPair(PortPairId portPairId); + + /** + * Adds the specified listener to Port-Pair manager. + * + * @param listener Port-Pair listener + */ + void addListener(PortPairListener listener); + + /** + * Removes the specified listener to Port-Pair manager. + * + * @param listener Port-Pair listener + */ + void removeListener(PortPairListener listener); } diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpair/impl/PortPairManager.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpair/impl/PortPairManager.java index 93c8782a..ad6fd4bb 100644 --- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpair/impl/PortPairManager.java +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpair/impl/PortPairManager.java @@ -19,6 +19,7 @@ import static com.google.common.base.Preconditions.checkNotNull; import static org.slf4j.LoggerFactory.getLogger; import java.util.Collections; +import java.util.Set; import org.apache.felix.scr.annotations.Activate; import org.apache.felix.scr.annotations.Component; @@ -34,9 +35,12 @@ import org.onosproject.store.service.StorageService; import org.onosproject.store.service.WallClockTimestamp; import org.onosproject.vtnrsc.PortPair; import org.onosproject.vtnrsc.PortPairId; +import org.onosproject.vtnrsc.portpair.PortPairListener; import org.onosproject.vtnrsc.portpair.PortPairService; import org.slf4j.Logger; +import com.google.common.collect.Sets; + /** * Provides implementation of the portPairService. */ @@ -44,11 +48,12 @@ import org.slf4j.Logger; @Service public class PortPairManager implements PortPairService { - private final Logger log = getLogger(getClass()); - private static final String PORT_PAIR_ID_NULL = "PortPair ID cannot be null"; private static final String PORT_PAIR_NULL = "PortPair cannot be null"; + private static final String LISTENER_NOT_NULL = "Listener cannot be null"; + private final Logger log = getLogger(getClass()); + private final Set<PortPairListener> listeners = Sets.newCopyOnWriteArraySet(); private EventuallyConsistentMap<PortPairId, PortPair> portPairStore; @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) @@ -73,6 +78,7 @@ public class PortPairManager implements PortPairService { @Deactivate public void deactivate() { portPairStore.destroy(); + listeners.clear(); log.info("Stopped"); } @@ -143,4 +149,16 @@ public class PortPairManager implements PortPairService { } return true; } + + @Override + public void addListener(PortPairListener listener) { + checkNotNull(listener, LISTENER_NOT_NULL); + listeners.add(listener); + } + + @Override + public void removeListener(PortPairListener listener) { + checkNotNull(listener, LISTENER_NOT_NULL); + listeners.remove(listener); + } } diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpairgroup/PortPairGroupEvent.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpairgroup/PortPairGroupEvent.java new file mode 100644 index 00000000..88e1d7fb --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpairgroup/PortPairGroupEvent.java @@ -0,0 +1,63 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc.portpairgroup; + +import org.onosproject.event.AbstractEvent; +import org.onosproject.vtnrsc.PortPairGroup; + +/** + * Describes network Port-Pair-Group event. + */ +public class PortPairGroupEvent extends AbstractEvent<PortPairGroupEvent.Type, PortPairGroup> { + /** + * Type of port-pair-group events. + */ + public enum Type { + /** + * Signifies that port-pair-group has been created. + */ + PORT_PAIR_GROUP_PUT, + /** + * Signifies that port-pair-group has been deleted. + */ + PORT_PAIR_GROUP_DELETE, + /** + * Signifies that port-pair-group has been updated. + */ + PORT_PAIR_GROUP_UPDATE + } + + /** + * Creates an event of a given type and for the specified Port-Pair-Group. + * + * @param type Port-Pair-Group event type + * @param portPairGroup Port-Pair-Group subject + */ + public PortPairGroupEvent(Type type, PortPairGroup portPairGroup) { + super(type, portPairGroup); + } + + /** + * Creates an event of a given type and for the specified Port-Pair-Group. + * + * @param type Port-Pair-Group event type + * @param portPairGroup Port-Pair-Group subject + * @param time occurrence time + */ + public PortPairGroupEvent(Type type, PortPairGroup portPairGroup, long time) { + super(type, portPairGroup, time); + } +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpairgroup/PortPairGroupListener.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpairgroup/PortPairGroupListener.java new file mode 100644 index 00000000..637149e3 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpairgroup/PortPairGroupListener.java @@ -0,0 +1,25 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnrsc.portpairgroup; + +import org.onosproject.event.EventListener; + +/** + * Entity capable of Port-Pair-Group related events. + */ +public interface PortPairGroupListener extends EventListener<PortPairGroupEvent> { + +} diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpairgroup/PortPairGroupService.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpairgroup/PortPairGroupService.java index 77f483fc..efee0eb9 100644 --- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpairgroup/PortPairGroupService.java +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpairgroup/PortPairGroupService.java @@ -77,4 +77,18 @@ public interface PortPairGroupService { * @return true if the give port pair group is deleted successfully. */ boolean removePortPairGroup(PortPairGroupId portPairGroupId); + + /** + * Adds the specified listener to Port-Pair-Group manager. + * + * @param listener Port-Pair-Group listener + */ + void addListener(PortPairGroupListener listener); + + /** + * Removes the specified listener to Port-Pair-Group manager. + * + * @param listener Port-Pair-Group listener + */ + void removeListener(PortPairGroupListener listener); } diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpairgroup/impl/PortPairGroupManager.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpairgroup/impl/PortPairGroupManager.java index 55fb4e43..5f80ef64 100644 --- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpairgroup/impl/PortPairGroupManager.java +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/portpairgroup/impl/PortPairGroupManager.java @@ -19,6 +19,7 @@ import static com.google.common.base.Preconditions.checkNotNull; import static org.slf4j.LoggerFactory.getLogger; import java.util.Collections; +import java.util.Set; import org.apache.felix.scr.annotations.Activate; import org.apache.felix.scr.annotations.Component; @@ -34,9 +35,12 @@ import org.onosproject.store.service.StorageService; import org.onosproject.store.service.WallClockTimestamp; import org.onosproject.vtnrsc.PortPairGroup; import org.onosproject.vtnrsc.PortPairGroupId; +import org.onosproject.vtnrsc.portpairgroup.PortPairGroupListener; import org.onosproject.vtnrsc.portpairgroup.PortPairGroupService; import org.slf4j.Logger; +import com.google.common.collect.Sets; + /** * Provides implementation of the portPairGroupService. */ @@ -44,11 +48,12 @@ import org.slf4j.Logger; @Service public class PortPairGroupManager implements PortPairGroupService { - private final Logger log = getLogger(getClass()); - private static final String PORT_PAIR_GROUP_ID_NULL = "PortPairGroup ID cannot be null"; private static final String PORT_PAIR_GROUP_NULL = "PortPairGroup cannot be null"; + private static final String LISTENER_NOT_NULL = "Listener cannot be null"; + private final Logger log = getLogger(getClass()); + private final Set<PortPairGroupListener> listeners = Sets.newCopyOnWriteArraySet(); private EventuallyConsistentMap<PortPairGroupId, PortPairGroup> portPairGroupStore; @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) @@ -73,6 +78,7 @@ public class PortPairGroupManager implements PortPairGroupService { @Deactivate public void deactivate() { portPairGroupStore.destroy(); + listeners.clear(); log.info("Stopped"); } @@ -143,4 +149,16 @@ public class PortPairGroupManager implements PortPairGroupService { } return true; } + + @Override + public void addListener(PortPairGroupListener listener) { + checkNotNull(listener, LISTENER_NOT_NULL); + listeners.add(listener); + } + + @Override + public void removeListener(PortPairGroupListener listener) { + checkNotNull(listener, LISTENER_NOT_NULL); + listeners.remove(listener); + } } diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/service/VtnRscService.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/service/VtnRscService.java index 21161ba5..bc9f4e68 100644 --- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/service/VtnRscService.java +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/service/VtnRscService.java @@ -18,32 +18,20 @@ package org.onosproject.vtnrsc.service; import java.util.Iterator; import org.onlab.packet.MacAddress; +import org.onosproject.event.ListenerService; import org.onosproject.net.Device; import org.onosproject.net.DeviceId; import org.onosproject.net.HostId; import org.onosproject.vtnrsc.SegmentationId; import org.onosproject.vtnrsc.TenantId; import org.onosproject.vtnrsc.VirtualPortId; +import org.onosproject.vtnrsc.event.VtnRscEvent; import org.onosproject.vtnrsc.event.VtnRscListener; /** * Service for interacting with the inventory of Vtn resource. */ -public interface VtnRscService { - /** - * Adds the specified listener. - * - * @param listener VtnRsc listener - */ - void addListener(VtnRscListener listener); - - /** - * Removes the specified listener. - * - * @param listener VtnRsc listener - */ - void removeListener(VtnRscListener listener); - +public interface VtnRscService extends ListenerService<VtnRscEvent, VtnRscListener> { /** * Returns the SegmentationId of tenant. * diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/service/impl/VtnRscManager.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/service/impl/VtnRscManager.java index ec9ca3ef..b21ad200 100644 --- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/service/impl/VtnRscManager.java +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/service/impl/VtnRscManager.java @@ -32,6 +32,7 @@ import org.onlab.packet.IpAddress; import org.onlab.packet.MacAddress; import org.onlab.util.KryoNamespace; import org.onosproject.core.CoreService; +import org.onosproject.event.AbstractListenerManager; import org.onosproject.net.Device; import org.onosproject.net.DeviceId; import org.onosproject.net.Host; @@ -54,6 +55,11 @@ import org.onosproject.vtnrsc.SubnetId; import org.onosproject.vtnrsc.TenantId; import org.onosproject.vtnrsc.VirtualPort; import org.onosproject.vtnrsc.VirtualPortId; +import org.onosproject.vtnrsc.PortPair; +import org.onosproject.vtnrsc.PortPairId; +import org.onosproject.vtnrsc.PortPairGroup; +import org.onosproject.vtnrsc.FlowClassifier; +import org.onosproject.vtnrsc.PortChain; import org.onosproject.vtnrsc.event.VtnRscEvent; import org.onosproject.vtnrsc.event.VtnRscEventFeedback; import org.onosproject.vtnrsc.event.VtnRscListener; @@ -70,16 +76,27 @@ import org.onosproject.vtnrsc.service.VtnRscService; import org.onosproject.vtnrsc.subnet.SubnetService; import org.onosproject.vtnrsc.tenantnetwork.TenantNetworkService; import org.onosproject.vtnrsc.virtualport.VirtualPortService; +import org.onosproject.vtnrsc.portpair.PortPairEvent; +import org.onosproject.vtnrsc.portpair.PortPairListener; +import org.onosproject.vtnrsc.portpair.PortPairService; +import org.onosproject.vtnrsc.portpairgroup.PortPairGroupEvent; +import org.onosproject.vtnrsc.portpairgroup.PortPairGroupListener; +import org.onosproject.vtnrsc.portpairgroup.PortPairGroupService; +import org.onosproject.vtnrsc.flowclassifier.FlowClassifierEvent; +import org.onosproject.vtnrsc.flowclassifier.FlowClassifierListener; +import org.onosproject.vtnrsc.flowclassifier.FlowClassifierService; +import org.onosproject.vtnrsc.portchain.PortChainEvent; +import org.onosproject.vtnrsc.portchain.PortChainListener; +import org.onosproject.vtnrsc.portchain.PortChainService; import org.slf4j.Logger; -import com.google.common.collect.Sets; - /** * Provides implementation of the VtnRsc service. */ @Component(immediate = true) @Service -public class VtnRscManager implements VtnRscService { +public class VtnRscManager extends AbstractListenerManager<VtnRscEvent, VtnRscListener> + implements VtnRscService { @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) protected CoreService coreService; @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) @@ -88,11 +105,14 @@ public class VtnRscManager implements VtnRscService { protected LogicalClockService clockService; private final Logger log = getLogger(getClass()); - private final Set<VtnRscListener> listeners = Sets.newCopyOnWriteArraySet(); private HostListener hostListener = new InnerHostListener(); private FloatingIpListener floatingIpListener = new InnerFloatingIpListener(); private RouterListener routerListener = new InnerRouterListener(); private RouterInterfaceListener routerInterfaceListener = new InnerRouterInterfaceListener(); + private PortPairListener portPairListener = new InnerPortPairListener(); + private PortPairGroupListener portPairGroupListener = new InnerPortPairGroupListener(); + private FlowClassifierListener flowClassifierListener = new InnerFlowClassifierListener(); + private PortChainListener portChainListener = new InnerPortChainListener(); private EventuallyConsistentMap<TenantId, SegmentationId> l3vniMap; private EventuallyConsistentMap<TenantId, Set<DeviceId>> classifierOvsMap; @@ -125,6 +145,14 @@ public class VtnRscManager implements VtnRscService { protected TenantNetworkService tenantNetworkService; @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) protected DeviceService deviceService; + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected PortPairService portPairService; + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected PortPairGroupService portPairGroupService; + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected FlowClassifierService flowClassifierService; + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected PortChainService portChainService; @Activate public void activate() { @@ -132,6 +160,10 @@ public class VtnRscManager implements VtnRscService { floatingIpService.addListener(floatingIpListener); routerService.addListener(routerListener); routerInterfaceService.addListener(routerInterfaceListener); + portPairService.addListener(portPairListener); + portPairGroupService.addListener(portPairGroupListener); + flowClassifierService.addListener(flowClassifierListener); + portChainService.addListener(portChainListener); KryoNamespace.Builder serializer = KryoNamespace.newBuilder() .register(KryoNamespaces.API) @@ -161,26 +193,18 @@ public class VtnRscManager implements VtnRscService { floatingIpService.removeListener(floatingIpListener); routerService.removeListener(routerListener); routerInterfaceService.removeListener(routerInterfaceListener); + portPairService.removeListener(portPairListener); + portPairGroupService.removeListener(portPairGroupListener); + flowClassifierService.removeListener(flowClassifierListener); + portChainService.removeListener(portChainListener); + l3vniMap.destroy(); classifierOvsMap.destroy(); sffOvsMap.destroy(); - listeners.clear(); log.info("Stopped"); } @Override - public void addListener(VtnRscListener listener) { - checkNotNull(listener, LISTENER_NOT_NULL); - listeners.add(listener); - } - - @Override - public void removeListener(VtnRscListener listener) { - checkNotNull(listener, LISTENER_NOT_NULL); - listeners.add(listener); - } - - @Override public SegmentationId getL3vni(TenantId tenantId) { checkNotNull(tenantId, "tenantId cannot be null"); SegmentationId l3vni = l3vniMap.get(tenantId); @@ -282,6 +306,93 @@ public class VtnRscManager implements VtnRscService { } } + private class InnerPortPairListener implements PortPairListener { + + @Override + public void event(PortPairEvent event) { + checkNotNull(event, EVENT_NOT_NULL); + PortPair portPair = event.subject(); + if (PortPairEvent.Type.PORT_PAIR_PUT == event.type()) { + notifyListeners(new VtnRscEvent(VtnRscEvent.Type.PORT_PAIR_PUT, + new VtnRscEventFeedback(portPair))); + } else if (PortPairEvent.Type.PORT_PAIR_DELETE == event.type()) { + notifyListeners(new VtnRscEvent( + VtnRscEvent.Type.PORT_PAIR_DELETE, + new VtnRscEventFeedback(portPair))); + } else if (PortPairEvent.Type.PORT_PAIR_UPDATE == event.type()) { + notifyListeners(new VtnRscEvent( + VtnRscEvent.Type.PORT_PAIR_UPDATE, + new VtnRscEventFeedback(portPair))); + } + } + } + + private class InnerPortPairGroupListener implements PortPairGroupListener { + + @Override + public void event(PortPairGroupEvent event) { + checkNotNull(event, EVENT_NOT_NULL); + PortPairGroup portPairGroup = event.subject(); + if (PortPairGroupEvent.Type.PORT_PAIR_GROUP_PUT == event.type()) { + notifyListeners(new VtnRscEvent( + VtnRscEvent.Type.PORT_PAIR_GROUP_PUT, + new VtnRscEventFeedback(portPairGroup))); + } else if (PortPairGroupEvent.Type.PORT_PAIR_GROUP_DELETE == event.type()) { + notifyListeners(new VtnRscEvent( + VtnRscEvent.Type.PORT_PAIR_GROUP_DELETE, + new VtnRscEventFeedback(portPairGroup))); + } else if (PortPairGroupEvent.Type.PORT_PAIR_GROUP_UPDATE == event.type()) { + notifyListeners(new VtnRscEvent( + VtnRscEvent.Type.PORT_PAIR_GROUP_UPDATE, + new VtnRscEventFeedback(portPairGroup))); + } + } + } + + private class InnerFlowClassifierListener implements FlowClassifierListener { + + @Override + public void event(FlowClassifierEvent event) { + checkNotNull(event, EVENT_NOT_NULL); + FlowClassifier flowClassifier = event.subject(); + if (FlowClassifierEvent.Type.FLOW_CLASSIFIER_PUT == event.type()) { + notifyListeners(new VtnRscEvent( + VtnRscEvent.Type.FLOW_CLASSIFIER_PUT, + new VtnRscEventFeedback(flowClassifier))); + } else if (FlowClassifierEvent.Type.FLOW_CLASSIFIER_DELETE == event.type()) { + notifyListeners(new VtnRscEvent( + VtnRscEvent.Type.FLOW_CLASSIFIER_DELETE, + new VtnRscEventFeedback(flowClassifier))); + } else if (FlowClassifierEvent.Type.FLOW_CLASSIFIER_UPDATE == event.type()) { + notifyListeners(new VtnRscEvent( + VtnRscEvent.Type.FLOW_CLASSIFIER_UPDATE, + new VtnRscEventFeedback(flowClassifier))); + } + } + } + + private class InnerPortChainListener implements PortChainListener { + + @Override + public void event(PortChainEvent event) { + checkNotNull(event, EVENT_NOT_NULL); + PortChain portChain = event.subject(); + if (PortChainEvent.Type.PORT_CHAIN_PUT == event.type()) { + notifyListeners(new VtnRscEvent( + VtnRscEvent.Type.PORT_CHAIN_PUT, + new VtnRscEventFeedback(portChain))); + } else if (PortChainEvent.Type.PORT_CHAIN_DELETE == event.type()) { + notifyListeners(new VtnRscEvent( + VtnRscEvent.Type.PORT_CHAIN_DELETE, + new VtnRscEventFeedback(portChain))); + } else if (PortChainEvent.Type.PORT_CHAIN_UPDATE == event.type()) { + notifyListeners(new VtnRscEvent( + VtnRscEvent.Type.PORT_CHAIN_UPDATE, + new VtnRscEventFeedback(portChain))); + } + } + } + @Override public Iterator<Device> getClassifierOfTenant(TenantId tenantId) { checkNotNull(tenantId, TENANTID_NOT_NULL); @@ -333,8 +444,7 @@ public class VtnRscManager implements VtnRscService { @Override public boolean isServiceFunction(VirtualPortId portId) { - // TODO Auto-generated method stub - return false; + return portPairService.exists(PortPairId.of(portId.portId())); } @Override @@ -343,7 +453,7 @@ public class VtnRscManager implements VtnRscService { VirtualPort vmPort = virtualPortService.getPort(portId); Set<Host> hostSet = hostService.getHostsByMac(vmPort.macAddress()); for (Host host : hostSet) { - if (host.annotations().value(IFACEID).equals(vmPort.portId())) { + if (host.annotations().value(IFACEID).equals(vmPort.portId().portId())) { return host.location().deviceId(); } } @@ -467,6 +577,6 @@ public class VtnRscManager implements VtnRscService { */ private void notifyListeners(VtnRscEvent event) { checkNotNull(event, EVENT_NOT_NULL); - listeners.forEach(listener -> listener.event(event)); + post(event); } } diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/virtualport/VirtualPortService.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/virtualport/VirtualPortService.java index 0a3ea2cd..19548db8 100644 --- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/virtualport/VirtualPortService.java +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/virtualport/VirtualPortService.java @@ -17,6 +17,7 @@ package org.onosproject.vtnrsc.virtualport; import java.util.Collection; +import org.onlab.packet.IpAddress; import org.onosproject.net.DeviceId; import org.onosproject.vtnrsc.FixedIp; import org.onosproject.vtnrsc.TenantId; @@ -53,6 +54,15 @@ public interface VirtualPortService { VirtualPort getPort(FixedIp fixedIP); /** + * Returns the virtualPort associated with the networkId and ip. + * + * @param networkId the TenantNetworkId identifier + * @param ip the ip identifier + * @return virtualPort. + */ + VirtualPort getPort(TenantNetworkId networkId, IpAddress ip); + + /** * Returns the collection of the currently known virtualPort. * @return collection of VirtualPort. */ diff --git a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/virtualport/impl/VirtualPortManager.java b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/virtualport/impl/VirtualPortManager.java index daec7839..9639e086 100644 --- a/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/virtualport/impl/VirtualPortManager.java +++ b/framework/src/onos/apps/vtn/vtnrsc/src/main/java/org/onosproject/vtnrsc/virtualport/impl/VirtualPortManager.java @@ -72,6 +72,7 @@ public class VirtualPortManager implements VirtualPortService { private static final String NETWORKID_NOT_NULL = "NetworkId cannot be null"; private static final String DEVICEID_NOT_NULL = "DeviceId cannot be null"; private static final String FIXEDIP_NOT_NULL = "FixedIp cannot be null"; + private static final String IP_NOT_NULL = "Ip cannot be null"; protected Map<VirtualPortId, VirtualPort> vPortStore; protected ApplicationId appId; @@ -148,6 +149,27 @@ public class VirtualPortManager implements VirtualPortService { } @Override + public VirtualPort getPort(TenantNetworkId networkId, IpAddress ip) { + checkNotNull(networkId, NETWORKID_NOT_NULL); + checkNotNull(ip, IP_NOT_NULL); + List<VirtualPort> vPorts = new ArrayList<>(); + vPortStore.values().stream().filter(p -> p.networkId().equals(networkId)) + .forEach(p -> { + Iterator<FixedIp> fixedIps = p.fixedIps().iterator(); + while (fixedIps.hasNext()) { + if (fixedIps.next().ip().equals(ip)) { + vPorts.add(p); + break; + } + } + }); + if (vPorts.size() == 0) { + return null; + } + return vPorts.get(0); + } + + @Override public Collection<VirtualPort> getPorts() { return Collections.unmodifiableCollection(vPortStore.values()); } diff --git a/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/FlowClassifierWebResource.java b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/FlowClassifierWebResource.java index 08e37f96..4fd3fa48 100644 --- a/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/FlowClassifierWebResource.java +++ b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/FlowClassifierWebResource.java @@ -36,12 +36,10 @@ import org.onosproject.rest.AbstractWebResource; import org.onosproject.vtnrsc.FlowClassifier; import org.onosproject.vtnrsc.FlowClassifierId; import org.onosproject.vtnrsc.flowclassifier.FlowClassifierService; -import org.onosproject.vtnweb.web.FlowClassifierCodec; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; @@ -64,11 +62,11 @@ public class FlowClassifierWebResource extends AbstractWebResource { @Produces(MediaType.APPLICATION_JSON) public Response getFlowClassifiers() { Iterable<FlowClassifier> flowClassifiers = get(FlowClassifierService.class).getFlowClassifiers(); - ObjectNode result = new ObjectMapper().createObjectNode(); + ObjectNode result = mapper().createObjectNode(); ArrayNode flowClassifierEntry = result.putArray("flow_classifiers"); if (flowClassifiers != null) { for (final FlowClassifier flowClassifier : flowClassifiers) { - flowClassifierEntry.add(new FlowClassifierCodec().encode(flowClassifier, this)); + flowClassifierEntry.add(codec(FlowClassifier.class).encode(flowClassifier, this)); } } return ok(result.toString()).build(); @@ -85,11 +83,11 @@ public class FlowClassifierWebResource extends AbstractWebResource { @Path("{flow_id}") @Produces(MediaType.APPLICATION_JSON) public Response getFlowClassifier(@PathParam("flow_id") String id) { - FlowClassifier flowClassifier = nullIsNotFound( - get(FlowClassifierService.class).getFlowClassifier(FlowClassifierId.of(id)), FLOW_CLASSIFIER_NOT_FOUND); + FlowClassifier flowClassifier = nullIsNotFound(get(FlowClassifierService.class) + .getFlowClassifier(FlowClassifierId.of(id)), FLOW_CLASSIFIER_NOT_FOUND); - ObjectNode result = new ObjectMapper().createObjectNode(); - result.set("flow_classifier", new FlowClassifierCodec().encode(flowClassifier, this)); + ObjectNode result = mapper().createObjectNode(); + result.set("flow_classifier", codec(FlowClassifier.class).encode(flowClassifier, this)); return ok(result.toString()).build(); } @@ -107,13 +105,12 @@ public class FlowClassifierWebResource extends AbstractWebResource { @Produces(MediaType.APPLICATION_JSON) public Response createFlowClassifier(InputStream stream) { try { - ObjectMapper mapper = new ObjectMapper(); - ObjectNode jsonTree = (ObjectNode) mapper.readTree(stream); + ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream); JsonNode flow = jsonTree.get("flow_classifier"); - FlowClassifier flowClassifier = new FlowClassifierCodec().decode((ObjectNode) flow, this); + FlowClassifier flowClassifier = codec(FlowClassifier.class).decode((ObjectNode) flow, this); Boolean issuccess = nullIsNotFound(get(FlowClassifierService.class).createFlowClassifier(flowClassifier), - FLOW_CLASSIFIER_NOT_FOUND); + FLOW_CLASSIFIER_NOT_FOUND); return Response.status(OK).entity(issuccess.toString()).build(); } catch (IOException ex) { log.error("Exception while creating flow classifier {}.", ex.toString()); @@ -139,9 +136,9 @@ public class FlowClassifierWebResource extends AbstractWebResource { JsonNode jsonTree = mapper().readTree(stream); JsonNode flow = jsonTree.get("flow_classifier"); - FlowClassifier flowClassifier = new FlowClassifierCodec().decode((ObjectNode) flow, this); + FlowClassifier flowClassifier = codec(FlowClassifier.class).decode((ObjectNode) flow, this); Boolean result = nullIsNotFound(get(FlowClassifierService.class).updateFlowClassifier(flowClassifier), - FLOW_CLASSIFIER_NOT_FOUND); + FLOW_CLASSIFIER_NOT_FOUND); return Response.status(OK).entity(result.toString()).build(); } catch (IOException e) { log.error("Update flow classifier failed because of exception {}.", e.toString()); @@ -161,7 +158,7 @@ public class FlowClassifierWebResource extends AbstractWebResource { log.debug("Deletes flow classifier by identifier {}.", id); FlowClassifierId flowClassifierId = FlowClassifierId.of(id); Boolean issuccess = nullIsNotFound(get(FlowClassifierService.class).removeFlowClassifier(flowClassifierId), - FLOW_CLASSIFIER_NOT_FOUND); + FLOW_CLASSIFIER_NOT_FOUND); } } diff --git a/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/PortChainWebResource.java b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/PortChainWebResource.java index db12bcc7..e7b908b7 100644 --- a/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/PortChainWebResource.java +++ b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/PortChainWebResource.java @@ -15,7 +15,6 @@ */ package org.onosproject.vtnweb.resources; -import static javax.ws.rs.core.Response.Status.NOT_FOUND; import static javax.ws.rs.core.Response.Status.OK; import static org.onlab.util.Tools.nullIsNotFound; @@ -37,11 +36,11 @@ import org.onosproject.rest.AbstractWebResource; import org.onosproject.vtnrsc.PortChain; import org.onosproject.vtnrsc.PortChainId; import org.onosproject.vtnrsc.portchain.PortChainService; -import org.onosproject.vtnweb.web.PortChainCodec; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; /** @@ -52,7 +51,6 @@ import com.fasterxml.jackson.databind.node.ObjectNode; public class PortChainWebResource extends AbstractWebResource { private final Logger log = LoggerFactory.getLogger(PortChainWebResource.class); - private final PortChainService service = get(PortChainService.class); public static final String PORT_CHAIN_NOT_FOUND = "Port chain not found"; public static final String PORT_CHAIN_ID_EXIST = "Port chain exists"; public static final String PORT_CHAIN_ID_NOT_EXIST = "Port chain does not exist with identifier"; @@ -65,10 +63,15 @@ public class PortChainWebResource extends AbstractWebResource { @GET @Produces(MediaType.APPLICATION_JSON) public Response getPortChains() { - Iterable<PortChain> portChains = service.getPortChains(); - ObjectNode result = new ObjectMapper().createObjectNode(); - result.set("port_chains", new PortChainCodec().encode(portChains, this)); - return ok(result).build(); + Iterable<PortChain> portChains = get(PortChainService.class).getPortChains(); + ObjectNode result = mapper().createObjectNode(); + ArrayNode portChainEntry = result.putArray("port_chains"); + if (portChains != null) { + for (final PortChain portChain : portChains) { + portChainEntry.add(codec(PortChain.class).encode(portChain, this)); + } + } + return ok(result.toString()).build(); } /** @@ -82,14 +85,11 @@ public class PortChainWebResource extends AbstractWebResource { @Produces(MediaType.APPLICATION_JSON) public Response getPortPain(@PathParam("chain_id") String id) { - if (!service.exists(PortChainId.of(id))) { - return Response.status(NOT_FOUND).entity(PORT_CHAIN_NOT_FOUND).build(); - } - PortChain portChain = nullIsNotFound(service.getPortChain(PortChainId.of(id)), + PortChain portChain = nullIsNotFound(get(PortChainService.class).getPortChain(PortChainId.of(id)), PORT_CHAIN_NOT_FOUND); - ObjectNode result = new ObjectMapper().createObjectNode(); - result.set("port_chain", new PortChainCodec().encode(portChain, this)); - return ok(result).build(); + ObjectNode result = mapper().createObjectNode(); + result.set("port_chain", codec(PortChain.class).encode(portChain, this)); + return ok(result.toString()).build(); } /** @@ -105,8 +105,10 @@ public class PortChainWebResource extends AbstractWebResource { public Response createPortChain(InputStream stream) { try { ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream); - PortChain portChain = codec(PortChain.class).decode(jsonTree, this); - Boolean issuccess = nullIsNotFound(service.createPortChain(portChain), PORT_CHAIN_NOT_FOUND); + JsonNode port = jsonTree.get("port_chain"); + PortChain portChain = codec(PortChain.class).decode((ObjectNode) port, this); + Boolean issuccess = nullIsNotFound(get(PortChainService.class).createPortChain(portChain), + PORT_CHAIN_NOT_FOUND); return Response.status(OK).entity(issuccess.toString()).build(); } catch (IOException e) { log.error("Exception while creating port chain {}.", e.toString()); @@ -129,8 +131,10 @@ public class PortChainWebResource extends AbstractWebResource { final InputStream stream) { try { ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream); - PortChain portChain = codec(PortChain.class).decode(jsonTree, this); - Boolean result = nullIsNotFound(service.updatePortChain(portChain), PORT_CHAIN_NOT_FOUND); + JsonNode port = jsonTree.get("port_chain"); + PortChain portChain = codec(PortChain.class).decode((ObjectNode) port, this); + Boolean result = nullIsNotFound(get(PortChainService.class).updatePortChain(portChain), + PORT_CHAIN_NOT_FOUND); return Response.status(OK).entity(result.toString()).build(); } catch (IOException e) { log.error("Update port chain failed because of exception {}.", e.toString()); @@ -149,7 +153,8 @@ public class PortChainWebResource extends AbstractWebResource { log.debug("Deletes port chain by identifier {}.", id); PortChainId portChainId = PortChainId.of(id); - Boolean issuccess = nullIsNotFound(service.removePortChain(portChainId), PORT_CHAIN_NOT_FOUND); + Boolean issuccess = nullIsNotFound(get(PortChainService.class).removePortChain(portChainId), + PORT_CHAIN_NOT_FOUND); if (!issuccess) { log.debug("Port Chain identifier {} does not exist", id); } diff --git a/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/PortPairGroupWebResource.java b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/PortPairGroupWebResource.java index 69daad37..dc5328a2 100644 --- a/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/PortPairGroupWebResource.java +++ b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/PortPairGroupWebResource.java @@ -16,7 +16,6 @@ package org.onosproject.vtnweb.resources; -import static javax.ws.rs.core.Response.Status.NOT_FOUND; import static javax.ws.rs.core.Response.Status.OK; import static org.onlab.util.Tools.nullIsNotFound; @@ -38,11 +37,12 @@ import org.onosproject.rest.AbstractWebResource; import org.onosproject.vtnrsc.PortPairGroup; import org.onosproject.vtnrsc.PortPairGroupId; import org.onosproject.vtnrsc.portpairgroup.PortPairGroupService; -import org.onosproject.vtnweb.web.PortPairGroupCodec; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; /** @@ -53,7 +53,6 @@ import com.fasterxml.jackson.databind.node.ObjectNode; public class PortPairGroupWebResource extends AbstractWebResource { private final Logger log = LoggerFactory.getLogger(PortPairGroupWebResource.class); - private final PortPairGroupService service = get(PortPairGroupService.class); public static final String PORT_PAIR_GROUP_NOT_FOUND = "Port pair group not found"; public static final String PORT_PAIR_GROUP_ID_EXIST = "Port pair group exists"; public static final String PORT_PAIR_GROUP_ID_NOT_EXIST = "Port pair group does not exist with identifier"; @@ -66,10 +65,15 @@ public class PortPairGroupWebResource extends AbstractWebResource { @GET @Produces(MediaType.APPLICATION_JSON) public Response getPortPairGroups() { - Iterable<PortPairGroup> portPairGroups = service.getPortPairGroups(); - ObjectNode result = new ObjectMapper().createObjectNode(); - result.set("port_pair_groups", new PortPairGroupCodec().encode(portPairGroups, this)); - return ok(result).build(); + Iterable<PortPairGroup> portPairGroups = get(PortPairGroupService.class).getPortPairGroups(); + ObjectNode result = mapper().createObjectNode(); + ArrayNode portPairGroupEntry = result.putArray("port_pair_groups"); + if (portPairGroups != null) { + for (final PortPairGroup portPairGroup : portPairGroups) { + portPairGroupEntry.add(codec(PortPairGroup.class).encode(portPairGroup, this)); + } + } + return ok(result.toString()).build(); } /** @@ -82,17 +86,13 @@ public class PortPairGroupWebResource extends AbstractWebResource { @Path("{group_id}") @Produces(MediaType.APPLICATION_JSON) public Response getPortPairGroup(@PathParam("group_id") String id) { - - if (!service.exists(PortPairGroupId.of(id))) { - return Response.status(NOT_FOUND) - .entity(PORT_PAIR_GROUP_NOT_FOUND).build(); - } - PortPairGroup portPairGroup = nullIsNotFound(service.getPortPairGroup(PortPairGroupId.of(id)), + PortPairGroup portPairGroup = nullIsNotFound(get(PortPairGroupService.class) + .getPortPairGroup(PortPairGroupId.of(id)), PORT_PAIR_GROUP_NOT_FOUND); - ObjectNode result = new ObjectMapper().createObjectNode(); - result.set("port_pair_group", new PortPairGroupCodec().encode(portPairGroup, this)); - return ok(result).build(); + ObjectNode result = mapper().createObjectNode(); + result.set("port_pair_group", codec(PortPairGroup.class).encode(portPairGroup, this)); + return ok(result.toString()).build(); } /** @@ -108,10 +108,12 @@ public class PortPairGroupWebResource extends AbstractWebResource { public Response createPortPairGroup(InputStream stream) { try { - ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream); + ObjectMapper mapper = new ObjectMapper(); + ObjectNode jsonTree = (ObjectNode) mapper.readTree(stream); + JsonNode port = jsonTree.get("port_pair_group"); - PortPairGroup portPairGroup = codec(PortPairGroup.class).decode(jsonTree, this); - Boolean issuccess = nullIsNotFound(service.createPortPairGroup(portPairGroup), + PortPairGroup portPairGroup = codec(PortPairGroup.class).decode((ObjectNode) port, this); + Boolean issuccess = nullIsNotFound(get(PortPairGroupService.class).createPortPairGroup(portPairGroup), PORT_PAIR_GROUP_NOT_FOUND); return Response.status(OK).entity(issuccess.toString()).build(); } catch (IOException e) { @@ -134,9 +136,12 @@ public class PortPairGroupWebResource extends AbstractWebResource { public Response updatePortPairGroup(@PathParam("group_id") String id, final InputStream stream) { try { - ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream); - PortPairGroup portPairGroup = codec(PortPairGroup.class).decode(jsonTree, this); - Boolean isSuccess = nullIsNotFound(service.updatePortPairGroup(portPairGroup), PORT_PAIR_GROUP_NOT_FOUND); + ObjectMapper mapper = new ObjectMapper(); + ObjectNode jsonTree = (ObjectNode) mapper.readTree(stream); + JsonNode port = jsonTree.get("port_pair_group"); + PortPairGroup portPairGroup = codec(PortPairGroup.class).decode((ObjectNode) port, this); + Boolean isSuccess = nullIsNotFound(get(PortPairGroupService.class).updatePortPairGroup(portPairGroup), + PORT_PAIR_GROUP_NOT_FOUND); return Response.status(OK).entity(isSuccess.toString()).build(); } catch (IOException e) { log.error("Update port pair group failed because of exception {}.", e.toString()); @@ -154,7 +159,7 @@ public class PortPairGroupWebResource extends AbstractWebResource { public void deletePortPairGroup(@PathParam("group_id") String id) { log.debug("Deletes port pair group by identifier {}.", id); PortPairGroupId portPairGroupId = PortPairGroupId.of(id); - Boolean issuccess = nullIsNotFound(service.removePortPairGroup(portPairGroupId), + Boolean issuccess = nullIsNotFound(get(PortPairGroupService.class).removePortPairGroup(portPairGroupId), PORT_PAIR_GROUP_NOT_FOUND); if (!issuccess) { log.debug("Port pair group identifier {} does not exist", id); diff --git a/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/PortPairWebResource.java b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/PortPairWebResource.java index b9012898..4ed8ecd8 100644 --- a/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/PortPairWebResource.java +++ b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/resources/PortPairWebResource.java @@ -16,7 +16,6 @@ package org.onosproject.vtnweb.resources; -import static javax.ws.rs.core.Response.Status.NOT_FOUND; import static javax.ws.rs.core.Response.Status.OK; import static org.onlab.util.Tools.nullIsNotFound; @@ -38,12 +37,10 @@ import org.onosproject.rest.AbstractWebResource; import org.onosproject.vtnrsc.PortPair; import org.onosproject.vtnrsc.PortPairId; import org.onosproject.vtnrsc.portpair.PortPairService; -import org.onosproject.vtnweb.web.PortPairCodec; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; @@ -54,7 +51,6 @@ import com.fasterxml.jackson.databind.node.ObjectNode; public class PortPairWebResource extends AbstractWebResource { private final Logger log = LoggerFactory.getLogger(PortPairWebResource.class); - private final PortPairService service = get(PortPairService.class); public static final String PORT_PAIR_NOT_FOUND = "Port pair not found"; public static final String PORT_PAIR_ID_EXIST = "Port pair exists"; public static final String PORT_PAIR_ID_NOT_EXIST = "Port pair does not exist with identifier"; @@ -67,12 +63,12 @@ public class PortPairWebResource extends AbstractWebResource { @GET @Produces(MediaType.APPLICATION_JSON) public Response getPortPairs() { - Iterable<PortPair> portPairs = service.getPortPairs(); - ObjectNode result = new ObjectMapper().createObjectNode(); + Iterable<PortPair> portPairs = get(PortPairService.class).getPortPairs(); + ObjectNode result = mapper().createObjectNode(); ArrayNode portPairEntry = result.putArray("port_pairs"); if (portPairs != null) { for (final PortPair portPair : portPairs) { - portPairEntry.add(new PortPairCodec().encode(portPair, this)); + portPairEntry.add(codec(PortPair.class).encode(portPair, this)); } } return ok(result.toString()).build(); @@ -88,13 +84,10 @@ public class PortPairWebResource extends AbstractWebResource { @Path("{pair_id}") @Produces(MediaType.APPLICATION_JSON) public Response getPortPair(@PathParam("pair_id") String id) { - - if (!service.exists(PortPairId.of(id))) { - return Response.status(NOT_FOUND).entity(PORT_PAIR_NOT_FOUND).build(); - } - PortPair portPair = nullIsNotFound(service.getPortPair(PortPairId.of(id)), PORT_PAIR_NOT_FOUND); - ObjectNode result = new ObjectMapper().createObjectNode(); - result.set("port_pair", new PortPairCodec().encode(portPair, this)); + PortPair portPair = nullIsNotFound(get(PortPairService.class).getPortPair(PortPairId.of(id)), + PORT_PAIR_NOT_FOUND); + ObjectNode result = mapper().createObjectNode(); + result.set("port_pair", codec(PortPair.class).encode(portPair, this)); return ok(result.toString()).build(); } @@ -110,11 +103,11 @@ public class PortPairWebResource extends AbstractWebResource { @Produces(MediaType.APPLICATION_JSON) public Response createPortPair(InputStream stream) { try { - ObjectMapper mapper = new ObjectMapper(); - ObjectNode jsonTree = (ObjectNode) mapper.readTree(stream); + ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream); JsonNode port = jsonTree.get("port_pair"); - PortPair portPair = new PortPairCodec().decode((ObjectNode) port, this); - Boolean isSuccess = nullIsNotFound(service.createPortPair(portPair), PORT_PAIR_NOT_FOUND); + PortPair portPair = codec(PortPair.class).decode((ObjectNode) port, this); + Boolean isSuccess = nullIsNotFound(get(PortPairService.class).createPortPair(portPair), + PORT_PAIR_NOT_FOUND); return Response.status(OK).entity(isSuccess.toString()).build(); } catch (IOException e) { log.error("Exception while creating port pair {}.", e.toString()); @@ -136,11 +129,11 @@ public class PortPairWebResource extends AbstractWebResource { public Response updatePortPair(@PathParam("pair_id") String id, final InputStream stream) { try { - ObjectMapper mapper = new ObjectMapper(); - ObjectNode jsonTree = (ObjectNode) mapper.readTree(stream); + ObjectNode jsonTree = (ObjectNode) mapper().readTree(stream); JsonNode port = jsonTree.get("port_pair"); - PortPair portPair = new PortPairCodec().decode((ObjectNode) port, this); - Boolean isSuccess = nullIsNotFound(service.updatePortPair(portPair), PORT_PAIR_NOT_FOUND); + PortPair portPair = codec(PortPair.class).decode((ObjectNode) port, this); + Boolean isSuccess = nullIsNotFound(get(PortPairService.class).updatePortPair(portPair), + PORT_PAIR_NOT_FOUND); return Response.status(OK).entity(isSuccess.toString()).build(); } catch (IOException e) { log.error("Update port pair failed because of exception {}.", e.toString()); @@ -158,7 +151,7 @@ public class PortPairWebResource extends AbstractWebResource { public void deletePortPair(@PathParam("pair_id") String id) { PortPairId portPairId = PortPairId.of(id); - Boolean isSuccess = nullIsNotFound(service.removePortPair(portPairId), PORT_PAIR_NOT_FOUND); + Boolean isSuccess = nullIsNotFound(get(PortPairService.class).removePortPair(portPairId), PORT_PAIR_NOT_FOUND); if (!isSuccess) { log.debug("Port pair identifier {} does not exist", id); } diff --git a/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/VtnCodecRegistrator.java b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/VtnCodecRegistrator.java new file mode 100644 index 00000000..e2defe59 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnweb/src/main/java/org/onosproject/vtnweb/web/VtnCodecRegistrator.java @@ -0,0 +1,56 @@ +/* + * Copyright 2014-2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnweb.web; + +import org.apache.felix.scr.annotations.Activate; +import org.apache.felix.scr.annotations.Component; +import org.apache.felix.scr.annotations.Deactivate; +import org.apache.felix.scr.annotations.Reference; +import org.apache.felix.scr.annotations.ReferenceCardinality; +import org.onosproject.codec.CodecService; +import org.onosproject.vtnrsc.FlowClassifier; +import org.onosproject.vtnrsc.PortChain; +import org.onosproject.vtnrsc.PortPair; +import org.onosproject.vtnrsc.PortPairGroup; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Implementation of the JSON codec brokering service for VTN app. + */ +@Component(immediate = true) +public class VtnCodecRegistrator { + + private static Logger log = LoggerFactory.getLogger(VtnCodecRegistrator.class); + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected CodecService codecService; + + @Activate + public void activate() { + codecService.registerCodec(PortPair.class, new PortPairCodec()); + codecService.registerCodec(PortPairGroup.class, new PortPairGroupCodec()); + codecService.registerCodec(FlowClassifier.class, new FlowClassifierCodec()); + codecService.registerCodec(PortChain.class, new PortChainCodec()); + + log.info("Started"); + } + + @Deactivate + public void deactivate() { + log.info("Stopped"); + } +} diff --git a/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/resources/FlowClassifierResourceTest.java b/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/resources/FlowClassifierResourceTest.java index be645be0..db08d7c4 100644 --- a/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/resources/FlowClassifierResourceTest.java +++ b/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/resources/FlowClassifierResourceTest.java @@ -40,11 +40,13 @@ import org.onlab.osgi.ServiceDirectory; import org.onlab.osgi.TestServiceDirectory; import org.onlab.packet.IpPrefix; import org.onlab.rest.BaseResource; +import org.onosproject.codec.CodecService; import org.onosproject.vtnrsc.FlowClassifier; import org.onosproject.vtnrsc.FlowClassifierId; import org.onosproject.vtnrsc.TenantId; import org.onosproject.vtnrsc.VirtualPortId; import org.onosproject.vtnrsc.flowclassifier.FlowClassifierService; +import org.onosproject.vtnweb.web.SfcCodecContext; import com.eclipsesource.json.JsonObject; import com.sun.jersey.api.client.ClientResponse; @@ -192,8 +194,11 @@ public class FlowClassifierResourceTest extends VtnResourceTest { */ @Before public void setUpTest() { - ServiceDirectory testDirectory = new TestServiceDirectory().add(FlowClassifierService.class, - flowClassifierService); + SfcCodecContext context = new SfcCodecContext(); + + ServiceDirectory testDirectory = new TestServiceDirectory() + .add(FlowClassifierService.class, flowClassifierService) + .add(CodecService.class, context.codecManager()); BaseResource.setServiceDirectory(testDirectory); } diff --git a/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/resources/PortChainResourceTest.java b/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/resources/PortChainResourceTest.java new file mode 100644 index 00000000..3cb2c83f --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/resources/PortChainResourceTest.java @@ -0,0 +1,247 @@ +/* + * Copyright 2014-2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnweb.resources; + +import static org.easymock.EasyMock.anyObject; +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.replay; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.fail; + +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.util.HashSet; +import java.util.List; +import java.util.Objects; +import java.util.Set; + +import javax.ws.rs.core.MediaType; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.onlab.osgi.ServiceDirectory; +import org.onlab.osgi.TestServiceDirectory; +import org.onlab.rest.BaseResource; +import org.onosproject.codec.CodecService; +import org.onosproject.vtnrsc.FlowClassifierId; +import org.onosproject.vtnrsc.PortChain; +import org.onosproject.vtnrsc.PortChainId; +import org.onosproject.vtnrsc.PortPairGroupId; +import org.onosproject.vtnrsc.TenantId; +import org.onosproject.vtnrsc.portchain.PortChainService; +import org.onosproject.vtnweb.web.SfcCodecContext; + +import com.eclipsesource.json.JsonObject; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; +import com.sun.jersey.api.client.ClientResponse; +import com.sun.jersey.api.client.UniformInterfaceException; +import com.sun.jersey.api.client.WebResource; + +/** + * Unit tests for port chain REST APIs. + */ +public class PortChainResourceTest extends VtnResourceTest { + + final PortChainService portChainService = createMock(PortChainService.class); + + PortChainId portChainId1 = PortChainId.of("78dcd363-fc23-aeb6-f44b-56dc5e2fb3ae"); + TenantId tenantId1 = TenantId.tenantId("d382007aa9904763a801f68ecf065cf5"); + private final List<PortPairGroupId> portPairGroupList1 = Lists.newArrayList(); + private final List<FlowClassifierId> flowClassifierList1 = Lists.newArrayList(); + + + final MockPortChain portChain1 = new MockPortChain(portChainId1, tenantId1, "portChain1", + "Mock port chain", portPairGroupList1, + flowClassifierList1); + + /** + * Mock class for a port chain. + */ + private static class MockPortChain implements PortChain { + + private final PortChainId portChainId; + private final TenantId tenantId; + private final String name; + private final String description; + private final List<PortPairGroupId> portPairGroupList; + private final List<FlowClassifierId> flowClassifierList; + + public MockPortChain(PortChainId portChainId, TenantId tenantId, + String name, String description, + List<PortPairGroupId> portPairGroupList, + List<FlowClassifierId> flowClassifierList) { + + this.portChainId = portChainId; + this.tenantId = tenantId; + this.name = name; + this.description = description; + this.portPairGroupList = portPairGroupList; + this.flowClassifierList = flowClassifierList; + } + + @Override + public PortChainId portChainId() { + return portChainId; + } + + @Override + public TenantId tenantId() { + return tenantId; + } + + @Override + public String name() { + return name; + } + + @Override + public String description() { + return description; + } + + @Override + public List<PortPairGroupId> portPairGroups() { + return ImmutableList.copyOf(portPairGroupList); + } + + @Override + public List<FlowClassifierId> flowClassifiers() { + return ImmutableList.copyOf(flowClassifierList); + } + + @Override + public boolean exactMatch(PortChain portChain) { + return this.equals(portChain) && + Objects.equals(this.portChainId, portChain.portChainId()) && + Objects.equals(this.tenantId, portChain.tenantId()); + } + } + + /** + * Sets up the global values for all the tests. + */ + @Before + public void setUpTest() { + SfcCodecContext context = new SfcCodecContext(); + ServiceDirectory testDirectory = new TestServiceDirectory() + .add(PortChainService.class, portChainService) + .add(CodecService.class, context.codecManager()); + BaseResource.setServiceDirectory(testDirectory); + + } + + /** + * Cleans up. + */ + @After + public void tearDownTest() { + } + + /** + * Tests the result of the rest api GET when there are no port chains. + */ + @Test + public void testPortChainsEmpty() { + + expect(portChainService.getPortChains()).andReturn(null).anyTimes(); + replay(portChainService); + final WebResource rs = resource(); + final String response = rs.path("port_chains").get(String.class); + assertThat(response, is("{\"port_chains\":[]}")); + } + + /** + * Tests the result of a rest api GET for port chain id. + */ + @Test + public void testGetPortChainId() { + + final Set<PortChain> portChains = new HashSet<>(); + portChains.add(portChain1); + + expect(portChainService.exists(anyObject())).andReturn(true).anyTimes(); + expect(portChainService.getPortChain(anyObject())).andReturn(portChain1).anyTimes(); + replay(portChainService); + + final WebResource rs = resource(); + final String response = rs.path("port_chains/1278dcd4-459f-62ed-754b-87fc5e4a6751").get(String.class); + final JsonObject result = JsonObject.readFrom(response); + assertThat(result, notNullValue()); + } + + /** + * Tests that a fetch of a non-existent port chain object throws an exception. + */ + @Test + public void testBadGet() { + expect(portChainService.getPortChain(anyObject())) + .andReturn(null).anyTimes(); + replay(portChainService); + WebResource rs = resource(); + try { + rs.path("port_chains/78dcd363-fc23-aeb6-f44b-56dc5aafb3ae").get(String.class); + fail("Fetch of non-existent port chain did not throw an exception"); + } catch (UniformInterfaceException ex) { + assertThat(ex.getMessage(), + containsString("returned a response status of")); + } + } + + /** + * Tests creating a port chain with POST. + */ + @Test + public void testPost() { + + expect(portChainService.createPortChain(anyObject())) + .andReturn(true).anyTimes(); + replay(portChainService); + + WebResource rs = resource(); + InputStream jsonStream = PortChainResourceTest.class.getResourceAsStream("post-PortChain.json"); + + ClientResponse response = rs.path("port_chains") + .type(MediaType.APPLICATION_JSON_TYPE) + .post(ClientResponse.class, jsonStream); + assertThat(response.getStatus(), is(HttpURLConnection.HTTP_OK)); + } + + /** + * Tests deleting a port chain. + */ + @Test + public void testDelete() { + expect(portChainService.removePortChain(anyObject())) + .andReturn(true).anyTimes(); + replay(portChainService); + + WebResource rs = resource(); + + String location = "port_chains/1278dcd4-459f-62ed-754b-87fc5e4a6751"; + + ClientResponse deleteResponse = rs.path(location) + .type(MediaType.APPLICATION_JSON_TYPE) + .delete(ClientResponse.class); + assertThat(deleteResponse.getStatus(), + is(HttpURLConnection.HTTP_NO_CONTENT)); + } +} diff --git a/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/resources/PortPairGroupResourceTest.java b/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/resources/PortPairGroupResourceTest.java new file mode 100644 index 00000000..c13f2141 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/resources/PortPairGroupResourceTest.java @@ -0,0 +1,234 @@ +/* + * Copyright 2014-2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtnweb.resources; + +import static org.easymock.EasyMock.anyObject; +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.replay; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.fail; + +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.util.HashSet; +import java.util.List; +import java.util.Objects; +import java.util.Set; + +import javax.ws.rs.core.MediaType; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.onlab.osgi.ServiceDirectory; +import org.onlab.osgi.TestServiceDirectory; +import org.onlab.rest.BaseResource; +import org.onosproject.codec.CodecService; +import org.onosproject.vtnrsc.PortPairGroup; +import org.onosproject.vtnrsc.PortPairGroupId; +import org.onosproject.vtnrsc.PortPairId; +import org.onosproject.vtnrsc.TenantId; +import org.onosproject.vtnrsc.portpairgroup.PortPairGroupService; +import org.onosproject.vtnweb.web.SfcCodecContext; + +import com.eclipsesource.json.JsonObject; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; +import com.sun.jersey.api.client.ClientResponse; +import com.sun.jersey.api.client.UniformInterfaceException; +import com.sun.jersey.api.client.WebResource; +/** + * Unit tests for port pair group REST APIs. + */ +public class PortPairGroupResourceTest extends VtnResourceTest { + + final PortPairGroupService portPairGroupService = createMock(PortPairGroupService.class); + + PortPairGroupId portPairGroupId1 = PortPairGroupId.of("4512d643-24fc-4fae-af4b-321c5e2eb3d1"); + TenantId tenantId1 = TenantId.tenantId("d382007aa9904763a801f68ecf065cf5"); + private final List<PortPairId> portPairList1 = Lists.newArrayList(); + + final MockPortPairGroup portPairGroup1 = new MockPortPairGroup(portPairGroupId1, tenantId1, "portPairGroup1", + "Mock port pair group", portPairList1); + + /** + * Mock class for a port pair group. + */ + private static class MockPortPairGroup implements PortPairGroup { + + private final PortPairGroupId portPairGroupId; + private final TenantId tenantId; + private final String name; + private final String description; + private final List<PortPairId> portPairList; + + public MockPortPairGroup(PortPairGroupId portPairGroupId, TenantId tenantId, + String name, String description, + List<PortPairId> portPairList) { + + this.portPairGroupId = portPairGroupId; + this.tenantId = tenantId; + this.name = name; + this.description = description; + this.portPairList = portPairList; + } + + @Override + public PortPairGroupId portPairGroupId() { + return portPairGroupId; + } + + @Override + public TenantId tenantId() { + return tenantId; + } + + @Override + public String name() { + return name; + } + + @Override + public String description() { + return description; + } + + @Override + public List<PortPairId> portPairs() { + return ImmutableList.copyOf(portPairList); + } + + @Override + public boolean exactMatch(PortPairGroup portPairGroup) { + return this.equals(portPairGroup) && + Objects.equals(this.portPairGroupId, portPairGroup.portPairGroupId()) && + Objects.equals(this.tenantId, portPairGroup.tenantId()); + } + } + + /** + * Sets up the global values for all the tests. + */ + @Before + public void setUpTest() { + SfcCodecContext context = new SfcCodecContext(); + ServiceDirectory testDirectory = new TestServiceDirectory() + .add(PortPairGroupService.class, portPairGroupService) + .add(CodecService.class, context.codecManager()); + BaseResource.setServiceDirectory(testDirectory); + + } + + /** + * Cleans up. + */ + @After + public void tearDownTest() { + } + + /** + * Tests the result of the rest api GET when there are no port pair groups. + */ + @Test + public void testPortPairGroupsEmpty() { + + expect(portPairGroupService.getPortPairGroups()).andReturn(null).anyTimes(); + replay(portPairGroupService); + final WebResource rs = resource(); + final String response = rs.path("port_pair_groups").get(String.class); + assertThat(response, is("{\"port_pair_groups\":[]}")); + } + + /** + * Tests the result of a rest api GET for port pair group id. + */ + @Test + public void testGetPortPairGroupId() { + + final Set<PortPairGroup> portPairGroups = new HashSet<>(); + portPairGroups.add(portPairGroup1); + + expect(portPairGroupService.exists(anyObject())).andReturn(true).anyTimes(); + expect(portPairGroupService.getPortPairGroup(anyObject())).andReturn(portPairGroup1).anyTimes(); + replay(portPairGroupService); + + final WebResource rs = resource(); + final String response = rs.path("port_pair_groups/4512d643-24fc-4fae-af4b-321c5e2eb3d1").get(String.class); + final JsonObject result = JsonObject.readFrom(response); + assertThat(result, notNullValue()); + } + + /** + * Tests that a fetch of a non-existent port pair group object throws an exception. + */ + @Test + public void testBadGet() { + expect(portPairGroupService.getPortPairGroup(anyObject())) + .andReturn(null).anyTimes(); + replay(portPairGroupService); + WebResource rs = resource(); + try { + rs.path("port_pair_groups/78dcd363-fc23-aeb6-f44b-56dc5aafb3ae").get(String.class); + fail("Fetch of non-existent port pair group did not throw an exception"); + } catch (UniformInterfaceException ex) { + assertThat(ex.getMessage(), + containsString("returned a response status of")); + } + } + + /** + * Tests creating a port pair group with POST. + */ + @Test + public void testPost() { + + expect(portPairGroupService.createPortPairGroup(anyObject())) + .andReturn(true).anyTimes(); + replay(portPairGroupService); + + WebResource rs = resource(); + InputStream jsonStream = PortPairGroupResourceTest.class.getResourceAsStream("post-PortPairGroup.json"); + + ClientResponse response = rs.path("port_pair_groups") + .type(MediaType.APPLICATION_JSON_TYPE) + .post(ClientResponse.class, jsonStream); + assertThat(response.getStatus(), is(HttpURLConnection.HTTP_OK)); + } + + /** + * Tests deleting a port pair group. + */ + @Test + public void testDelete() { + expect(portPairGroupService.removePortPairGroup(anyObject())) + .andReturn(true).anyTimes(); + replay(portPairGroupService); + + WebResource rs = resource(); + + String location = "port_pair_groups/4512d643-24fc-4fae-af4b-321c5e2eb3d1"; + + ClientResponse deleteResponse = rs.path(location) + .type(MediaType.APPLICATION_JSON_TYPE) + .delete(ClientResponse.class); + assertThat(deleteResponse.getStatus(), + is(HttpURLConnection.HTTP_NO_CONTENT)); + } +} diff --git a/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/resources/PortPairResourceTest.java b/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/resources/PortPairResourceTest.java index 271904cc..36014ec5 100644 --- a/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/resources/PortPairResourceTest.java +++ b/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/resources/PortPairResourceTest.java @@ -39,10 +39,12 @@ import org.junit.Test; import org.onlab.osgi.ServiceDirectory; import org.onlab.osgi.TestServiceDirectory; import org.onlab.rest.BaseResource; +import org.onosproject.codec.CodecService; import org.onosproject.vtnrsc.PortPair; import org.onosproject.vtnrsc.PortPairId; import org.onosproject.vtnrsc.TenantId; import org.onosproject.vtnrsc.portpair.PortPairService; +import org.onosproject.vtnweb.web.SfcCodecContext; import com.eclipsesource.json.JsonObject; import com.sun.jersey.api.client.ClientResponse; @@ -129,7 +131,10 @@ public class PortPairResourceTest extends VtnResourceTest { */ @Before public void setUpTest() { - ServiceDirectory testDirectory = new TestServiceDirectory().add(PortPairService.class, portPairService); + + SfcCodecContext context = new SfcCodecContext(); + ServiceDirectory testDirectory = new TestServiceDirectory().add(PortPairService.class, portPairService) + .add(CodecService.class, context.codecManager()); BaseResource.setServiceDirectory(testDirectory); } diff --git a/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/web/SfcCodecContext.java b/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/web/SfcCodecContext.java index fe9d7995..c56a4fcb 100644 --- a/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/web/SfcCodecContext.java +++ b/framework/src/onos/apps/vtn/vtnweb/src/test/java/org/onosproject/vtnweb/web/SfcCodecContext.java @@ -15,15 +15,10 @@ */ package org.onosproject.vtnweb.web; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - import org.onosproject.codec.CodecContext; +import org.onosproject.codec.CodecService; import org.onosproject.codec.JsonCodec; -import org.onosproject.vtnrsc.FlowClassifier; -import org.onosproject.vtnrsc.PortChain; -import org.onosproject.vtnrsc.PortPair; -import org.onosproject.vtnrsc.PortPairGroup; +import org.onosproject.codec.impl.CodecManager; import com.fasterxml.jackson.databind.ObjectMapper; @@ -33,17 +28,16 @@ import com.fasterxml.jackson.databind.ObjectMapper; public class SfcCodecContext implements CodecContext { private final ObjectMapper mapper = new ObjectMapper(); - private final Map<Class<?>, JsonCodec> codecs = new ConcurrentHashMap<>(); + private final CodecManager codecManager = new CodecManager(); + private final VtnCodecRegistrator manager = new VtnCodecRegistrator(); /** * Constructs a new mock codec context. */ public SfcCodecContext() { - codecs.clear(); - registerCodec(PortPair.class, new PortPairCodec()); - registerCodec(PortChain.class, new PortChainCodec()); - registerCodec(PortPairGroup.class, new PortPairGroupCodec()); - registerCodec(FlowClassifier.class, new FlowClassifierCodec()); + codecManager.activate(); + manager.codecService = codecManager; + manager.activate(); } @Override @@ -58,20 +52,17 @@ public class SfcCodecContext implements CodecContext { return null; } + @Override + public <T> JsonCodec<T> codec(Class<T> entityClass) { + return codecManager.getCodec(entityClass); + } + /** - * Registers the specified JSON codec for the given entity class. + * Get the codec manager. * - * @param entityClass entity class - * @param codec JSON codec - * @param <T> entity type + * @return instance of codec manager */ - public <T> void registerCodec(Class<T> entityClass, JsonCodec<T> codec) { - codecs.putIfAbsent(entityClass, codec); - } - - @SuppressWarnings("unchecked") - @Override - public <T> JsonCodec<T> codec(Class<T> entityClass) { - return codecs.get(entityClass); + public CodecService codecManager() { + return codecManager; } } diff --git a/framework/src/onos/apps/vtn/vtnweb/src/test/resources/org/onosproject/vtnweb/resources/post-PortChain.json b/framework/src/onos/apps/vtn/vtnweb/src/test/resources/org/onosproject/vtnweb/resources/post-PortChain.json new file mode 100644 index 00000000..488e290f --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnweb/src/test/resources/org/onosproject/vtnweb/resources/post-PortChain.json @@ -0,0 +1,15 @@ +{"port_pair": { + "id": "1278dcd4-459f-62ed-754b-87fc5e4a6751", + "name": "PC2", + "tenant_id": "d382007aa9904763a801f68ecf065cf5", + "description": "Two flows and two port-pair-groups", + "flow_classifiers": [ + "456a4a34-2e9c-14ae-37fb-765feae2eb05", + "4a334cd4-fe9c-4fae-af4b-321c5e2eb051" + ], + "port_pair_groups": [ + "4512d643-24fc-4fae-af4b-321c5e2eb3d1", + "4a634d49-76dc-4fae-af4b-321c5e23d651" + ] + } +} diff --git a/framework/src/onos/apps/vtn/vtnweb/src/test/resources/org/onosproject/vtnweb/resources/post-PortPairGroup.json b/framework/src/onos/apps/vtn/vtnweb/src/test/resources/org/onosproject/vtnweb/resources/post-PortPairGroup.json new file mode 100644 index 00000000..f6a888d9 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnweb/src/test/resources/org/onosproject/vtnweb/resources/post-PortPairGroup.json @@ -0,0 +1,11 @@ +{"port_pair_group": { + "id": "4512d643-24fc-4fae-af4b-321c5e2eb3d1", + "name": "portPairGroup1", + "tenant_id": "d382007aa9904763a801f68ecf065cf5", + "description": "Mock port pair group", + "port_pairs": [ + "875dfeda-43ed-23fe-454b-764feab2c342", + "78dcd363-fc23-aeb6-f44b-56dc5e2fb3ae" + ] +} +} |