blob: 6085c60a71272272dc3ee75dea142d47828b058c [file] [log] [blame]
Jonathan Hart4cb39882015-08-12 23:50:55 -04001/*
2 * Copyright 2015 Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package org.onosproject.routing.config;
18
19import com.fasterxml.jackson.databind.JsonNode;
papazois7d39a742015-10-14 10:15:56 +030020import com.fasterxml.jackson.databind.node.ArrayNode;
21import com.fasterxml.jackson.databind.node.JsonNodeFactory;
22import com.fasterxml.jackson.databind.node.ObjectNode;
Jonathan Hart4cb39882015-08-12 23:50:55 -040023import com.google.common.collect.Sets;
24import org.onlab.packet.IpAddress;
25import org.onosproject.core.ApplicationId;
Jonathan Hart4cb39882015-08-12 23:50:55 -040026import org.onosproject.net.ConnectPoint;
Jonathan Harta8625482015-09-08 16:14:56 -070027import org.onosproject.net.config.Config;
Jonathan Hart4cb39882015-08-12 23:50:55 -040028
papazois7d39a742015-10-14 10:15:56 +030029import java.util.Objects;
Jonathan Harta8625482015-09-08 16:14:56 -070030import java.util.Optional;
Jonathan Hart4cb39882015-08-12 23:50:55 -040031import java.util.Set;
32
33import static com.google.common.base.Preconditions.checkNotNull;
34
35/**
36 * Configuration object for BGP config.
37 */
38public class BgpConfig extends Config<ApplicationId> {
39
40 public static final String SPEAKERS = "bgpSpeakers";
41 public static final String CONNECT_POINT = "connectPoint";
Jonathan Harta8625482015-09-08 16:14:56 -070042 public static final String NAME = "name";
Jonathan Hart4cb39882015-08-12 23:50:55 -040043 public static final String PEERS = "peers";
44
45 // TODO add methods for updating config
46
47 /**
48 * Gets the set of configured BGP speakers.
49 *
50 * @return BGP speakers
51 */
52 public Set<BgpSpeakerConfig> bgpSpeakers() {
53 Set<BgpSpeakerConfig> speakers = Sets.newHashSet();
54
Thomas Vachuska0a400ea2015-09-04 11:25:03 -070055 JsonNode speakersNode = object.get(SPEAKERS);
papazois7d39a742015-10-14 10:15:56 +030056
57 if (speakersNode == null) {
58 return speakers;
59 }
60
Jonathan Hart4cb39882015-08-12 23:50:55 -040061 speakersNode.forEach(jsonNode -> {
62 Set<IpAddress> listenAddresses = Sets.newHashSet();
63 jsonNode.path(PEERS).forEach(addressNode ->
Jonathan Harta8625482015-09-08 16:14:56 -070064 listenAddresses.add(IpAddress.valueOf(addressNode.asText()))
Jonathan Hart4cb39882015-08-12 23:50:55 -040065 );
Jonathan Harta8625482015-09-08 16:14:56 -070066
67 Optional<String> name;
68 if (jsonNode.get(NAME) == null) {
69 name = Optional.empty();
70 } else {
71 name = Optional.of(jsonNode.get(NAME).asText());
72 }
73
74 speakers.add(new BgpSpeakerConfig(name,
Jonathan Hart4cb39882015-08-12 23:50:55 -040075 ConnectPoint.deviceConnectPoint(jsonNode.path(CONNECT_POINT).asText()),
76 listenAddresses));
77 });
78
79 return speakers;
80 }
81
82 /**
papazois7d39a742015-10-14 10:15:56 +030083 * Examines whether a name of BGP speaker exists in configuration.
84 *
85 * @param name name of BGP speaker being search
86 * @return speaker
87 */
88 public BgpSpeakerConfig getSpeakerWithName(String name) {
89 for (BgpConfig.BgpSpeakerConfig speaker : bgpSpeakers()) {
90 if (speaker.name().isPresent() && speaker.name().get().equals(name)) {
91 return speaker;
92 }
93 }
94 return null;
95 }
96
97 /**
98 * Adds BGP speaker to configuration.
99 *
100 * @param speaker BGP speaker configuration entry
101 */
102 public void addSpeaker(BgpSpeakerConfig speaker) {
103 ObjectNode speakerNode = JsonNodeFactory.instance.objectNode();
104
105 speakerNode.put(NAME, speaker.name().get());
106
107 speakerNode.put(CONNECT_POINT, speaker.connectPoint().elementId().toString()
108 + "/" + speaker.connectPoint().port().toString());
109
110 ArrayNode peersNode = speakerNode.putArray(PEERS);
111 for (IpAddress peerAddress: speaker.peers()) {
112 peersNode.add(peerAddress.toString());
113 }
114
115 ArrayNode speakersArray = bgpSpeakers().isEmpty() ?
116 initBgpConfiguration() : (ArrayNode) object.get(SPEAKERS);
117 speakersArray.add(speakerNode);
118 }
119
120 /**
121 * Removes BGP speaker from configuration.
122 *
123 * @param speakerName BGP speaker name
124 */
125 public void removeSpeaker(String speakerName) {
126 ArrayNode speakersArray = (ArrayNode) object.get(SPEAKERS);
127
128 for (int i = 0; i < speakersArray.size(); i++) {
129 if (speakersArray.get(i).hasNonNull(NAME) &&
130 speakersArray.get(i).get(NAME).asText().equals(speakerName)) {
131 speakersArray.remove(i);
132 return;
133 }
134 }
135 }
136
137 /**
138 * Adds peering address to BGP speaker.
139 *
140 * @param speakerName name of BGP speaker
141 * @param peerAddress peering address to be added
142 */
143 public void addPeerToSpeaker(String speakerName, IpAddress peerAddress) {
144 JsonNode speakersNode = object.get(SPEAKERS);
145 speakersNode.forEach(jsonNode -> {
146 if (jsonNode.hasNonNull(NAME) &&
147 jsonNode.get(NAME).asText().equals(speakerName)) {
148 ArrayNode peersNode = (ArrayNode) jsonNode.get(PEERS);
149 for (int i = 0; i < peersNode.size(); i++) {
150 if (peersNode.get(i).asText().equals(peerAddress.toString())) {
151 return; // Peer already exists.
152 }
153 }
154 peersNode.add(peerAddress.toString());
155 }
156 });
157 }
158
159 /**
160 * Finds BGP speaker peering with a given external peer.
161 *
162 * @param peerAddress peering address to be removed
163 * @return speaker
164 */
165 public BgpSpeakerConfig getSpeakerFromPeer(IpAddress peerAddress) {
166 for (BgpConfig.BgpSpeakerConfig speaker : bgpSpeakers()) {
167 if (speaker.peers().contains(peerAddress)) {
168 return speaker;
169 }
170 }
171 return null;
172 }
173
174 /**
175 * Removes peering address from BGP speaker.
176 *
177 * @param speaker BGP speaker configuration entries
178 * @param peerAddress peering address to be removed
179 */
180 public void removePeerFromSpeaker(BgpSpeakerConfig speaker, IpAddress peerAddress) {
181 JsonNode speakersNode = object.get(SPEAKERS);
182 speakersNode.forEach(jsonNode -> {
183 if (jsonNode.hasNonNull(NAME) &&
184 jsonNode.get(NAME).asText().equals(speaker.name().get())) {
185 ArrayNode peersNode = (ArrayNode) jsonNode.get(PEERS);
186 for (int i = 0; i < peersNode.size(); i++) {
187 if (peersNode.get(i).asText().equals(peerAddress.toString())) {
188 peersNode.remove(i);
189 return;
190 }
191 }
192 }
193 });
194 }
195
196 /**
197 * Creates empty configuration for BGP speakers.
198 *
199 * @return empty array of BGP speakers
200 */
201 private ArrayNode initBgpConfiguration() {
202 return object.putArray(SPEAKERS);
203 }
204
205
206 /**
Jonathan Hart4cb39882015-08-12 23:50:55 -0400207 * Configuration for a BGP speaker.
208 */
209 public static class BgpSpeakerConfig {
210
Jonathan Harta8625482015-09-08 16:14:56 -0700211 private Optional<String> name;
Jonathan Hart4cb39882015-08-12 23:50:55 -0400212 private ConnectPoint connectPoint;
213 private Set<IpAddress> peers;
214
Jonathan Harta8625482015-09-08 16:14:56 -0700215 public BgpSpeakerConfig(Optional<String> name, ConnectPoint connectPoint,
216 Set<IpAddress> peers) {
217 this.name = checkNotNull(name);
Jonathan Hart4cb39882015-08-12 23:50:55 -0400218 this.connectPoint = checkNotNull(connectPoint);
219 this.peers = checkNotNull(peers);
220 }
221
Jonathan Harta8625482015-09-08 16:14:56 -0700222 public Optional<String> name() {
223 return name;
224 }
225
Jonathan Hart4cb39882015-08-12 23:50:55 -0400226 public ConnectPoint connectPoint() {
227 return connectPoint;
228 }
229
230 public Set<IpAddress> peers() {
231 return peers;
232 }
papazois7d39a742015-10-14 10:15:56 +0300233
234 /**
235 * Examines if BGP peer is connected.
236 *
237 * @param peer IP address of peer
238 * @return result of search
239 */
240 public boolean isConnectedToPeer(IpAddress peer) {
241 for (final IpAddress entry : peers()) {
242 if (entry.equals(peer)) {
243 return true;
244 }
245 }
246 return false;
247 }
248
249 @Override
250 public boolean equals(Object obj) {
251 if (this == obj) {
252 return true;
253 }
254 if (obj instanceof BgpSpeakerConfig) {
255 final BgpSpeakerConfig that = (BgpSpeakerConfig) obj;
256 return Objects.equals(this.name, that.name) &&
257 Objects.equals(this.connectPoint, that.connectPoint) &&
258 Objects.equals(this.peers, that.peers);
259 }
260 return false;
261 }
262
263 @Override
264 public int hashCode() {
265 return Objects.hash(name, connectPoint, peers);
266 }
Jonathan Hart4cb39882015-08-12 23:50:55 -0400267 }
268}