diff options
Diffstat (limited to 'framework/src/onos/apps/xos-integration')
12 files changed, 1178 insertions, 0 deletions
diff --git a/framework/src/onos/apps/xos-integration/features.xml b/framework/src/onos/apps/xos-integration/features.xml new file mode 100644 index 00000000..a7b14569 --- /dev/null +++ b/framework/src/onos/apps/xos-integration/features.xml @@ -0,0 +1,24 @@ +<?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}"> + <repository>mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features</repository> + <feature name="${project.artifactId}" version="${project.version}" + description="${project.description}"> + <bundle>mvn:com.sun.jersey/jersey-client/1.19</bundle> + <bundle>mvn:${project.groupId}/${project.artifactId}/${project.version}</bundle> + </feature> +</features> diff --git a/framework/src/onos/apps/xos-integration/pom.xml b/framework/src/onos/apps/xos-integration/pom.xml new file mode 100644 index 00000000..0dc2300e --- /dev/null +++ b/framework/src/onos/apps/xos-integration/pom.xml @@ -0,0 +1,67 @@ +<?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.3.0-SNAPSHOT</version> + <relativePath>../pom.xml</relativePath> + </parent> + + <artifactId>onos-app-xos-integration</artifactId> + <packaging>bundle</packaging> + + <description>ONOS XOS integration application</description> + + <properties> + <onos.app.name>org.onosproject.xosintegration</onos.app.name> + </properties> + + <dependencies> + <dependency> + <groupId>org.osgi</groupId> + <artifactId>org.osgi.compendium</artifactId> + </dependency> + <dependency> + <groupId>com.sun.jersey</groupId> + <artifactId>jersey-client</artifactId> + <version>1.19</version> + </dependency> + <dependency> + <groupId>org.onosproject</groupId> + <artifactId>onos-cli</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.osgi</groupId> + <artifactId>org.osgi.core</artifactId> + </dependency> + <dependency> + <groupId>org.apache.karaf.shell</groupId> + <artifactId>org.apache.karaf.shell.console</artifactId> + </dependency> + <dependency> + <groupId>org.onosproject</groupId> + <artifactId>onlab-misc</artifactId> + </dependency> + </dependencies> + +</project> diff --git a/framework/src/onos/apps/xos-integration/src/main/java/org/onosproject/xosintegration/OnosXOSIntegrationManager.java b/framework/src/onos/apps/xos-integration/src/main/java/org/onosproject/xosintegration/OnosXOSIntegrationManager.java new file mode 100644 index 00000000..1f686aeb --- /dev/null +++ b/framework/src/onos/apps/xos-integration/src/main/java/org/onosproject/xosintegration/OnosXOSIntegrationManager.java @@ -0,0 +1,545 @@ +/* + * 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.xosintegration; + +import com.eclipsesource.json.JsonArray; +import com.eclipsesource.json.JsonObject; +import com.google.common.collect.Maps; +import com.sun.jersey.api.client.Client; +import com.sun.jersey.api.client.ClientHandlerException; +import com.sun.jersey.api.client.ClientResponse; +import com.sun.jersey.api.client.WebResource; +import com.sun.jersey.api.client.filter.HTTPBasicAuthFilter; +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 org.apache.felix.scr.annotations.Reference; +import org.apache.felix.scr.annotations.ReferenceCardinality; +import org.apache.felix.scr.annotations.Service; +import org.onlab.packet.VlanId; +import org.onlab.util.Tools; +import org.onosproject.cfg.ComponentConfigService; +import org.onosproject.core.ApplicationId; +import org.onosproject.core.CoreService; +import org.onosproject.net.ConnectPoint; +import org.onosproject.net.DeviceId; +import org.onosproject.net.PortNumber; +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.flowobjective.DefaultForwardingObjective; +import org.onosproject.net.flowobjective.FlowObjectiveService; +import org.onosproject.net.flowobjective.ForwardingObjective; +import org.osgi.service.component.ComponentContext; +import org.slf4j.Logger; + +import java.util.Dictionary; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +import static com.google.common.base.Strings.isNullOrEmpty; +import static com.google.common.net.MediaType.JSON_UTF_8; +import static java.net.HttpURLConnection.HTTP_CREATED; +import static java.net.HttpURLConnection.HTTP_NO_CONTENT; +import static java.net.HttpURLConnection.HTTP_OK; +import static org.slf4j.LoggerFactory.getLogger; + + +/** + * XOS interface application. + */ +@Component(immediate = true) +@Service +public class OnosXOSIntegrationManager implements VoltTenantService { + private static final String XOS_SERVER_ADDRESS_PROPERTY_NAME = + "xosServerAddress"; + private static final String XOS_SERVER_PORT_PROPERTY_NAME = + "xosServerPort"; + private static final String XOS_PROVIDER_SERVICE_PROPERTY_NAME = + "xosProviderService"; + + private static final String TEST_XOS_SERVER_ADDRESS = "10.254.1.22"; + private static final int TEST_XOS_SERVER_PORT = 8000; + private static final String XOS_TENANT_BASE_URI = "/xoslib/volttenant/"; + private static final int TEST_XOS_PROVIDER_SERVICE = 1; + + private static final int PRIORITY = 50000; + private static final DeviceId FABRIC_DEVICE_ID = DeviceId.deviceId("of:5e3e486e73000187"); + private static final PortNumber FABRIC_OLT_CONNECT_POINT = PortNumber.portNumber(2); + private static final PortNumber FABRIC_VCPE_CONNECT_POINT = PortNumber.portNumber(3); + private static final String FABRIC_CONTROLLER_ADDRESS = "10.0.3.136"; + private static final int FABRIC_SERVER_PORT = 8181; + private static final String FABRIC_BASE_URI = "/onos/cordfabric/vlans/add"; + + private static final DeviceId OLT_DEVICE_ID = DeviceId.deviceId("of:90e2ba82f97791e9"); + private static final int OLT_UPLINK_PORT = 129; + + private static final ConnectPoint FABRIC_PORT = new ConnectPoint( + DeviceId.deviceId("of:000090e2ba82f974"), + PortNumber.portNumber(2)); + + private final Logger log = getLogger(getClass()); + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected CoreService coreService; + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected ComponentConfigService cfgService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected FlowObjectiveService flowObjectiveService; + + @Property(name = XOS_SERVER_ADDRESS_PROPERTY_NAME, + value = TEST_XOS_SERVER_ADDRESS, + label = "XOS Server address") + protected String xosServerAddress = TEST_XOS_SERVER_ADDRESS; + + @Property(name = XOS_SERVER_PORT_PROPERTY_NAME, + intValue = TEST_XOS_SERVER_PORT, + label = "XOS Server port") + protected int xosServerPort = TEST_XOS_SERVER_PORT; + + @Property(name = XOS_PROVIDER_SERVICE_PROPERTY_NAME, + intValue = TEST_XOS_PROVIDER_SERVICE, + label = "XOS Provider Service") + protected int xosProviderService = TEST_XOS_PROVIDER_SERVICE; + + private ApplicationId appId; + private Map<String, ConnectPoint> nodeToPort; + private Map<Long, Short> portToVlan; + private Map<ConnectPoint, String> portToSsid; + + @Activate + public void activate(ComponentContext context) { + log.info("XOS app is starting"); + cfgService.registerProperties(getClass()); + appId = coreService.registerApplication("org.onosproject.xosintegration"); + + setupMap(); + + readComponentConfiguration(context); + + log.info("XOS({}) started", appId.id()); + } + + @Deactivate + public void deactivate() { + cfgService.unregisterProperties(getClass(), false); + log.info("XOS({}) stopped", appId.id()); + } + + @Modified + public void modified(ComponentContext context) { + readComponentConfiguration(context); + } + + private void setupMap() { + nodeToPort = Maps.newHashMap(); + + nodeToPort.put("cordcompute01.onlab.us", new ConnectPoint(FABRIC_DEVICE_ID, + PortNumber.portNumber(4))); + + nodeToPort.put("cordcompute02.onlab.us", new ConnectPoint(FABRIC_DEVICE_ID, + PortNumber.portNumber(3))); + + portToVlan = Maps.newHashMap(); + portToVlan.putIfAbsent(1L, (short) 201); + portToVlan.putIfAbsent(6L, (short) 401); + + portToSsid = Maps.newHashMap(); + portToSsid.put(new ConnectPoint(OLT_DEVICE_ID, PortNumber.portNumber(1)), "0"); + portToSsid.put(new ConnectPoint(FABRIC_DEVICE_ID, PortNumber.portNumber(6)), "1"); + } + + /** + * Converts a JSON representation of a tenant into a tenant object. + * + * @param jsonTenant JSON object representing the tenant + * @return volt tenant object + */ + private VoltTenant jsonToTenant(JsonObject jsonTenant) { + return VoltTenant.builder() + .withHumanReadableName(jsonTenant.get("humanReadableName").asString()) + .withId(jsonTenant.get("id").asInt()) + .withProviderService(jsonTenant.get("provider_service").asInt()) + .withServiceSpecificId(jsonTenant.get("service_specific_id").asString()) + .withVlanId(jsonTenant.get("vlan_id").asString()) + .build(); + } + + /** + * Converts a tenant object into a JSON string. + * + * @param tenant volt tenant object to convert + * @return JSON string for the tenant + */ + private String tenantToJson(VoltTenant tenant) { + return "{" + + "\"humanReadableName\": \"" + tenant.humanReadableName() + "\"," + + "\"id\": \"" + tenant.id() + "\"," + + "\"provider_service\": \"" + tenant.providerService() + "\"," + + "\"service_specific_id\": \"" + tenant.serviceSpecificId() + "\"," + + "\"vlan_id\": \"" + tenant.vlanId() + "\"" + + "}"; + } + + /** + * Gets a client web resource builder for the base XOS REST API + * with no additional URI. + * + * @return web resource builder + * @deprecated in Cardinal Release + */ + @Deprecated + private WebResource.Builder getClientBuilder() { + return getClientBuilder(""); + } + + /** + * Gets a client web resource builder for the base XOS REST API + * with an optional additional URI. + * + * @return web resource builder + * @deprecated in Cardinal Release + */ + @Deprecated + private WebResource.Builder getClientBuilder(String uri) { + String baseUrl = "http://" + xosServerAddress + ":" + + Integer.toString(xosServerPort); + Client client = Client.create(); + client.addFilter(new HTTPBasicAuthFilter("padmin@vicci.org", "letmein")); + WebResource resource = client.resource(baseUrl + + XOS_TENANT_BASE_URI + uri); + return resource.accept(JSON_UTF_8.toString()) + .type(JSON_UTF_8.toString()); + } + + /** + * Performs a REST GET operation on the base XOS REST URI. + * + * @return JSON string fetched by the GET operation + * @deprecated in Cardinal Release + */ + @Deprecated + private String getRest() { + return getRest(""); + } + + /** + * Performs a REST GET operation on the base XOS REST URI with + * an optional additional URI. + * + * @return JSON string fetched by the GET operation + * @deprecated in Cardinal Release + */ + @Deprecated + private String getRest(String uri) { + WebResource.Builder builder = getClientBuilder(uri); + ClientResponse response = builder.get(ClientResponse.class); + + if (response.getStatus() != HTTP_OK) { + log.info("REST GET request returned error code {}", + response.getStatus()); + } + String jsonString = response.getEntity(String.class); + log.info("JSON read:\n{}", jsonString); + + return jsonString; + } + + /** + * Performs a REST POST operation of a json string on the base + * XOS REST URI with an optional additional URI. + * + * @param json JSON string to post + * @deprecated in Cardinal Release + */ + @Deprecated + private String postRest(String json) { + WebResource.Builder builder = getClientBuilder(); + ClientResponse response; + + try { + response = builder.post(ClientResponse.class, json); + } catch (ClientHandlerException e) { + log.warn("Unable to contact REST server: {}", e.getMessage()); + return "{ 'error' : 'oops no one home' }"; + } + + if (response.getStatus() != HTTP_CREATED) { + log.info("REST POST request returned error code {}", + response.getStatus()); + } + return response.getEntity(String.class); + } + + /** + * Performs a REST DELETE operation on the base + * XOS REST URI with an optional additional URI. + * + * @param uri optional additional URI + * @deprecated in Cardinal Release + */ + @Deprecated + private void deleteRest(String uri) { + WebResource.Builder builder = getClientBuilder(uri); + ClientResponse response = builder.delete(ClientResponse.class); + + if (response.getStatus() != HTTP_NO_CONTENT) { + log.info("REST DELETE request returned error code {}", + response.getStatus()); + } + } + + /** + * Deletes the tenant with the given ID. + * + * @param tenantId ID of tenant to delete + */ + private void deleteTenant(long tenantId) { + deleteRest(Long.toString(tenantId)); + } + + @Override + public Set<VoltTenant> getAllTenants() { + String jsonString = getRest(); + + JsonArray voltTenantItems = JsonArray.readFrom(jsonString); + + return IntStream.range(0, voltTenantItems.size()) + .mapToObj(index -> jsonToTenant(voltTenantItems.get(index).asObject())) + .collect(Collectors.toSet()); + } + + @Override + public void removeTenant(long id) { + deleteTenant(id); + } + + @Override + public VoltTenant addTenant(VoltTenant newTenant) { + long providerServiceId = newTenant.providerService(); + if (providerServiceId == -1) { + providerServiceId = xosProviderService; + } + + PortNumber onuPort = newTenant.port().port(); + VlanId subscriberVlan = VlanId.vlanId(portToVlan.get(onuPort.toLong())); + + VoltTenant tenantToCreate = VoltTenant.builder() + .withProviderService(providerServiceId) + .withServiceSpecificId(portToSsid.get(newTenant.port())) + .withVlanId(String.valueOf(subscriberVlan.toShort())) + .withPort(newTenant.port()) + .build(); + String json = tenantToJson(tenantToCreate); + + + provisionVlanOnPort(OLT_DEVICE_ID, OLT_UPLINK_PORT, onuPort, subscriberVlan.toShort()); + + String retJson = postRest(json); + + fetchCPELocation(tenantToCreate, retJson); + + return newTenant; + } + + private void fetchCPELocation(VoltTenant newTenant, String jsonString) { + JsonObject json = JsonObject.readFrom(jsonString); + + if (json.get("computeNodeName") != null) { + ConnectPoint point = nodeToPort.get(json.get("computeNodeName").asString()); + //ConnectPoint fromPoint = newTenant.port(); + ConnectPoint oltPort = new ConnectPoint(FABRIC_DEVICE_ID, FABRIC_OLT_CONNECT_POINT); + + provisionFabric(VlanId.vlanId(Short.parseShort(newTenant.vlanId())), + point, oltPort); + } + + } + + @Override + public VoltTenant getTenant(long id) { + String jsonString = getRest(Long.toString(id)); + JsonObject jsonTenant = JsonObject.readFrom(jsonString); + if (jsonTenant.get("id") != null) { + return jsonToTenant(jsonTenant); + } else { + return null; + } + } + + private void provisionVlanOnPort(DeviceId deviceId, int uplinkPort, PortNumber p, short vlanId) { + + TrafficSelector upstream = DefaultTrafficSelector.builder() + .matchVlanId(VlanId.ANY) + .matchInPort(p) + .build(); + + TrafficSelector downstream = DefaultTrafficSelector.builder() + .matchVlanId(VlanId.vlanId(vlanId)) + .matchInPort(PortNumber.portNumber(uplinkPort)) + .build(); + + TrafficTreatment upstreamTreatment = DefaultTrafficTreatment.builder() + .setVlanId(VlanId.vlanId(vlanId)) + .setOutput(PortNumber.portNumber(uplinkPort)) + .build(); + + TrafficTreatment downstreamTreatment = DefaultTrafficTreatment.builder() + .popVlan() + .setOutput(p) + .build(); + + + ForwardingObjective upFwd = DefaultForwardingObjective.builder() + .withFlag(ForwardingObjective.Flag.VERSATILE) + .withPriority(1000) + .makePermanent() + .withSelector(upstream) + .fromApp(appId) + .withTreatment(upstreamTreatment) + .add(); + + ForwardingObjective downFwd = DefaultForwardingObjective.builder() + .withFlag(ForwardingObjective.Flag.VERSATILE) + .withPriority(1000) + .makePermanent() + .withSelector(downstream) + .fromApp(appId) + .withTreatment(downstreamTreatment) + .add(); + + flowObjectiveService.forward(deviceId, upFwd); + flowObjectiveService.forward(deviceId, downFwd); + + } + + private void provisionDataPlane(VoltTenant tenant) { + VlanId vlan = VlanId.vlanId(Short.parseShort(tenant.vlanId())); + + TrafficSelector fromGateway = DefaultTrafficSelector.builder() + .matchInPhyPort(tenant.port().port()) + .build(); + + TrafficSelector fromFabric = DefaultTrafficSelector.builder() + .matchInPhyPort(FABRIC_PORT.port()) + .matchVlanId(vlan) + .build(); + + TrafficTreatment toFabric = DefaultTrafficTreatment.builder() + .pushVlan() + .setVlanId(vlan) + .setOutput(FABRIC_PORT.port()) + .build(); + + TrafficTreatment toGateway = DefaultTrafficTreatment.builder() + .popVlan() + .setOutput(tenant.port().port()) + .build(); + + ForwardingObjective forwardToFabric = DefaultForwardingObjective.builder() + .withFlag(ForwardingObjective.Flag.VERSATILE) + .withPriority(PRIORITY) + .makePermanent() + .fromApp(appId) + .withSelector(fromGateway) + .withTreatment(toFabric) + .add(); + + ForwardingObjective forwardToGateway = DefaultForwardingObjective.builder() + .withFlag(ForwardingObjective.Flag.VERSATILE) + .withPriority(PRIORITY) + .makePermanent() + .fromApp(appId) + .withSelector(fromFabric) + .withTreatment(toGateway) + .add(); + + flowObjectiveService.forward(FABRIC_PORT.deviceId(), forwardToFabric); + flowObjectiveService.forward(FABRIC_PORT.deviceId(), forwardToGateway); + } + + private void provisionFabric(VlanId vlanId, ConnectPoint point, ConnectPoint fromPoint) { + + long vlan = vlanId.toShort(); + + JsonObject node = new JsonObject(); + node.add("vlan", vlan); + if (vlan == 201) { + node.add("iptv", true); + } else { + node.add("iptv", false); + } + JsonArray array = new JsonArray(); + JsonObject cp1 = new JsonObject(); + JsonObject cp2 = new JsonObject(); + cp1.add("device", point.deviceId().toString()); + cp1.add("port", point.port().toLong()); + cp2.add("device", fromPoint.deviceId().toString()); + cp2.add("port", fromPoint.port().toLong()); + array.add(cp1); + array.add(cp2); + node.add("ports", array); + + + String baseUrl = "http://" + FABRIC_CONTROLLER_ADDRESS + ":" + + Integer.toString(FABRIC_SERVER_PORT); + Client client = Client.create(); + WebResource resource = client.resource(baseUrl + FABRIC_BASE_URI); + WebResource.Builder builder = resource.accept(JSON_UTF_8.toString()) + .type(JSON_UTF_8.toString()); + + try { + builder.post(ClientResponse.class, node.toString()); + } catch (ClientHandlerException e) { + log.warn("Unable to contact fabric REST server: {}", e.getMessage()); + return; + } + } + + /** + * Extracts properties from the component configuration context. + * + * @param context the component context + */ + private void readComponentConfiguration(ComponentContext context) { + Dictionary<?, ?> properties = context.getProperties(); + + String newXosServerAddress = + Tools.get(properties, XOS_SERVER_ADDRESS_PROPERTY_NAME); + if (!isNullOrEmpty(newXosServerAddress)) { + xosServerAddress = newXosServerAddress; + } + + String newXosServerPortString = + Tools.get(properties, XOS_SERVER_PORT_PROPERTY_NAME); + if (!isNullOrEmpty(newXosServerPortString)) { + xosServerPort = Integer.parseInt(newXosServerPortString); + } + + String newXosProviderServiceString = + Tools.get(properties, XOS_PROVIDER_SERVICE_PROPERTY_NAME); + if (!isNullOrEmpty(newXosProviderServiceString)) { + xosProviderService = Integer.parseInt(newXosProviderServiceString); + } + } +} + + diff --git a/framework/src/onos/apps/xos-integration/src/main/java/org/onosproject/xosintegration/VoltTenant.java b/framework/src/onos/apps/xos-integration/src/main/java/org/onosproject/xosintegration/VoltTenant.java new file mode 100644 index 00000000..6685b7ac --- /dev/null +++ b/framework/src/onos/apps/xos-integration/src/main/java/org/onosproject/xosintegration/VoltTenant.java @@ -0,0 +1,202 @@ +/* + * 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.xosintegration; + +import com.google.common.base.MoreObjects; +import org.onosproject.net.ConnectPoint; + +public final class VoltTenant { + + private final String humanReadableName; + private final long id; + private final long providerService; + private final String serviceSpecificId; + private final String vlanId; + private final ConnectPoint port; + + /** + * Constructs a vOLT tenant object. + * + * @param humanReadableName name string + * @param id identifier for the tenant + * @param providerService provider service ID + * @param serviceSpecificId id for the user + * @param vlanId vlan id for the user + */ + private VoltTenant(String humanReadableName, long id, long providerService, + String serviceSpecificId, String vlanId, ConnectPoint port) { + this.humanReadableName = humanReadableName; + this.id = id; + this.providerService = providerService; + this.serviceSpecificId = serviceSpecificId; + this.vlanId = vlanId; + this.port = port; + } + + /** + * Fetches a builder to make a tenant. + * + * @return tenant builder + */ + public static Builder builder() { + return new Builder(); + } + + /** + * Fetches the name of the tenant. + * + * @return human readable name + */ + public String humanReadableName() { + return humanReadableName; + } + + /** + * Fetches the ID of the tenant object. + * + * @return ID of tenant object. + */ + public long id() { + return id; + } + + /** + * Fetches the identifier for the provider service. + * + * @return provider service ID + */ + public long providerService() { + return providerService; + } + + /** + * Fetches the server specific ID (user id). + * + * @return server specific ID + */ + public String serviceSpecificId() { + return serviceSpecificId; + } + + /** + * Fetches the vlan id for this tenant. + * + * @return VLAN ID + */ + public String vlanId() { + return vlanId; + } + + public ConnectPoint port() { + return port; + } + + /** + * Builder class to allow callers to assemble tenants. + */ + + public static final class Builder { + private String humanReadableName = "unknown"; + private long id = 0; + private long providerService = -1; + private String serviceSpecificId = "unknown"; + private String vlanId = "unknown"; + private ConnectPoint port; + + /** + * Sets the name string for the tenant. + * + * @param humanReadableName name + * @return self + */ + public Builder withHumanReadableName(String humanReadableName) { + this.humanReadableName = humanReadableName; + return this; + } + + /** + * Sets the identifier for the tenant. + * + * @param id identifier for the tenant + * @return self + */ + public Builder withId(long id) { + this.id = id; + return this; + } + + /** + * Sets the server specific id (user id) for the tenant. + * + * @param serviceSpecificId server specific (user) id + * @return self + */ + public Builder withServiceSpecificId(String serviceSpecificId) { + this.serviceSpecificId = serviceSpecificId; + return this; + } + + /** + * Sets the VLAN ID for the tenant. + * + * @param vlanId VLAN ID + * @return self + */ + public Builder withVlanId(String vlanId) { + this.vlanId = vlanId; + return this; + } + + /** + * Sets the provider service ID. + * + * @param providerService provider service ID + * @return self + */ + public Builder withProviderService(long providerService) { + this.providerService = providerService; + return this; + } + + public Builder withPort(ConnectPoint port) { + this.port = port; + return this; + } + + /** + * Constructs a VoltTenant from the assembled data. + * + * @return constructed tenant object + */ + public VoltTenant build() { + return new VoltTenant(humanReadableName, id, providerService, + serviceSpecificId, vlanId, port); + } + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(getClass()) + .add("humanReadableName", humanReadableName()) + .add("id", id()) + .add("providerService", providerService()) + .add("serviceSpecificId", serviceSpecificId()) + .add("vlanId", vlanId()) + .add("port", port()) + .toString(); + } + +} diff --git a/framework/src/onos/apps/xos-integration/src/main/java/org/onosproject/xosintegration/VoltTenantService.java b/framework/src/onos/apps/xos-integration/src/main/java/org/onosproject/xosintegration/VoltTenantService.java new file mode 100644 index 00000000..7cf46ead --- /dev/null +++ b/framework/src/onos/apps/xos-integration/src/main/java/org/onosproject/xosintegration/VoltTenantService.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.xosintegration; + +import java.util.Set; + +public interface VoltTenantService { + + /** + * Queries all the tenants. + * + * @return Set of all of the tenants + */ + Set<VoltTenant> getAllTenants(); + + /** + * Removes a tenant given its ID. + * + * @param id if od tenant to remove. + */ + void removeTenant(long id); + + /** + * Creates a new tenant and adds it to the XOS instance. + * + * @param newTenant tenant to add + * @return the added tenant + */ + VoltTenant addTenant(VoltTenant newTenant); + + /** + * Gets a single tenant for the given ID. + * + * @param id ID of the tenant to fetch + * @return tenant that was fetched + */ + VoltTenant getTenant(long id); +} diff --git a/framework/src/onos/apps/xos-integration/src/main/java/org/onosproject/xosintegration/cli/TenantIdCompleter.java b/framework/src/onos/apps/xos-integration/src/main/java/org/onosproject/xosintegration/cli/TenantIdCompleter.java new file mode 100644 index 00000000..45330799 --- /dev/null +++ b/framework/src/onos/apps/xos-integration/src/main/java/org/onosproject/xosintegration/cli/TenantIdCompleter.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.xosintegration.cli; + +import java.util.List; + +import org.onosproject.cli.AbstractChoicesCompleter; +import org.onosproject.xosintegration.VoltTenant; +import org.onosproject.xosintegration.VoltTenantService; +import static java.util.stream.Collectors.toList; + +import static org.onosproject.cli.AbstractShellCommand.get; + + +/** + * Application command completer. + */ +public class TenantIdCompleter extends AbstractChoicesCompleter { + @Override + public List<String> choices() { + VoltTenantService service = get(VoltTenantService.class); + + return service.getAllTenants().stream() + .map(VoltTenant::id) + .map(Object::toString) + .collect(toList()); + + } + +} diff --git a/framework/src/onos/apps/xos-integration/src/main/java/org/onosproject/xosintegration/cli/VoltRemoveTenantCommand.java b/framework/src/onos/apps/xos-integration/src/main/java/org/onosproject/xosintegration/cli/VoltRemoveTenantCommand.java new file mode 100644 index 00000000..0c44eb5c --- /dev/null +++ b/framework/src/onos/apps/xos-integration/src/main/java/org/onosproject/xosintegration/cli/VoltRemoveTenantCommand.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.xosintegration.cli; + +import org.apache.karaf.shell.commands.Argument; +import org.apache.karaf.shell.commands.Command; +import org.onosproject.cli.AbstractShellCommand; +import org.onosproject.xosintegration.VoltTenantService; + +/** + * CLI command to remove an existing tenant from the system. + */ +@Command(scope = "onos", name = "remove-tenant", + description = "Removes a tenant") +public class VoltRemoveTenantCommand extends AbstractShellCommand { + + @Argument(index = 0, name = "tenant", + description = "Tenant ID", + required = true, multiValued = false) + String tenantIdString = null; + + @Override + protected void execute() { + VoltTenantService service = get(VoltTenantService.class); + + service.removeTenant(Long.parseLong(tenantIdString)); + } +} diff --git a/framework/src/onos/apps/xos-integration/src/main/java/org/onosproject/xosintegration/cli/VoltTenantsCreateCommand.java b/framework/src/onos/apps/xos-integration/src/main/java/org/onosproject/xosintegration/cli/VoltTenantsCreateCommand.java new file mode 100644 index 00000000..3a5b094c --- /dev/null +++ b/framework/src/onos/apps/xos-integration/src/main/java/org/onosproject/xosintegration/cli/VoltTenantsCreateCommand.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.xosintegration.cli; + +import org.apache.karaf.shell.commands.Argument; +import org.apache.karaf.shell.commands.Command; +import org.onosproject.cli.AbstractShellCommand; +import org.onosproject.net.ConnectPoint; +import org.onosproject.xosintegration.VoltTenant; +import org.onosproject.xosintegration.VoltTenantService; + +/** + * CLI command to create a new tenant. + */ +@Command(scope = "onos", name = "add-tenant", + description = "Lists the inventory of VOLT tenants and their contents") +public class VoltTenantsCreateCommand extends AbstractShellCommand { + + @Argument(index = 0, name = "service specific ID", + description = "service specific ID", + required = true, multiValued = false) + String serviceSpecificId; + + @Argument(index = 1, name = "vlan ID", + description = "vlan ID", + required = true, multiValued = false) + String vlanId; + + @Argument(index = 2, name = "port", + description = "Port", + required = true, multiValued = false) + String port; + + @Override + protected void execute() { + VoltTenantService service = get(VoltTenantService.class); + + VoltTenant newTenant = VoltTenant.builder() + .withServiceSpecificId(serviceSpecificId) + .withVlanId(vlanId) + .withPort(ConnectPoint.deviceConnectPoint(port)) + .build(); + + service.addTenant(newTenant); + } +} diff --git a/framework/src/onos/apps/xos-integration/src/main/java/org/onosproject/xosintegration/cli/VoltTenantsListCommand.java b/framework/src/onos/apps/xos-integration/src/main/java/org/onosproject/xosintegration/cli/VoltTenantsListCommand.java new file mode 100644 index 00000000..e1e621bd --- /dev/null +++ b/framework/src/onos/apps/xos-integration/src/main/java/org/onosproject/xosintegration/cli/VoltTenantsListCommand.java @@ -0,0 +1,61 @@ +/* + * 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.xosintegration.cli; + +import java.util.Set; + +import org.apache.karaf.shell.commands.Argument; +import org.apache.karaf.shell.commands.Command; +import org.onosproject.cli.AbstractShellCommand; +import org.onosproject.xosintegration.VoltTenant; +import org.onosproject.xosintegration.VoltTenantService; + +/** + * CLI command for listing VOLT tenant objects. + */ + +/** + * CLI command to list the existing tenants. + */ +@Command(scope = "onos", name = "tenants", + description = "Lists the inventory of VOLT tenants and their contents") +public class VoltTenantsListCommand extends AbstractShellCommand { + + @Argument(index = 0, name = "tenantId", + description = "Tenant ID", + required = false, multiValued = false) + private String tenantId = null; + + @Override + protected void execute() { + VoltTenantService service = get(VoltTenantService.class); + + if (tenantId != null) { + VoltTenant tenant = service.getTenant(Long.parseLong(tenantId)); + if (tenant != null) { + print(tenant.toString()); + } else { + error("Tenant not found {}", tenantId); + } + } else { + Set<VoltTenant> tenants = service.getAllTenants(); + for (VoltTenant tenant : tenants) { + print(tenant.toString()); + } + } + } + +} diff --git a/framework/src/onos/apps/xos-integration/src/main/java/org/onosproject/xosintegration/cli/package-info.java b/framework/src/onos/apps/xos-integration/src/main/java/org/onosproject/xosintegration/cli/package-info.java new file mode 100644 index 00000000..cd7c72ee --- /dev/null +++ b/framework/src/onos/apps/xos-integration/src/main/java/org/onosproject/xosintegration/cli/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. + */ + +/** + * XOS integration application CLI commands. + */ +package org.onosproject.xosintegration.cli;
\ No newline at end of file diff --git a/framework/src/onos/apps/xos-integration/src/main/java/org/onosproject/xosintegration/package-info.java b/framework/src/onos/apps/xos-integration/src/main/java/org/onosproject/xosintegration/package-info.java new file mode 100644 index 00000000..ea2483f9 --- /dev/null +++ b/framework/src/onos/apps/xos-integration/src/main/java/org/onosproject/xosintegration/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. + */ + +/** + * XOS integration application which relies on XOS REST APIs to manage VMs. + */ +package org.onosproject.xosintegration; diff --git a/framework/src/onos/apps/xos-integration/src/main/resources/OSGI-INF/blueprint/shell-config.xml b/framework/src/onos/apps/xos-integration/src/main/resources/OSGI-INF/blueprint/shell-config.xml new file mode 100644 index 00000000..4689be97 --- /dev/null +++ b/framework/src/onos/apps/xos-integration/src/main/resources/OSGI-INF/blueprint/shell-config.xml @@ -0,0 +1,45 @@ +<!-- + ~ 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. + --> +<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"> + <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0"> + <command> + <action class="org.onosproject.xosintegration.cli.VoltTenantsListCommand"/> + <completers> + <ref component-id="tenantIdCompleter"/> + <null/> + </completers> + </command> + <command> + <action class="org.onosproject.xosintegration.cli.VoltTenantsCreateCommand"/> + <completers> + <ref component-id="placeholderCompleter"/> + <ref component-id="placeholderCompleter"/> + <ref component-id="connectPointCompleter"/> + <null/> + </completers> + </command> + <command> + <action class="org.onosproject.xosintegration.cli.VoltRemoveTenantCommand"/> + <completers> + <ref component-id="tenantIdCompleter"/> + <null/> + </completers> + </command> + </command-bundle> + <bean id="tenantIdCompleter" class="org.onosproject.xosintegration.cli.TenantIdCompleter"/> + <bean id="placeholderCompleter" class="org.onosproject.cli.PlaceholderCompleter"/> + <bean id="connectPointCompleter" class="org.onosproject.cli.net.ConnectPointCompleter"/> +</blueprint> |