blob: dc1cc81c35937ad80073e6a0f8d464df4b37efc5 [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
Jonathan Hart4cb39882015-08-12 23:50:55 -040045 /**
46 * Gets the set of configured BGP speakers.
47 *
48 * @return BGP speakers
49 */
50 public Set<BgpSpeakerConfig> bgpSpeakers() {
51 Set<BgpSpeakerConfig> speakers = Sets.newHashSet();
52
Thomas Vachuska0a400ea2015-09-04 11:25:03 -070053 JsonNode speakersNode = object.get(SPEAKERS);
papazois7d39a742015-10-14 10:15:56 +030054
55 if (speakersNode == null) {
56 return speakers;
57 }
58
Jonathan Hart4cb39882015-08-12 23:50:55 -040059 speakersNode.forEach(jsonNode -> {
60 Set<IpAddress> listenAddresses = Sets.newHashSet();
61 jsonNode.path(PEERS).forEach(addressNode ->
Jonathan Harta8625482015-09-08 16:14:56 -070062 listenAddresses.add(IpAddress.valueOf(addressNode.asText()))
Jonathan Hart4cb39882015-08-12 23:50:55 -040063 );
Jonathan Harta8625482015-09-08 16:14:56 -070064
65 Optional<String> name;
66 if (jsonNode.get(NAME) == null) {
67 name = Optional.empty();
68 } else {
69 name = Optional.of(jsonNode.get(NAME).asText());
70 }
71
72 speakers.add(new BgpSpeakerConfig(name,
Jonathan Hart4cb39882015-08-12 23:50:55 -040073 ConnectPoint.deviceConnectPoint(jsonNode.path(CONNECT_POINT).asText()),
74 listenAddresses));
75 });
76
77 return speakers;
78 }
79
80 /**
papazois7d39a742015-10-14 10:15:56 +030081 * Examines whether a name of BGP speaker exists in configuration.
82 *
83 * @param name name of BGP speaker being search
84 * @return speaker
85 */
86 public BgpSpeakerConfig getSpeakerWithName(String name) {
87 for (BgpConfig.BgpSpeakerConfig speaker : bgpSpeakers()) {
Sho SHIMIZUef7e2902016-02-12 18:38:29 -080088 if (speaker.name().filter(name::equals).isPresent()) {
papazois7d39a742015-10-14 10:15:56 +030089 return speaker;
90 }
91 }
92 return null;
93 }
94
95 /**
96 * Adds BGP speaker to configuration.
97 *
98 * @param speaker BGP speaker configuration entry
99 */
100 public void addSpeaker(BgpSpeakerConfig speaker) {
101 ObjectNode speakerNode = JsonNodeFactory.instance.objectNode();
102
103 speakerNode.put(NAME, speaker.name().get());
104
105 speakerNode.put(CONNECT_POINT, speaker.connectPoint().elementId().toString()
106 + "/" + speaker.connectPoint().port().toString());
107
108 ArrayNode peersNode = speakerNode.putArray(PEERS);
109 for (IpAddress peerAddress: speaker.peers()) {
110 peersNode.add(peerAddress.toString());
111 }
112
113 ArrayNode speakersArray = bgpSpeakers().isEmpty() ?
114 initBgpConfiguration() : (ArrayNode) object.get(SPEAKERS);
115 speakersArray.add(speakerNode);
116 }
117
118 /**
119 * Removes BGP speaker from configuration.
120 *
121 * @param speakerName BGP speaker name
122 */
123 public void removeSpeaker(String speakerName) {
124 ArrayNode speakersArray = (ArrayNode) object.get(SPEAKERS);
125
126 for (int i = 0; i < speakersArray.size(); i++) {
127 if (speakersArray.get(i).hasNonNull(NAME) &&
128 speakersArray.get(i).get(NAME).asText().equals(speakerName)) {
129 speakersArray.remove(i);
130 return;
131 }
132 }
133 }
134
135 /**
136 * Adds peering address to BGP speaker.
137 *
138 * @param speakerName name of BGP speaker
139 * @param peerAddress peering address to be added
140 */
141 public void addPeerToSpeaker(String speakerName, IpAddress peerAddress) {
142 JsonNode speakersNode = object.get(SPEAKERS);
143 speakersNode.forEach(jsonNode -> {
144 if (jsonNode.hasNonNull(NAME) &&
145 jsonNode.get(NAME).asText().equals(speakerName)) {
146 ArrayNode peersNode = (ArrayNode) jsonNode.get(PEERS);
147 for (int i = 0; i < peersNode.size(); i++) {
148 if (peersNode.get(i).asText().equals(peerAddress.toString())) {
149 return; // Peer already exists.
150 }
151 }
152 peersNode.add(peerAddress.toString());
153 }
154 });
155 }
156
157 /**
158 * Finds BGP speaker peering with a given external peer.
159 *
160 * @param peerAddress peering address to be removed
161 * @return speaker
162 */
163 public BgpSpeakerConfig getSpeakerFromPeer(IpAddress peerAddress) {
164 for (BgpConfig.BgpSpeakerConfig speaker : bgpSpeakers()) {
165 if (speaker.peers().contains(peerAddress)) {
166 return speaker;
167 }
168 }
169 return null;
170 }
171
172 /**
173 * Removes peering address from BGP speaker.
174 *
175 * @param speaker BGP speaker configuration entries
176 * @param peerAddress peering address to be removed
177 */
178 public void removePeerFromSpeaker(BgpSpeakerConfig speaker, IpAddress peerAddress) {
179 JsonNode speakersNode = object.get(SPEAKERS);
180 speakersNode.forEach(jsonNode -> {
181 if (jsonNode.hasNonNull(NAME) &&
182 jsonNode.get(NAME).asText().equals(speaker.name().get())) {
183 ArrayNode peersNode = (ArrayNode) jsonNode.get(PEERS);
184 for (int i = 0; i < peersNode.size(); i++) {
185 if (peersNode.get(i).asText().equals(peerAddress.toString())) {
186 peersNode.remove(i);
187 return;
188 }
189 }
190 }
191 });
192 }
193
194 /**
195 * Creates empty configuration for BGP speakers.
196 *
197 * @return empty array of BGP speakers
198 */
199 private ArrayNode initBgpConfiguration() {
200 return object.putArray(SPEAKERS);
201 }
202
203
204 /**
Jonathan Hart4cb39882015-08-12 23:50:55 -0400205 * Configuration for a BGP speaker.
206 */
207 public static class BgpSpeakerConfig {
208
Jonathan Harta8625482015-09-08 16:14:56 -0700209 private Optional<String> name;
Jonathan Hart4cb39882015-08-12 23:50:55 -0400210 private ConnectPoint connectPoint;
211 private Set<IpAddress> peers;
212
Jonathan Harta8625482015-09-08 16:14:56 -0700213 public BgpSpeakerConfig(Optional<String> name, ConnectPoint connectPoint,
214 Set<IpAddress> peers) {
215 this.name = checkNotNull(name);
Jonathan Hart4cb39882015-08-12 23:50:55 -0400216 this.connectPoint = checkNotNull(connectPoint);
217 this.peers = checkNotNull(peers);
218 }
219
Jonathan Harta8625482015-09-08 16:14:56 -0700220 public Optional<String> name() {
221 return name;
222 }
223
Jonathan Hart4cb39882015-08-12 23:50:55 -0400224 public ConnectPoint connectPoint() {
225 return connectPoint;
226 }
227
228 public Set<IpAddress> peers() {
229 return peers;
230 }
papazois7d39a742015-10-14 10:15:56 +0300231
232 /**
233 * Examines if BGP peer is connected.
234 *
235 * @param peer IP address of peer
236 * @return result of search
237 */
238 public boolean isConnectedToPeer(IpAddress peer) {
239 for (final IpAddress entry : peers()) {
240 if (entry.equals(peer)) {
241 return true;
242 }
243 }
244 return false;
245 }
246
247 @Override
248 public boolean equals(Object obj) {
249 if (this == obj) {
250 return true;
251 }
252 if (obj instanceof BgpSpeakerConfig) {
253 final BgpSpeakerConfig that = (BgpSpeakerConfig) obj;
254 return Objects.equals(this.name, that.name) &&
255 Objects.equals(this.connectPoint, that.connectPoint) &&
256 Objects.equals(this.peers, that.peers);
257 }
258 return false;
259 }
260
261 @Override
262 public int hashCode() {
263 return Objects.hash(name, connectPoint, peers);
264 }
Jonathan Hart4cb39882015-08-12 23:50:55 -0400265 }
266}