blob: 8b8d1707e80b778acbf0851404a7e973c5c51451 [file] [log] [blame]
Aaron Kruglikov17b4c852016-01-15 16:37:04 -08001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2016-present Open Networking Laboratory
Aaron Kruglikov17b4c852016-01-15 16:37:04 -08003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package org.onosproject.drivers.fujitsu;
18
Andrea Campanella6c71a052016-04-22 11:56:31 -070019import com.google.common.collect.ImmutableList;
20import com.google.common.collect.Lists;
HIGUCHI Yutadbb631f2016-05-16 16:18:10 -070021import org.apache.commons.configuration.HierarchicalConfiguration;
Aaron Kruglikov17b4c852016-01-15 16:37:04 -080022import org.onosproject.drivers.utilities.XmlConfigParser;
HIGUCHI Yutadbb631f2016-05-16 16:18:10 -070023import org.onosproject.net.AnnotationKeys;
24import org.onosproject.net.ChannelSpacing;
25import org.onosproject.net.CltSignalType;
26import org.onosproject.net.DefaultAnnotations;
27import org.onosproject.net.GridType;
28import org.onosproject.net.OchSignal;
29import org.onosproject.net.OduSignalType;
30import org.onosproject.net.PortNumber;
Andrea Campanella6c71a052016-04-22 11:56:31 -070031import org.onosproject.net.device.DeviceDescription;
32import org.onosproject.net.device.DeviceDescriptionDiscovery;
Aaron Kruglikov17b4c852016-01-15 16:37:04 -080033import org.onosproject.net.device.PortDescription;
34import org.onosproject.net.driver.AbstractHandlerBehaviour;
35import org.onosproject.netconf.NetconfController;
36import org.onosproject.netconf.NetconfException;
37import org.onosproject.netconf.NetconfSession;
38import org.slf4j.Logger;
39
40import java.io.ByteArrayInputStream;
41import java.io.IOException;
42import java.util.List;
HIGUCHI Yutadbb631f2016-05-16 16:18:10 -070043import java.util.concurrent.atomic.AtomicInteger;
Aaron Kruglikov17b4c852016-01-15 16:37:04 -080044
45import static com.google.common.base.Preconditions.checkNotNull;
HIGUCHI Yutadbb631f2016-05-16 16:18:10 -070046import static org.onosproject.net.optical.device.OchPortHelper.ochPortDescription;
47import static org.onosproject.net.optical.device.OduCltPortHelper.oduCltPortDescription;
Aaron Kruglikov17b4c852016-01-15 16:37:04 -080048import static org.slf4j.LoggerFactory.getLogger;
49
50/**
51 * Retrieves the ports from a Fujitsu T100 device via netconf.
52 */
Andrea Campanella6c71a052016-04-22 11:56:31 -070053public class FujitsuT100DeviceDescription extends AbstractHandlerBehaviour
54 implements DeviceDescriptionDiscovery {
Aaron Kruglikov17b4c852016-01-15 16:37:04 -080055
56 private final Logger log = getLogger(getClass());
57
58 @Override
Andrea Campanella6c71a052016-04-22 11:56:31 -070059 public DeviceDescription discoverDeviceDetails() {
60 log.info("No description to be added for device");
61 //TODO to be implemented if needed.
62 return null;
63 }
64
65 @Override
66 public List<PortDescription> discoverPortDetails() {
Aaron Kruglikov17b4c852016-01-15 16:37:04 -080067 NetconfController controller = checkNotNull(handler().get(NetconfController.class));
68 NetconfSession session = controller.getDevicesMap().get(handler().data().deviceId()).getSession();
69 String reply;
70 try {
71 reply = session.get(requestBuilder());
72 } catch (IOException e) {
73 throw new RuntimeException(new NetconfException("Failed to retrieve configuration.", e));
74 }
HIGUCHI Yutadbb631f2016-05-16 16:18:10 -070075 List<PortDescription> descriptions =
Aaron Kruglikov17b4c852016-01-15 16:37:04 -080076 parseFujitsuT100Ports(XmlConfigParser.
77 loadXml(new ByteArrayInputStream(reply.getBytes())));
Andrea Campanella6c71a052016-04-22 11:56:31 -070078 return ImmutableList.copyOf(descriptions);
Aaron Kruglikov17b4c852016-01-15 16:37:04 -080079 }
80
81 /**
82 * Builds a request crafted to get the configuration required to create port
83 * descriptions for the device.
Andrea Campanella6c71a052016-04-22 11:56:31 -070084 *
Aaron Kruglikov17b4c852016-01-15 16:37:04 -080085 * @return The request string.
86 */
87 private String requestBuilder() {
88 StringBuilder rpc = new StringBuilder("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
89 //Message ID is injected later.
90 rpc.append("<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">");
91 rpc.append("<get>");
92 rpc.append("<filter type=\"subtree\">");
93 rpc.append("<interfaces xmlns=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\">");
94 rpc.append("</interfaces>");
95 rpc.append("</filter>");
96 rpc.append("</get>");
97 rpc.append("</rpc>");
98 return rpc.toString();
99 }
HIGUCHI Yutadbb631f2016-05-16 16:18:10 -0700100
101 /**
102 * Parses a configuration and returns a set of ports for the fujitsu T100.
Andrea Campanella6c71a052016-04-22 11:56:31 -0700103 *
HIGUCHI Yutadbb631f2016-05-16 16:18:10 -0700104 * @param cfg a hierarchical configuration
105 * @return a list of port descriptions
106 */
107 private static List<PortDescription> parseFujitsuT100Ports(HierarchicalConfiguration cfg) {
108 AtomicInteger counter = new AtomicInteger(1);
109 List<PortDescription> portDescriptions = Lists.newArrayList();
110 List<HierarchicalConfiguration> subtrees =
111 cfg.configurationsAt("data.interfaces.interface");
112 for (HierarchicalConfiguration portConfig : subtrees) {
113 if (!portConfig.getString("name").contains("LCN") &&
114 !portConfig.getString("name").contains("LMP") &&
115 portConfig.getString("type").equals("ianaift:ethernetCsmacd")) {
116 portDescriptions.add(parseT100OduPort(portConfig, counter.getAndIncrement()));
117 } else if (portConfig.getString("type").equals("ianaift:otnOtu")) {
118 portDescriptions.add(parseT100OchPort(portConfig, counter.getAndIncrement()));
119 }
120 }
121 return portDescriptions;
122 }
123
124 private static PortDescription parseT100OchPort(HierarchicalConfiguration cfg, long count) {
125 PortNumber portNumber = PortNumber.portNumber(count);
126 HierarchicalConfiguration otuConfig = cfg.configurationAt("otu");
127 boolean enabled = otuConfig.getString("administrative-state").equals("up");
128 OduSignalType signalType = otuConfig.getString("rate").equals("OTU4") ? OduSignalType.ODU4 : null;
129 //Unsure how to retreive, outside knowledge it is tunable.
130 boolean isTunable = true;
131 OchSignal lambda = new OchSignal(GridType.DWDM, ChannelSpacing.CHL_50GHZ, 0, 4);
132 DefaultAnnotations annotations = DefaultAnnotations.builder().
133 set(AnnotationKeys.PORT_NAME, cfg.getString("name")).
134 build();
135 return ochPortDescription(portNumber, enabled, signalType, isTunable, lambda, annotations);
136 }
137
138 private static PortDescription parseT100OduPort(HierarchicalConfiguration cfg, long count) {
139 PortNumber portNumber = PortNumber.portNumber(count);
140 HierarchicalConfiguration ethernetConfig = cfg.configurationAt("ethernet");
141 boolean enabled = ethernetConfig.getString("administrative-state").equals("up");
142 //Rate is in kbps
143 CltSignalType signalType = ethernetConfig.getString("rate").equals("100000000") ?
144 CltSignalType.CLT_100GBE : null;
145 DefaultAnnotations annotations = DefaultAnnotations.builder().
146 set(AnnotationKeys.PORT_NAME, cfg.getString("name")).
147 build();
148 return oduCltPortDescription(portNumber, enabled, signalType, annotations);
149 }
150
Aaron Kruglikov17b4c852016-01-15 16:37:04 -0800151}