View Javadoc
1   /*
2    * Licensed to The Apereo Foundation under one or more contributor license
3    * agreements. See the NOTICE file distributed with this work for additional
4    * information regarding copyright ownership.
5    *
6    *
7    * The Apereo Foundation licenses this file to you under the Educational
8    * Community License, Version 2.0 (the "License"); you may not use this file
9    * except in compliance with the License. You may obtain a copy of the License
10   * at:
11   *
12   *   http://opensource.org/licenses/ecl2.txt
13   *
14   * Unless required by applicable law or agreed to in writing, software
15   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
16   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
17   * License for the specific language governing permissions and limitations under
18   * the License.
19   *
20   */
21  
22  package org.opencastproject.serviceregistry.api;
23  
24  import org.opencastproject.util.NotFoundException;
25  
26  import java.util.Collection;
27  import java.util.LinkedHashMap;
28  import java.util.Map;
29  
30  import javax.xml.bind.annotation.XmlAccessType;
31  import javax.xml.bind.annotation.XmlAccessorType;
32  import javax.xml.bind.annotation.XmlAttribute;
33  import javax.xml.bind.annotation.XmlElement;
34  import javax.xml.bind.annotation.XmlElementWrapper;
35  import javax.xml.bind.annotation.XmlRootElement;
36  import javax.xml.bind.annotation.XmlType;
37  
38  /**
39   * Mappings between the registered hosts and their load factors.
40   */
41  @XmlType(name = "load", namespace = "http://serviceregistry.opencastproject.org")
42  @XmlRootElement(name = "load", namespace = "http://serviceregistry.opencastproject.org")
43  @XmlAccessorType(XmlAccessType.NONE)
44  public class SystemLoad {
45  
46    /** No-arg constructor needed by JAXB */
47    public SystemLoad() {
48      nodeLoads = new LinkedHashMap<String, NodeLoad>();
49    }
50  
51    /** The list of nodes and their current load */
52    protected Map<String, NodeLoad> nodeLoads;
53  
54    /**
55     * Get the list of nodes and their current loadfactor.
56     *
57     * @return the nodeLoads
58     */
59    @XmlElementWrapper(name = "nodes")
60    @XmlElement(name = "node")
61    public Collection<NodeLoad> getNodeLoads() {
62      return nodeLoads.values();
63    }
64  
65    /**
66     * Sets the list of nodes and their current loadfactor.
67     *
68     * @param newLoads
69     *          the nodeLoads to set
70     */
71    public void setNodeLoads(Collection<NodeLoad> newLoads) {
72      for (NodeLoad node : newLoads) {
73        nodeLoads.put(node.getHost(), node);
74      }
75    }
76  
77    /**
78     * Updates the load factor for a node
79     * @param host
80     *   The host to update
81     * @param modifier
82     *   The modifier to apply to the load
83     */
84    public void updateNodeLoad(String host, float modifier) throws NotFoundException {
85      if (!nodeLoads.containsKey(host)) {
86        throw new NotFoundException("Host " + host + " not in this load object");
87      }
88      nodeLoads.get(host).modifyLoad(modifier);
89    }
90  
91    /**
92     * Adds a node to the map of load values, overwriting an existing entry if the node is already present in the map
93     * @param load
94     *          the nodeLoad to add
95     */
96    public void addNodeLoad(NodeLoad load) {
97      nodeLoads.put(load.getHost(), load);
98    }
99  
100   /**
101    * Gets a specific host from the map, if present.  If the node is not present, or the host value is null, this method
102    * returns null.
103    * @param host
104    *        The hostname of the host you are interested in.
105    * @return
106    *        The specific host from the map, if present.  If the node is not present, or the host value is null, this
107    *        method returns null.
108    */
109   public NodeLoad get(String host) {
110     if (host != null && this.containsHost(host)) {
111       return nodeLoads.get(host);
112     }
113     return null;
114   }
115 
116   /**
117    * Returns true if the load map contains the host in question.
118    * @param host
119    *          The hostname of the host you are interested in.
120    * @return
121    *          True if the host is present, false if the host is not, or the host variable is null.
122    */
123   public boolean containsHost(String host) {
124     if (host != null) {
125       return nodeLoads.containsKey(host);
126     }
127     return false;
128   }
129 
130   @Override
131   public String toString() {
132     StringBuilder sb = new StringBuilder();
133     sb.append("Current Loads:\n");
134     for (NodeLoad n : getNodeLoads()) {
135       sb.append(String.format("  %s: %f / %f\n", n.getHost(), n.getCurrentLoad(), n.getMaxLoad()));
136     }
137     return sb.toString();
138   }
139 
140 
141   /** A record of a node in the cluster and its load factor */
142   @XmlType(name = "nodetype", namespace = "http://serviceregistry.opencastproject.org")
143   @XmlRootElement(name = "nodetype", namespace = "http://serviceregistry.opencastproject.org")
144   @XmlAccessorType(XmlAccessType.NONE)
145   public static class NodeLoad implements Comparable<NodeLoad> {
146 
147     /** No-arg constructor needed by JAXB */
148     public NodeLoad() {
149     }
150 
151     public NodeLoad(String host, float currentload, float maxload) {
152       this.host = host;
153       this.currentLoad = currentload;
154       this.maxLoad = maxload;
155     }
156 
157     /** This node's base URL */
158     @XmlAttribute
159     protected String host;
160 
161     /** This node's current load */
162     @XmlAttribute
163     protected float currentLoad;
164 
165     @XmlAttribute
166     protected float maxLoad;
167 
168     /**
169      * @return the host
170      */
171     public String getHost() {
172       return host;
173     }
174 
175     /**
176      * @param host
177      *          the host to set
178      */
179     public void setHost(String host) {
180       this.host = host;
181     }
182 
183     /**
184      * @return the load factor, current / maxload
185      */
186     public float getLoadFactor() {
187       return currentLoad / maxLoad;
188     }
189 
190     /**
191      * Modifies the load for this node
192      * @param modifier
193      *              the amount to add or subtract from the current load
194      */
195     public void modifyLoad(float modifier) {
196       this.currentLoad = this.currentLoad + modifier;
197     }
198 
199     public float getCurrentLoad() {
200       return currentLoad;
201     }
202 
203     public void setCurrentLoad(float load) {
204       this.currentLoad = load;
205     }
206 
207     public float getMaxLoad() {
208       return maxLoad;
209     }
210 
211     public void setMaxLoad(float load) {
212       this.maxLoad = load;
213     }
214 
215 
216     @Override
217     public int compareTo(NodeLoad other) {
218       if (other.getLoadFactor() > this.getLoadFactor()) {
219         return 1;
220       } else if (this.getLoadFactor() > other.getLoadFactor()) {
221         return -1;
222       } else {
223         return 0;
224       }
225     }
226 
227     public boolean exceeds(NodeLoad other) {
228       if (this.compareTo(other) > 1) {
229         return true;
230       }
231       return false;
232     }
233   }
234 }