1 /**
2 * Licensed to jclouds, Inc. (jclouds) under one or more
3 * contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. jclouds licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19 package org.jclouds.cloudloadbalancers.domain;
20
21 import static com.google.common.base.Preconditions.checkArgument;
22 import static com.google.common.base.Preconditions.checkNotNull;
23
24 import org.jclouds.cloudloadbalancers.domain.internal.BaseNode;
25
26 /**
27 * The nodes defined by the load balancer are responsible for servicing the requests received
28 * through the load balancer's virtual IP. By default, the load balancer employs a basic health
29 * check that ensures the node is listening on its defined port. The node is checked at the time of
30 * addition and at regular intervals as defined by the load balancer health check configuration. If
31 * a back-end node is not listening on its port or does not meet the conditions of the defined
32 * active health check for the load balancer, then the load balancer will not forward connections
33 * and its status will be listed as OFFLINE. Only nodes that are in an ONLINE status will receive
34 * and be able to service traffic from the load balancer.
35 * <p/>
36 * All nodes have an associated status that indicates whether the node is ONLINE, OFFLINE, or
37 * DRAINING. Only nodes that are in ONLINE status will receive and be able to service traffic from
38 * the load balancer. The OFFLINE status represents a node that cannot accept or service traffic. A
39 * node in DRAINING status represents a node that stops the traffic manager from sending any
40 * additional new connections to the node, but honors established sessions. If the traffic manager
41 * receives a request and session persistence requires that the node is used, the traffic manager
42 * will use it. The status is determined by the passive or active health monitors.
43 * <p/>
44 * If the WEIGHTED_ROUND_ROBIN load balancer algorithm mode is selected, then the caller should
45 * assign the relevant weights to the node as part of the weight attribute of the node element. When
46 * the algorithm of the load balancer is changed to WEIGHTED_ROUND_ROBIN and the nodes do not
47 * already have an assigned weight, the service will automatically set the weight to "1" for all
48 * nodes.
49 *
50 * @author Adrian Cole
51 * @see <a href=
52 * "http://docs.rackspacecloud.com/loadbalancers/api/v1.0/clb-devguide/content/ch04s02.html" />
53 */
54 public class Node extends BaseNode<Node> {
55
56 @SuppressWarnings("unchecked")
57 public static Builder builder() {
58 return new Builder();
59 }
60
61 /**
62 * {@inheritDoc}
63 */
64 @Override
65 public Builder toBuilder() {
66 return new Builder().from(this);
67 }
68
69 public static class Builder extends BaseNode.Builder<Node> {
70 private int id = -1;
71 private Status status;
72
73 public Builder id(int id) {
74 this.id = id;
75 return this;
76 }
77
78 public Builder status(Status status) {
79 this.status = status;
80 return this;
81 }
82
83 @Override
84 public Node build() {
85 return new Node(id, address, port, condition, status, weight);
86 }
87
88 @Override
89 public Builder address(String address) {
90 return Builder.class.cast(super.address(address));
91 }
92
93 @Override
94 public Builder condition(Condition condition) {
95 return Builder.class.cast(super.condition(condition));
96 }
97
98 @Override
99 public Builder from(Node in) {
100 return Builder.class.cast(super.from(in)).id(in.getId()).status(in.getStatus());
101 }
102
103 @Override
104 public Builder port(int port) {
105 return Builder.class.cast(super.port(port));
106 }
107
108 @Override
109 public Builder weight(Integer weight) {
110 return Builder.class.cast(super.weight(weight));
111 }
112
113 }
114
115 /**
116 * The status is determined by the passive or active health monitors.
117 *
118 */
119 public static enum Status {
120 /**
121 * Only nodes that are in an ONLINE status will receive and be able to service traffic from
122 * the load balancer.
123 */
124 ONLINE,
125
126 /**
127 * represents a node that cannot accept or service traffic
128 */
129 OFFLINE,
130
131 /**
132 * represents a node that stops the traffic manager from sending any additional new
133 * connections to the node, but honors established sessions.
134 */
135 DRAINING,
136
137 UNRECOGNIZED;
138
139 public static Status fromValue(String status) {
140 try {
141 return valueOf(checkNotNull(status, "status"));
142 } catch (IllegalArgumentException e) {
143 return UNRECOGNIZED;
144 }
145 }
146
147 }
148
149 private int id;
150 private Status status;
151
152 // for serialization only
153 Node() {
154
155 }
156
157 public Node(int id, String address, int port, Condition condition, Status status, Integer weight) {
158 super(address, port, condition, weight);
159 checkArgument(id != -1, "id must be specified");
160 this.id = id;
161 this.status = checkNotNull(status, "status");
162 }
163
164 public int getId() {
165 return id;
166 }
167
168 public Status getStatus() {
169 return status;
170 }
171
172 @Override
173 public String toString() {
174 return String.format("[id=%s, address=%s, condition=%s, port=%s, weight=%s,status=%s]", id, address, condition,
175 port, weight, status);
176 }
177
178 @Override
179 public int hashCode() {
180 final int prime = 31;
181 int result = super.hashCode();
182 result = prime * result + id;
183 return result;
184 }
185
186 @Override
187 public boolean equals(Object obj) {
188 if (this == obj)
189 return true;
190 if (!super.equals(obj))
191 return false;
192 if (getClass() != obj.getClass())
193 return false;
194 Node other = (Node) obj;
195 if (id != other.id)
196 return false;
197 return true;
198 }
199
200 }