MVPN RFC6514 Extendend communities
[bgpcep.git] / bgp / path-selection-mode / src / main / java / org / opendaylight / protocol / bgp / mode / impl / BestPathStateImpl.java
1 /*
2  * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.protocol.bgp.mode.impl;
9
10 import static java.util.Objects.requireNonNull;
11
12 import com.google.common.base.MoreObjects;
13 import com.google.common.base.MoreObjects.ToStringHelper;
14 import java.util.List;
15 import org.opendaylight.protocol.bgp.mode.BesthPathStateUtil;
16 import org.opendaylight.protocol.bgp.mode.api.BestPathState;
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev180329.path.attributes.Attributes;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev180329.path.attributes.attributes.as.path.Segments;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.BgpOrigin;
20
21 public final class BestPathStateImpl implements BestPathState {
22     private final Attributes attributes;
23     private long peerAs = 0L;
24     private int asPathLength = 0;
25     private Long localPref;
26     private Long multiExitDisc;
27     private BgpOrigin origin;
28     private boolean resolved;
29
30     public BestPathStateImpl(final Attributes attributes) {
31         this.attributes = requireNonNull(attributes);
32         resolveValues();
33     }
34
35     private static int countAsPath(final List<Segments> segments) {
36         // an AS_SET counts as 1, no matter how many ASs are in the set.
37         int count = 0;
38         boolean setPresent = false;
39         for (final Segments s : segments) {
40             if (s.getAsSet() != null && !setPresent) {
41                 setPresent = true;
42                 count++;
43             } else if (s.getAsSequence() != null) {
44                 count += s.getAsSequence().size();
45             }
46         }
47         return count;
48     }
49
50     private void resolveValues() {
51         if (this.resolved) {
52             return;
53         }
54
55         if (this.attributes.getLocalPref() != null) {
56             this.localPref = this.attributes.getLocalPref().getPref();
57         } else {
58             this.localPref = null;
59         }
60
61         if (this.attributes.getMultiExitDisc() != null) {
62             this.multiExitDisc = this.attributes.getMultiExitDisc().getMed();
63         } else {
64             this.multiExitDisc = null;
65         }
66
67         if (this.attributes.getOrigin() != null) {
68             this.origin = this.attributes.getOrigin().getValue();
69         } else {
70             this.origin = null;
71         }
72         if (this.attributes.getAsPath() != null) {
73             final List<Segments> segs = this.attributes.getAsPath().getSegments();
74             if (segs != null && !segs.isEmpty()) {
75                 this.peerAs = BesthPathStateUtil.getPeerAs(segs);
76                 this.asPathLength = countAsPath(segs);
77             }
78         }
79         this.resolved = true;
80     }
81
82     @Override
83     public Long getLocalPref() {
84         resolveValues();
85         return this.localPref;
86     }
87
88     @Override
89     public Long getMultiExitDisc() {
90         resolveValues();
91         return this.multiExitDisc;
92     }
93
94     @Override
95     public BgpOrigin getOrigin() {
96         resolveValues();
97         return this.origin;
98     }
99
100     @Override
101     public long getPeerAs() {
102         resolveValues();
103         return this.peerAs;
104     }
105
106     @Override
107     public int getAsPathLength() {
108         resolveValues();
109         return this.asPathLength;
110     }
111
112     @Override
113     public Attributes getAttributes() {
114         return this.attributes;
115     }
116
117     private ToStringHelper addToStringAttributes(final ToStringHelper toStringHelper) {
118         toStringHelper.add("attributes", this.attributes);
119         toStringHelper.add("localPref", this.localPref);
120         toStringHelper.add("multiExitDisc", this.multiExitDisc);
121         toStringHelper.add("origin", this.origin);
122         toStringHelper.add("resolved", this.resolved);
123         return toStringHelper;
124     }
125
126     @Override
127     public String toString() {
128         return addToStringAttributes(MoreObjects.toStringHelper(this)).toString();
129     }
130
131     @Override
132     public int hashCode() {
133         final int prime = 31;
134         int result = 1;
135         result = prime * result + this.attributes.hashCode();
136         result = prime * result + (this.localPref == null ? 0 : this.localPref.hashCode());
137         result = prime * result + (this.multiExitDisc == null ? 0 : this.multiExitDisc.hashCode());
138         result = prime * result + (this.origin == null ? 0 : this.origin.hashCode());
139         return result;
140     }
141
142     @Override
143     public boolean equals(final Object obj) {
144         if (this == obj) {
145             return true;
146         }
147         if (!(obj instanceof BestPathStateImpl)) {
148             return false;
149         }
150         final BestPathStateImpl other = (BestPathStateImpl) obj;
151         if (!this.attributes.equals(other.attributes)) {
152             return false;
153         }
154         if (this.localPref == null) {
155             if (other.localPref != null) {
156                 return false;
157             }
158         } else if (!this.localPref.equals(other.localPref)) {
159             return false;
160         }
161         if (this.multiExitDisc == null) {
162             if (other.multiExitDisc != null) {
163                 return false;
164             }
165         } else if (!this.multiExitDisc.equals(other.multiExitDisc)) {
166             return false;
167         }
168         if (this.origin != other.origin) {
169             return false;
170         }
171         return true;
172     }
173 }