View Javadoc

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.compute.util;
20  
21  import static com.google.common.base.Preconditions.checkState;
22  import static com.google.common.base.Throwables.getStackTraceAsString;
23  import static com.google.common.collect.Iterables.concat;
24  import static com.google.common.collect.Iterables.filter;
25  import static com.google.common.collect.Iterables.find;
26  import static com.google.common.collect.Iterables.size;
27  import static com.google.common.collect.Iterables.transform;
28  import static org.jclouds.scriptbuilder.domain.Statements.pipeHttpResponseToBash;
29  
30  import java.net.URI;
31  import java.util.Formatter;
32  import java.util.Map;
33  import java.util.NoSuchElementException;
34  import java.util.Map.Entry;
35  import java.util.regex.Matcher;
36  import java.util.regex.Pattern;
37  
38  import org.jclouds.compute.ComputeServiceContextBuilder;
39  import org.jclouds.compute.domain.ComputeMetadata;
40  import org.jclouds.compute.domain.Hardware;
41  import org.jclouds.compute.domain.NodeMetadata;
42  import org.jclouds.compute.domain.OsFamily;
43  import org.jclouds.compute.domain.Processor;
44  import org.jclouds.compute.domain.Volume;
45  import org.jclouds.compute.predicates.RetryIfSocketNotYetOpen;
46  import org.jclouds.http.HttpRequest;
47  import org.jclouds.net.IPSocket;
48  import org.jclouds.rest.Providers;
49  import org.jclouds.scriptbuilder.domain.Statement;
50  import org.jclouds.scriptbuilder.domain.Statements;
51  
52  import com.google.common.base.Function;
53  import com.google.common.base.Predicate;
54  import com.google.common.collect.Iterables;
55  
56  /**
57   * 
58   * @author Adrian Cole
59   */
60  public class ComputeServiceUtils {
61     public static final Pattern DELIMETED_BY_HYPHEN_ENDING_IN_HYPHEN_HEX = Pattern.compile("(.+)-[0-9a-f]+");
62  
63     /**
64      * build a shell script that invokes the contents of the http request in bash.
65      * 
66      * @return a shell script that will invoke the http request
67      */
68     public static Statement execHttpResponse(HttpRequest request) {
69        return pipeHttpResponseToBash(request.getMethod(), request.getEndpoint(), request.getHeaders());
70     }
71  
72     public static Statement execHttpResponse(URI location) {
73        return execHttpResponse(new HttpRequest("GET", location));
74     }
75  
76     /**
77      * build a shell script that invokes the contents of the http request in bash.
78      * 
79      * @return a shell script that will invoke the http request
80      */
81     public static Statement extractTargzIntoDirectory(HttpRequest targz, String directory) {
82        return Statements
83                 .extractTargzIntoDirectory(targz.getMethod(), targz.getEndpoint(), targz.getHeaders(), directory);
84     }
85  
86     public static Statement extractTargzIntoDirectory(URI targz, String directory) {
87        return extractTargzIntoDirectory(new HttpRequest("GET", targz), directory);
88     }
89  
90     /**
91      * build a shell script that invokes the contents of the http request in bash.
92      * 
93      * @return a shell script that will invoke the http request
94      */
95     public static Statement extractZipIntoDirectory(HttpRequest zip, String directory) {
96        return Statements.extractZipIntoDirectory(zip.getMethod(), zip.getEndpoint(), zip.getHeaders(), directory);
97     }
98  
99     public static Statement extractZipIntoDirectory(URI zip, String directory) {
100       return extractZipIntoDirectory(new HttpRequest("GET", zip), directory);
101    }
102 
103    /**
104     * 
105     * @return null if group cannot be parsed
106     */
107    public static String parseGroupFromName(String from) {
108       if (from == null)
109          return null;
110       Matcher matcher = DELIMETED_BY_HYPHEN_ENDING_IN_HYPHEN_HEX.matcher(from);
111       return matcher.find() ? matcher.group(1) : null;
112    }
113 
114    public static double getCores(Hardware input) {
115       double cores = 0;
116       for (Processor processor : input.getProcessors())
117          cores += processor.getCores();
118       return cores;
119    }
120 
121    public static double getCoresAndSpeed(Hardware input) {
122       double total = 0;
123       for (Processor processor : input.getProcessors())
124          total += (processor.getCores() * processor.getSpeed());
125       return total;
126    }
127 
128    public static double getSpace(Hardware input) {
129       double total = 0;
130       for (Volume volume : input.getVolumes())
131          total += volume.getSize() != null ? volume.getSize() : 0;
132       return total;
133    }
134 
135    public static org.jclouds.compute.domain.OsFamily parseOsFamilyOrUnrecognized(String in) {
136       org.jclouds.compute.domain.OsFamily myOs = null;
137       for (org.jclouds.compute.domain.OsFamily os : org.jclouds.compute.domain.OsFamily.values()) {
138          if (in.toLowerCase().replaceAll("\\s", "").indexOf(os.toString()) != -1) {
139             myOs = os;
140          }
141       }
142       return myOs != null ? myOs : OsFamily.UNRECOGNIZED;
143    }
144 
145    public static String createExecutionErrorMessage(Map<?, Exception> executionExceptions) {
146       Formatter fmt = new Formatter().format("Execution failures:%n%n");
147       int index = 1;
148       for (Entry<?, Exception> errorMessage : executionExceptions.entrySet()) {
149          fmt.format("%s) %s on %s:%n%s%n%n", index++, errorMessage.getValue().getClass().getSimpleName(), errorMessage
150                   .getKey(), getStackTraceAsString(errorMessage.getValue()));
151       }
152       return fmt.format("%s error[s]", executionExceptions.size()).toString();
153    }
154 
155    public static String createNodeErrorMessage(Map<? extends NodeMetadata, ? extends Throwable> failedNodes) {
156       Formatter fmt = new Formatter().format("Node failures:%n%n");
157       int index = 1;
158       for (Entry<? extends NodeMetadata, ? extends Throwable> errorMessage : failedNodes.entrySet()) {
159          fmt.format("%s) %s on node %s:%n%s%n%n", index++, errorMessage.getValue().getClass().getSimpleName(),
160                   errorMessage.getKey().getId(), getStackTraceAsString(errorMessage.getValue()));
161       }
162       return fmt.format("%s error[s]", failedNodes.size()).toString();
163    }
164 
165    public static Iterable<? extends ComputeMetadata> filterByName(Iterable<? extends ComputeMetadata> nodes,
166             final String name) {
167       return filter(nodes, new Predicate<ComputeMetadata>() {
168          @Override
169          public boolean apply(ComputeMetadata input) {
170             return input.getName().equalsIgnoreCase(name);
171          }
172       });
173    }
174 
175    public static Iterable<String> getSupportedProviders() {
176       return Providers.getSupportedProvidersOfType(ComputeServiceContextBuilder.class);
177    }
178 
179    public static IPSocket findReachableSocketOnNode(RetryIfSocketNotYetOpen socketTester, final NodeMetadata node,
180             final int port) {
181       checkNodeHasIps(node);
182       IPSocket socket = null;
183       try {
184          socket = find(transform(concat(node.getPublicAddresses(), node.getPrivateAddresses()),
185                   new Function<String, IPSocket>() {
186 
187                      @Override
188                      public IPSocket apply(String from) {
189                         return new IPSocket(from, port);
190                      }
191                   }), socketTester);
192       } catch (NoSuchElementException e) {
193          throw new NoSuchElementException(String.format("could not connect to any ip address port %d on node %s", port,
194                   node));
195       }
196       return socket;
197    }
198 
199    public static void checkNodeHasIps(NodeMetadata node) {
200       checkState(size(concat(node.getPublicAddresses(), node.getPrivateAddresses())) > 0,
201                "node does not have IP addresses configured: " + node);
202    }
203 
204    public static String parseVersionOrReturnEmptyString(org.jclouds.compute.domain.OsFamily family, String in,
205             Map<OsFamily, Map<String, String>> osVersionMap) {
206       if (osVersionMap.containsKey(family)) {
207          if (osVersionMap.get(family).containsKey(in))
208             return osVersionMap.get(family).get(in);
209          if (osVersionMap.get(family).containsValue(in))
210             return in;
211          CONTAINS_SUBSTRING contains = new CONTAINS_SUBSTRING(in.replace('-', '.'));
212          try {
213             String key = Iterables.find(osVersionMap.get(family).keySet(), contains);
214             return osVersionMap.get(family).get(key);
215          } catch (NoSuchElementException e) {
216             try {
217                return Iterables.find(osVersionMap.get(family).values(), contains);
218             } catch (NoSuchElementException e1) {
219             }
220          }
221       }
222       return "";
223    }
224 
225    static final class CONTAINS_SUBSTRING implements Predicate<String> {
226       private final String in;
227 
228       CONTAINS_SUBSTRING(String in) {
229          this.in = in;
230       }
231 
232       @Override
233       public boolean apply(String input) {
234          return in.indexOf(input) != -1;
235       }
236    }
237 
238 }