View Javadoc

1   /**
2    *
3    * Copyright (C) 2011 Cloud Conscious, LLC. <info@cloudconscious.com>
4    *
5    * ====================================================================
6    * Licensed under the Apache License, Version 2.0 (the "License");
7    * you may not use this file except in compliance with the License.
8    * 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, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   * ====================================================================
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       Matcher matcher = DELIMETED_BY_HYPHEN_ENDING_IN_HYPHEN_HEX.matcher(from);
109       return matcher.find() ? matcher.group(1) : null;
110    }
111 
112    public static double getCores(Hardware input) {
113       double cores = 0;
114       for (Processor processor : input.getProcessors())
115          cores += processor.getCores();
116       return cores;
117    }
118 
119    public static double getCoresAndSpeed(Hardware input) {
120       double total = 0;
121       for (Processor processor : input.getProcessors())
122          total += (processor.getCores() * processor.getSpeed());
123       return total;
124    }
125 
126    public static double getSpace(Hardware input) {
127       double total = 0;
128       for (Volume volume : input.getVolumes())
129          total += volume.getSize() != null ? volume.getSize() : 0;
130       return total;
131    }
132 
133    public static org.jclouds.compute.domain.OsFamily parseOsFamilyOrUnrecognized(String in) {
134       org.jclouds.compute.domain.OsFamily myOs = null;
135       for (org.jclouds.compute.domain.OsFamily os : org.jclouds.compute.domain.OsFamily.values()) {
136          if (in.toLowerCase().replaceAll("\\s", "").indexOf(os.toString()) != -1) {
137             myOs = os;
138          }
139       }
140       return myOs != null ? myOs : OsFamily.UNRECOGNIZED;
141    }
142 
143    public static String createExecutionErrorMessage(Map<?, Exception> executionExceptions) {
144       Formatter fmt = new Formatter().format("Execution failures:%n%n");
145       int index = 1;
146       for (Entry<?, Exception> errorMessage : executionExceptions.entrySet()) {
147          fmt.format("%s) %s on %s:%n%s%n%n", index++, errorMessage.getValue().getClass().getSimpleName(), errorMessage
148                   .getKey(), getStackTraceAsString(errorMessage.getValue()));
149       }
150       return fmt.format("%s error[s]", executionExceptions.size()).toString();
151    }
152 
153    public static String createNodeErrorMessage(Map<? extends NodeMetadata, ? extends Throwable> failedNodes) {
154       Formatter fmt = new Formatter().format("Node failures:%n%n");
155       int index = 1;
156       for (Entry<? extends NodeMetadata, ? extends Throwable> errorMessage : failedNodes.entrySet()) {
157          fmt.format("%s) %s on node %s:%n%s%n%n", index++, errorMessage.getValue().getClass().getSimpleName(),
158                   errorMessage.getKey().getId(), getStackTraceAsString(errorMessage.getValue()));
159       }
160       return fmt.format("%s error[s]", failedNodes.size()).toString();
161    }
162 
163    public static Iterable<? extends ComputeMetadata> filterByName(Iterable<? extends ComputeMetadata> nodes,
164             final String name) {
165       return filter(nodes, new Predicate<ComputeMetadata>() {
166          @Override
167          public boolean apply(ComputeMetadata input) {
168             return input.getName().equalsIgnoreCase(name);
169          }
170       });
171    }
172 
173    public static Iterable<String> getSupportedProviders() {
174       return Providers.getSupportedProvidersOfType(ComputeServiceContextBuilder.class);
175    }
176 
177    public static IPSocket findReachableSocketOnNode(RetryIfSocketNotYetOpen socketTester, final NodeMetadata node,
178             final int port) {
179       checkNodeHasIps(node);
180       IPSocket socket = null;
181       try {
182          socket = find(transform(concat(node.getPublicAddresses(), node.getPrivateAddresses()),
183                   new Function<String, IPSocket>() {
184 
185                      @Override
186                      public IPSocket apply(String from) {
187                         return new IPSocket(from, port);
188                      }
189                   }), socketTester);
190       } catch (NoSuchElementException e) {
191          throw new NoSuchElementException(String.format("could not connect to any ip address port %d on node %s", port,
192                   node));
193       }
194       return socket;
195    }
196 
197    public static void checkNodeHasIps(NodeMetadata node) {
198       checkState(size(concat(node.getPublicAddresses(), node.getPrivateAddresses())) > 0,
199                "node does not have IP addresses configured: " + node);
200    }
201 
202    public static String parseVersionOrReturnEmptyString(org.jclouds.compute.domain.OsFamily family, String in,
203             Map<OsFamily, Map<String, String>> osVersionMap) {
204       if (osVersionMap.containsKey(family)) {
205          if (osVersionMap.get(family).containsKey(in))
206             return osVersionMap.get(family).get(in);
207          if (osVersionMap.get(family).containsValue(in))
208             return in;
209          CONTAINS_SUBSTRING contains = new CONTAINS_SUBSTRING(in.replace('-', '.'));
210          try {
211             String key = Iterables.find(osVersionMap.get(family).keySet(), contains);
212             return osVersionMap.get(family).get(key);
213          } catch (NoSuchElementException e) {
214             try {
215                return Iterables.find(osVersionMap.get(family).values(), contains);
216             } catch (NoSuchElementException e1) {
217             }
218          }
219       }
220       return "";
221    }
222 
223    static final class CONTAINS_SUBSTRING implements Predicate<String> {
224       private final String in;
225 
226       CONTAINS_SUBSTRING(String in) {
227          this.in = in;
228       }
229 
230       @Override
231       public boolean apply(String input) {
232          return in.indexOf(input) != -1;
233       }
234    }
235 
236 }