You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by sa...@apache.org on 2016/06/16 08:12:21 UTC
[20/50] [abbrv] git commit: updated refs/heads/deploy-from-snapshot
to 44ba14d
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/83fd8f60/utils/src/main/java/com/cloud/utils/HttpUtils.java
----------------------------------------------------------------------
diff --git a/utils/src/main/java/com/cloud/utils/HttpUtils.java b/utils/src/main/java/com/cloud/utils/HttpUtils.java
new file mode 100644
index 0000000..d2e844a
--- /dev/null
+++ b/utils/src/main/java/com/cloud/utils/HttpUtils.java
@@ -0,0 +1,114 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package com.cloud.utils;
+
+import org.apache.log4j.Logger;
+
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+import java.io.IOException;
+import java.util.Map;
+
+public class HttpUtils {
+
+ public static final Logger s_logger = Logger.getLogger(HttpUtils.class);
+
+ public static final String UTF_8 = "UTF-8";
+ public static final String RESPONSE_TYPE_JSON = "json";
+ public static final String RESPONSE_TYPE_XML = "xml";
+ public static final String JSON_CONTENT_TYPE = "application/json; charset=UTF-8";
+ public static final String XML_CONTENT_TYPE = "text/xml; charset=UTF-8";
+
+ public static void addSecurityHeaders(final HttpServletResponse resp) {
+ if (resp.containsHeader("X-Content-Type-Options")) {
+ resp.setHeader("X-Content-Type-Options", "nosniff");
+ }
+ else {
+ resp.addHeader("X-Content-Type-Options", "nosniff");
+ }
+ if (resp.containsHeader("X-XSS-Protection")) {
+ resp.setHeader("X-XSS-Protection", "1;mode=block");
+ }
+ else {
+ resp.addHeader("X-XSS-Protection", "1;mode=block");
+ }
+ }
+
+ public static void writeHttpResponse(final HttpServletResponse resp, final String response,
+ final Integer responseCode, final String responseType, final String jsonContentType) {
+ try {
+ if (RESPONSE_TYPE_JSON.equalsIgnoreCase(responseType)) {
+ if (jsonContentType != null && !jsonContentType.isEmpty()) {
+ resp.setContentType(jsonContentType);
+ } else {
+ resp.setContentType(JSON_CONTENT_TYPE);
+ }
+ } else if (RESPONSE_TYPE_XML.equalsIgnoreCase(responseType)){
+ resp.setContentType(XML_CONTENT_TYPE);
+ }
+ if (responseCode != null) {
+ resp.setStatus(responseCode);
+ }
+ addSecurityHeaders(resp);
+ resp.getWriter().print(response);
+ } catch (final IOException ioex) {
+ if (s_logger.isTraceEnabled()) {
+ s_logger.trace("Exception writing http response: " + ioex);
+ }
+ } catch (final Exception ex) {
+ if (!(ex instanceof IllegalStateException)) {
+ s_logger.error("Unknown exception writing http response", ex);
+ }
+ }
+ }
+
+ public static String findCookie(final Cookie[] cookies, final String key) {
+ if (cookies == null || key == null || key.isEmpty()) {
+ return null;
+ }
+ for (Cookie cookie: cookies) {
+ if (cookie != null && cookie.getName().equals(key)) {
+ return cookie.getValue();
+ }
+ }
+ return null;
+ }
+
+ public static boolean validateSessionKey(final HttpSession session, final Map<String, Object[]> params, final Cookie[] cookies, final String sessionKeyString) {
+ if (session == null || sessionKeyString == null) {
+ return false;
+ }
+ final String sessionKey = (String) session.getAttribute(sessionKeyString);
+ final String sessionKeyFromCookie = HttpUtils.findCookie(cookies, sessionKeyString);
+ String[] sessionKeyFromParams = null;
+ if (params != null) {
+ sessionKeyFromParams = (String[]) params.get(sessionKeyString);
+ }
+ if ((sessionKey == null)
+ || (sessionKeyFromParams == null && sessionKeyFromCookie == null)
+ || (sessionKeyFromParams != null && !sessionKey.equals(sessionKeyFromParams[0]))
+ || (sessionKeyFromCookie != null && !sessionKey.equals(sessionKeyFromCookie))) {
+ return false;
+ }
+ return true;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/83fd8f60/utils/src/main/java/com/cloud/utils/IteratorUtil.java
----------------------------------------------------------------------
diff --git a/utils/src/main/java/com/cloud/utils/IteratorUtil.java b/utils/src/main/java/com/cloud/utils/IteratorUtil.java
new file mode 100644
index 0000000..8ab88f5
--- /dev/null
+++ b/utils/src/main/java/com/cloud/utils/IteratorUtil.java
@@ -0,0 +1,72 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package com.cloud.utils;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.List;
+
+public class IteratorUtil {
+ public static <T> Iterable<T> enumerationAsIterable(final Enumeration<T> e) {
+ return new Iterable<T>() {
+ @Override
+ public Iterator<T> iterator() {
+ return new Iterator<T>() {
+ @Override
+ public boolean hasNext() {
+ return e.hasMoreElements();
+ }
+
+ @Override
+ public T next() {
+ return e.nextElement();
+ }
+
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ };
+ }
+ };
+ }
+
+ public static <T> Enumeration<T> iteratorAsEnumeration(final Iterator<T> it) {
+ return new Enumeration<T>() {
+ @Override
+ public boolean hasMoreElements() {
+ return it.hasNext();
+ }
+
+ @Override
+ public T nextElement() {
+ return it.next();
+ }
+ };
+ }
+
+ public static <T extends Comparable<? super T>> List<T> asSortedList(Collection<T> c) {
+ List<T> list = new ArrayList<T>(c);
+ java.util.Collections.sort(list);
+ return list;
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/83fd8f60/utils/src/main/java/com/cloud/utils/Journal.java
----------------------------------------------------------------------
diff --git a/utils/src/main/java/com/cloud/utils/Journal.java b/utils/src/main/java/com/cloud/utils/Journal.java
new file mode 100644
index 0000000..e88dba3
--- /dev/null
+++ b/utils/src/main/java/com/cloud/utils/Journal.java
@@ -0,0 +1,104 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package com.cloud.utils;
+
+import java.util.ArrayList;
+
+import org.apache.log4j.Level;
+import org.apache.log4j.Logger;
+
+/**
+ * Journal is used to kept what has happened during a process so someone can track
+ * what happens during a process.
+ *
+ */
+public class Journal {
+ String _name;
+ ArrayList<Pair<String, Object[]>> _entries;
+
+ public Journal(String name) {
+ _name = name;
+ _entries = new ArrayList<Pair<String, Object[]>>();
+ }
+
+ final private void log(String msg, Object... params) {
+ Pair<String, Object[]> entry = new Pair<String, Object[]>(msg, params);
+ assert msg != null : "Message can not be null or else it's useless!";
+ _entries.add(entry);
+ }
+
+ public void record(String msg, Object... params) {
+ log(msg, params);
+ }
+
+ public void record(Logger logger, Level p, String msg, Object... params) {
+ if (logger.isEnabledFor(p)) {
+ StringBuilder buf = new StringBuilder();
+ toString(buf, msg, params);
+ String entry = buf.toString();
+ log(entry);
+ logger.log(p, entry);
+ } else {
+ log(msg, params);
+ }
+ }
+
+ protected void toString(StringBuilder buf, String msg, Object[] params) {
+ buf.append(msg);
+ if (params != null) {
+ buf.append(" - ");
+ int i = 0;
+ for (Object obj : params) {
+ buf.append('P').append(i).append('=');
+ buf.append(obj != null ? obj.toString() : "null");
+ buf.append(", ");
+ }
+ buf.delete(buf.length() - 2, buf.length());
+ }
+ }
+
+ public String toString(String separator) {
+ StringBuilder buf = new StringBuilder(_name).append(": ");
+ for (Pair<String, Object[]> entry : _entries) {
+ toString(buf, entry.first(), entry.second());
+ buf.append(separator);
+ }
+ return buf.toString();
+ }
+
+ @Override
+ public String toString() {
+ return toString("; ");
+ }
+
+ public static class LogJournal extends Journal {
+ Logger _logger;
+
+ public LogJournal(String name, Logger logger) {
+ super(name);
+ _logger = logger;
+ }
+
+ @Override
+ public void record(String msg, Object... params) {
+ record(_logger, Level.DEBUG, msg, params);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/83fd8f60/utils/src/main/java/com/cloud/utils/LogUtils.java
----------------------------------------------------------------------
diff --git a/utils/src/main/java/com/cloud/utils/LogUtils.java b/utils/src/main/java/com/cloud/utils/LogUtils.java
new file mode 100644
index 0000000..d86766c
--- /dev/null
+++ b/utils/src/main/java/com/cloud/utils/LogUtils.java
@@ -0,0 +1,45 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package com.cloud.utils;
+
+import java.io.File;
+
+import org.apache.log4j.Logger;
+import org.apache.log4j.xml.DOMConfigurator;
+
+public class LogUtils {
+ public static final Logger s_logger = Logger.getLogger(LogUtils.class);
+
+ public static void initLog4j(String log4jConfigFileName) {
+ assert (log4jConfigFileName != null);
+ File file = PropertiesUtil.findConfigFile(log4jConfigFileName);
+ if (file != null) {
+ s_logger.info("log4j configuration found at " + file.getAbsolutePath());
+ DOMConfigurator.configureAndWatch(file.getAbsolutePath());
+ } else {
+ String nameWithoutExtension = log4jConfigFileName.substring(0, log4jConfigFileName.lastIndexOf('.'));
+ file = PropertiesUtil.findConfigFile(nameWithoutExtension + ".properties");
+ if (file != null) {
+ s_logger.info("log4j configuration found at " + file.getAbsolutePath());
+ DOMConfigurator.configureAndWatch(file.getAbsolutePath());
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/83fd8f60/utils/src/main/java/com/cloud/utils/MethodCapturer.java
----------------------------------------------------------------------
diff --git a/utils/src/main/java/com/cloud/utils/MethodCapturer.java b/utils/src/main/java/com/cloud/utils/MethodCapturer.java
new file mode 100644
index 0000000..655a45d
--- /dev/null
+++ b/utils/src/main/java/com/cloud/utils/MethodCapturer.java
@@ -0,0 +1,113 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package com.cloud.utils;
+
+import java.lang.reflect.Method;
+import java.util.WeakHashMap;
+
+import net.sf.cglib.proxy.Callback;
+import net.sf.cglib.proxy.CallbackFilter;
+import net.sf.cglib.proxy.Enhancer;
+import net.sf.cglib.proxy.MethodInterceptor;
+import net.sf.cglib.proxy.MethodProxy;
+
+/*
+ * This helper class provides a way to retrieve Method in a strong-type way. It takes advantage of power of
+ * Intelligent IDE(Eclipse) in code-editing
+ *
+ * DummyImpl dummy = new DummyImpl();
+ * MethodCapturer<DummyImpl> capturer = MethodCapturer.capture(dummy);
+ * Method method = capturer.get(capturer.instance().foo2());
+ *
+ */
+public class MethodCapturer<T> {
+
+ private final static int CACHE_SIZE = 1024;
+
+ private T _instance;
+ private Method _method;
+
+ private static WeakHashMap<Object, Object> s_cache = new WeakHashMap<Object, Object>();
+
+ private MethodCapturer() {
+ }
+
+ @SuppressWarnings("unchecked")
+ public static <T> MethodCapturer<T> capture(T obj) {
+ synchronized (s_cache) {
+ MethodCapturer<T> capturer = (MethodCapturer<T>)s_cache.get(obj);
+ if (capturer != null) {
+ return capturer;
+ }
+
+ final MethodCapturer<T> capturerNew = new MethodCapturer<T>();
+
+ Enhancer en = new Enhancer();
+ en.setSuperclass(obj.getClass());
+ en.setCallbacks(new Callback[] {new MethodInterceptor() {
+ @Override
+ public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable {
+ capturerNew.setMethod(arg1);
+ return null;
+ }
+ }, new MethodInterceptor() {
+ @Override
+ public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable {
+ return null;
+ }
+ }});
+ en.setCallbackFilter(new CallbackFilter() {
+ @Override
+ public int accept(Method method) {
+ if (method.getParameterTypes().length == 0 && method.getName().equals("finalize")) {
+ return 1;
+ }
+ return 0;
+ }
+ });
+
+ capturerNew.setInstance((T)en.create());
+
+ // We expect MethodCapturer is only used for singleton objects here, so we only maintain a limited cache
+ // here
+ if (s_cache.size() < CACHE_SIZE) {
+ s_cache.put(obj, capturerNew);
+ }
+
+ return capturerNew;
+ }
+ }
+
+ public T instance() {
+ return _instance;
+ }
+
+ private void setInstance(T instance) {
+ _instance = instance;
+ }
+
+ public Method get(Object... useless) {
+ return _method;
+ }
+
+ private void setMethod(Method method) {
+ _method = method;
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/83fd8f60/utils/src/main/java/com/cloud/utils/NumbersUtil.java
----------------------------------------------------------------------
diff --git a/utils/src/main/java/com/cloud/utils/NumbersUtil.java b/utils/src/main/java/com/cloud/utils/NumbersUtil.java
new file mode 100644
index 0000000..8b93a40
--- /dev/null
+++ b/utils/src/main/java/com/cloud/utils/NumbersUtil.java
@@ -0,0 +1,139 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package com.cloud.utils;
+
+import java.nio.ByteBuffer;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Formatter;
+import java.util.Locale;
+
+import org.apache.commons.lang.math.NumberUtils;
+
+import com.cloud.utils.exception.CloudRuntimeException;
+
+public class NumbersUtil {
+ public static long parseLong(String s, long defaultValue) {
+ return NumberUtils.toLong(s, defaultValue);
+ }
+
+ public static int parseInt(String s, int defaultValue) {
+ return NumberUtils.toInt(s, defaultValue);
+ }
+
+ public static float parseFloat(String s, float defaultValue) {
+ return NumberUtils.toFloat(s, defaultValue);
+ }
+
+ /**
+ * Converts bytes to long on input.
+ */
+ public static long bytesToLong(byte b[]) {
+ return bytesToLong(b, 0);
+ }
+
+ public static long bytesToLong(byte b[], int pos) {
+ return ByteBuffer.wrap(b, pos, 8).getLong();
+ }
+
+ /**
+ * Converts a byte array to a hex readable string.
+ **/
+ public static String bytesToString(byte[] data, int start, int end) {
+ StringBuilder buf = new StringBuilder();
+ if (end > data.length) {
+ end = data.length;
+ }
+ for (int i = start; i < end; i++) {
+ buf.append(" ");
+ buf.append(Integer.toHexString(data[i] & 0xff));
+ }
+ return buf.toString();
+ }
+
+ protected static final long KB = 1024;
+ protected static final long MB = 1024 * KB;
+ protected static final long GB = 1024 * MB;
+ protected static final long TB = 1024 * GB;
+
+ public static String toReadableSize(long bytes) {
+ if (bytes < KB && bytes >= 0) {
+ return Long.toString(bytes) + " bytes";
+ }
+ StringBuilder builder = new StringBuilder();
+ Formatter format = new Formatter(builder, Locale.getDefault());
+ if (bytes < MB) {
+ format.format("%.2f KB", (float)bytes / (float)KB);
+ } else if (bytes < GB) {
+ format.format("%.2f MB", (float)bytes / (float)MB);
+ } else if (bytes < TB) {
+ format.format("%.2f GB", (float)bytes / (float)GB);
+ } else {
+ format.format("%.4f TB", (float)bytes / (float)TB);
+ }
+ format.close();
+ return builder.toString();
+ }
+
+ /**
+ * Converts a string of the format 'yy-MM-dd'T'HH:mm:ss.SSS" into ms.
+ *
+ * @param str containing the interval.
+ * @param defaultValue value to return if str doesn't parse. If -1, throws VmopsRuntimeException
+ * @return interval in ms
+ */
+ public static long parseInterval(String str, long defaultValue) {
+ try {
+ if (str == null) {
+ throw new ParseException("String is wrong", 0);
+ }
+
+ SimpleDateFormat sdf = null;
+ if (str.contains("D")) {
+ sdf = new SimpleDateFormat("dd'D'HH'h'mm'M'ss'S'SSS'ms'");
+ } else if (str.contains("h")) {
+ sdf = new SimpleDateFormat("HH'h'mm'M'ss'S'SSS'ms'");
+ } else if (str.contains("M")) {
+ sdf = new SimpleDateFormat("mm'M'ss'S'SSS'ms'");
+ } else if (str.contains("S")) {
+ sdf = new SimpleDateFormat("ss'S'SSS'ms'");
+ } else if (str.contains("ms")) {
+ sdf = new SimpleDateFormat("SSS'ms'");
+ }
+ if (sdf == null) {
+ throw new ParseException("String is wrong", 0);
+ }
+
+ Date date = sdf.parse(str);
+ return date.getTime();
+ } catch (ParseException e) {
+ if (defaultValue != -1) {
+ return defaultValue;
+ } else {
+ throw new CloudRuntimeException("Unable to parse: " + str, e);
+ }
+ }
+ }
+
+ public static int hash(long value) {
+ return (int)(value ^ (value >>> 32));
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/83fd8f60/utils/src/main/java/com/cloud/utils/Pair.java
----------------------------------------------------------------------
diff --git a/utils/src/main/java/com/cloud/utils/Pair.java b/utils/src/main/java/com/cloud/utils/Pair.java
new file mode 100644
index 0000000..73d3562
--- /dev/null
+++ b/utils/src/main/java/com/cloud/utils/Pair.java
@@ -0,0 +1,87 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package com.cloud.utils;
+
+import java.io.Serializable;
+
+public class Pair<T, U> implements Serializable {
+ private static final long serialVersionUID = 2L;
+ T t;
+ U u;
+
+ protected Pair() {
+
+ }
+
+ public Pair(T t, U u) {
+ this.t = t;
+ this.u = u;
+ }
+
+ public T first() {
+ return t;
+ }
+
+ public U second() {
+ return u;
+ }
+
+ public U second(U value) {
+ u = value;
+ return u;
+ }
+
+ public T first(T value) {
+ t = value;
+ return t;
+ }
+
+ public void set(T t, U u) {
+ this.t = t;
+ this.u = u;
+ }
+
+ @Override
+ // Note: This means any two pairs with null for both values will match each
+ // other but what can I do? This is due to stupid type erasure.
+ public
+ int hashCode() {
+ return (t != null ? t.hashCode() : 0) | (u != null ? u.hashCode() : 0);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof Pair)) {
+ return false;
+ }
+ Pair<?, ?> that = (Pair<?, ?>)obj;
+ return (t != null ? t.equals(that.t) : that.t == null) && (u != null ? u.equals(that.u) : that.u == null);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder b = new StringBuilder("P[");
+ b.append((t != null) ? t.toString() : "null");
+ b.append(":");
+ b.append((u != null) ? u.toString() : "null");
+ b.append("]");
+ return b.toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/83fd8f60/utils/src/main/java/com/cloud/utils/PasswordGenerator.java
----------------------------------------------------------------------
diff --git a/utils/src/main/java/com/cloud/utils/PasswordGenerator.java b/utils/src/main/java/com/cloud/utils/PasswordGenerator.java
new file mode 100644
index 0000000..0d79143
--- /dev/null
+++ b/utils/src/main/java/com/cloud/utils/PasswordGenerator.java
@@ -0,0 +1,90 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package com.cloud.utils;
+
+import java.security.SecureRandom;
+import java.util.Random;
+
+/**
+ * Generate random passwords
+ *
+ */
+public class PasswordGenerator {
+ //Leave out visually confusing l,L,1,o,O,0
+ static private char[] lowerCase = new char[] {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'm', 'n', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'};
+ static private char[] upperCase = new char[] {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};
+ static private char[] numeric = new char[] {'2', '3', '4', '5', '6', '7', '8', '9'};
+
+ static private char[] alphaNumeric = new char[] {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y',
+ 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'j', 'k', 'm', 'n', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '2', '3', '4', '5', '6', '7', '8', '9'};
+
+ static private int minLength = 3;
+
+ public static String generateRandomPassword(int num) {
+ Random r = new SecureRandom();
+ StringBuilder password = new StringBuilder();
+
+ //Guard for num < minLength
+ if (num < minLength) {
+ //Add alphanumeric chars at random
+ for (int i = 0; i < minLength; i++) {
+ password.append(generateAlphaNumeric(r));
+ }
+ } else {
+ // Generate random 3-character string with a lowercase character,
+ // uppercase character, and a digit
+ password.append(generateLowercaseChar(r)).append(generateUppercaseChar(r)).append(generateDigit(r));
+
+ // Generate a random n-character string with only lowercase
+ // characters
+ for (int i = 0; i < num - 3; i++) {
+ password.append(generateLowercaseChar(r));
+ }
+ }
+
+ return password.toString();
+ }
+
+ private static char generateLowercaseChar(Random r) {
+ return lowerCase[r.nextInt(lowerCase.length)];
+ }
+
+ private static char generateDigit(Random r) {
+ return numeric[r.nextInt(numeric.length)];
+ }
+
+ private static char generateUppercaseChar(Random r) {
+ return upperCase[r.nextInt(upperCase.length)];
+ }
+
+ private static char generateAlphaNumeric(Random r) {
+ return alphaNumeric[r.nextInt(alphaNumeric.length)];
+ }
+
+ public static String generatePresharedKey(int numChars) {
+ Random r = new SecureRandom();
+ StringBuilder psk = new StringBuilder();
+ for (int i = 0; i < numChars; i++) {
+ psk.append(generateAlphaNumeric(r));
+ }
+ return psk.toString();
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/83fd8f60/utils/src/main/java/com/cloud/utils/Predicate.java
----------------------------------------------------------------------
diff --git a/utils/src/main/java/com/cloud/utils/Predicate.java b/utils/src/main/java/com/cloud/utils/Predicate.java
new file mode 100644
index 0000000..6079d16
--- /dev/null
+++ b/utils/src/main/java/com/cloud/utils/Predicate.java
@@ -0,0 +1,24 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package com.cloud.utils;
+
+public interface Predicate {
+ boolean checkCondition();
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/83fd8f60/utils/src/main/java/com/cloud/utils/ProcessUtil.java
----------------------------------------------------------------------
diff --git a/utils/src/main/java/com/cloud/utils/ProcessUtil.java b/utils/src/main/java/com/cloud/utils/ProcessUtil.java
new file mode 100644
index 0000000..53137c4
--- /dev/null
+++ b/utils/src/main/java/com/cloud/utils/ProcessUtil.java
@@ -0,0 +1,112 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package com.cloud.utils;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Properties;
+
+import javax.naming.ConfigurationException;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.log4j.Logger;
+
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.script.OutputInterpreter;
+import com.cloud.utils.script.Script;
+
+public class ProcessUtil {
+ private static final Logger s_logger = Logger.getLogger(ProcessUtil.class.getName());
+
+ // paths cannot be hardcoded
+ public static void pidCheck(String pidDir, String run) throws ConfigurationException {
+
+ String dir = pidDir == null ? "/var/run" : pidDir;
+
+ try {
+ final File propsFile = PropertiesUtil.findConfigFile("environment.properties");
+ if (propsFile == null) {
+ s_logger.debug("environment.properties could not be opened");
+ } else {
+ final Properties props = PropertiesUtil.loadFromFile(propsFile);
+ dir = props.getProperty("paths.pid");
+ if (dir == null) {
+ dir = pidDir == null ? "/var/run" : pidDir;
+ }
+ }
+ } catch (IOException e) {
+ s_logger.debug("environment.properties could not be opened");
+ }
+
+ final File pidFile = new File(dir + File.separator + run);
+ try {
+ if (!pidFile.createNewFile()) {
+ if (!pidFile.exists()) {
+ throw new ConfigurationException("Unable to write to " + pidFile.getAbsolutePath() + ". Are you sure you're running as root?");
+ }
+
+ final String pidLine = FileUtils.readFileToString(pidFile).trim();
+ if (pidLine.isEmpty()) {
+ throw new ConfigurationException("Java process is being started twice. If this is not true, remove " + pidFile.getAbsolutePath());
+ }
+ try {
+ final long pid = Long.parseLong(pidLine);
+ final Script script = new Script("bash", 120000, s_logger);
+ script.add("-c", "ps -p " + pid);
+ final String result = script.execute();
+ if (result == null) {
+ throw new ConfigurationException("Java process is being started twice. If this is not true, remove " + pidFile.getAbsolutePath());
+ }
+ if (!pidFile.delete()) {
+ throw new ConfigurationException("Java process is being started twice. If this is not true, remove " + pidFile.getAbsolutePath());
+ }
+ if (!pidFile.createNewFile()) {
+ throw new ConfigurationException("Java process is being started twice. If this is not true, remove " + pidFile.getAbsolutePath());
+ }
+ } catch (final NumberFormatException e) {
+ throw new ConfigurationException("Java process is being started twice. If this is not true, remove " + pidFile.getAbsolutePath());
+ }
+ }
+ pidFile.deleteOnExit();
+
+ final Script script = new Script("bash", 120000, s_logger);
+ script.add("-c", "echo $PPID");
+ final OutputInterpreter.OneLineParser parser = new OutputInterpreter.OneLineParser();
+ script.execute(parser);
+
+ final String pid = parser.getLine();
+
+ FileUtils.writeStringToFile(pidFile, pid + "\n");
+ } catch (final IOException e) {
+ throw new CloudRuntimeException("Unable to create the " + pidFile.getAbsolutePath() + ". Are you running as root?", e);
+ }
+ }
+
+ public static String dumpStack() {
+ StringBuilder sb = new StringBuilder();
+ StackTraceElement[] elems = Thread.currentThread().getStackTrace();
+ if (elems != null && elems.length > 0) {
+ for (StackTraceElement elem : elems) {
+ sb.append("\tat ").append(elem.getMethodName()).append("(").append(elem.getFileName()).append(":").append(elem.getLineNumber()).append(")\n");
+ }
+ }
+ return sb.toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/83fd8f60/utils/src/main/java/com/cloud/utils/Profiler.java
----------------------------------------------------------------------
diff --git a/utils/src/main/java/com/cloud/utils/Profiler.java b/utils/src/main/java/com/cloud/utils/Profiler.java
new file mode 100644
index 0000000..f8e44bd
--- /dev/null
+++ b/utils/src/main/java/com/cloud/utils/Profiler.java
@@ -0,0 +1,91 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package com.cloud.utils;
+
+public class Profiler {
+
+ private static final long MILLIS_FACTOR = 1000l;
+ private static final double EXPONENT = 2d;
+
+
+ private Long startTickNanoSeconds;
+ private Long stopTickNanoSeconds;
+
+ public long start() {
+ startTickNanoSeconds = System.nanoTime();
+ return startTickNanoSeconds;
+ }
+
+ public long stop() {
+ stopTickNanoSeconds = System.nanoTime();
+ return stopTickNanoSeconds;
+ }
+
+ /**
+ * 1 millisecond = 1e+6 nanoseconds
+ * 1 second = 1000 milliseconds = 1e+9 nanoseconds
+ *
+ * @return the duration in nanoseconds.
+ */
+ public long getDuration() {
+ if (startTickNanoSeconds != null && stopTickNanoSeconds != null) {
+ final long timeInNanoSeconds = stopTickNanoSeconds - startTickNanoSeconds;
+ return timeInNanoSeconds;
+ }
+
+ return -1;
+ }
+
+ /**
+ * 1 millisecond = 1e+6 nanoseconds
+ * 1 second = 1000 millisecond = 1e+9 nanoseconds
+ *
+ * @return the duration in milliseconds.
+ */
+ public long getDurationInMillis() {
+ if (startTickNanoSeconds != null && stopTickNanoSeconds != null) {
+ final long timeInMillis = (stopTickNanoSeconds - startTickNanoSeconds) / (long)Math.pow(MILLIS_FACTOR, EXPONENT);
+ return timeInMillis;
+ }
+
+ return -1;
+ }
+
+ public boolean isStarted() {
+ return startTickNanoSeconds != null;
+ }
+
+ public boolean isStopped() {
+ return stopTickNanoSeconds != null;
+ }
+
+ @Override
+ public String toString() {
+ if (startTickNanoSeconds == null) {
+ return "Not Started";
+ }
+
+ if (stopTickNanoSeconds == null) {
+ return "Started but not stopped";
+ }
+
+ return "Done. Duration: " + getDurationInMillis() + "ms";
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/83fd8f60/utils/src/main/java/com/cloud/utils/PropertiesUtil.java
----------------------------------------------------------------------
diff --git a/utils/src/main/java/com/cloud/utils/PropertiesUtil.java b/utils/src/main/java/com/cloud/utils/PropertiesUtil.java
new file mode 100644
index 0000000..4cb89f7
--- /dev/null
+++ b/utils/src/main/java/com/cloud/utils/PropertiesUtil.java
@@ -0,0 +1,196 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package com.cloud.utils;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+import org.apache.log4j.Logger;
+
+public class PropertiesUtil {
+ private static final Logger s_logger = Logger.getLogger(PropertiesUtil.class);
+
+ /**
+ * Searches the class path and local paths to find the config file.
+ * @param path path to find. if it starts with / then it's absolute path.
+ * @return File or null if not found at all.
+ */
+
+ public static File findConfigFile(String path) {
+ ClassLoader cl = PropertiesUtil.class.getClassLoader();
+ URL url = cl.getResource(path);
+
+ if (url != null && "file".equals(url.getProtocol())) {
+ return new File(url.getFile());
+ }
+
+ url = ClassLoader.getSystemResource(path);
+ if (url != null && "file".equals(url.getProtocol())) {
+ return new File(url.getFile());
+ }
+
+ File file = new File(path);
+ if (file.exists()) {
+ return file;
+ }
+
+ String newPath = "conf" + (path.startsWith(File.separator) ? "" : "/") + path;
+ url = ClassLoader.getSystemResource(newPath);
+ if (url != null && "file".equals(url.getProtocol())) {
+ return new File(url.getFile());
+ }
+
+ url = cl.getResource(newPath);
+ if (url != null && "file".equals(url.getProtocol())) {
+ return new File(url.getFile());
+ }
+
+ newPath = "conf" + (path.startsWith(File.separator) ? "" : File.separator) + path;
+ file = new File(newPath);
+ if (file.exists()) {
+ return file;
+ }
+
+ newPath = System.getProperty("catalina.home");
+ if (newPath == null) {
+ newPath = System.getenv("CATALINA_HOME");
+ }
+
+ if (newPath == null) {
+ newPath = System.getenv("CATALINA_BASE");
+ }
+
+ if (newPath == null) {
+ return null;
+ }
+
+ file = new File(newPath + File.separator + "conf" + File.separator + path);
+ if (file.exists()) {
+ return file;
+ }
+
+ return null;
+ }
+
+ public static Map<String, Object> toMap(Properties props) {
+ Set<String> names = props.stringPropertyNames();
+ HashMap<String, Object> map = new HashMap<String, Object>(names.size());
+ for (String name : names) {
+ map.put(name, props.getProperty(name));
+ }
+
+ return map;
+ }
+
+ /*
+ * Returns an InputStream for the given resource
+ * This is needed to read the files within a jar in classpath.
+ */
+ public static InputStream openStreamFromURL(String path) {
+ ClassLoader cl = PropertiesUtil.class.getClassLoader();
+ URL url = cl.getResource(path);
+ if (url != null) {
+ try {
+ InputStream stream = url.openStream();
+ return stream;
+ } catch (IOException ioex) {
+ return null;
+ }
+ }
+ return null;
+ }
+
+ public static void loadFromJar(Properties properties, String configFile) throws IOException {
+ InputStream stream = PropertiesUtil.openStreamFromURL(configFile);
+ if (stream != null) {
+ properties.load(stream);
+ } else {
+ s_logger.error("Unable to find properties file: " + configFile);
+ }
+ }
+
+ // Returns key=value pairs by parsing a commands.properties/config file
+ // with syntax; key=cmd;value (with this syntax cmd is stripped) and key=value
+ public static Map<String, String> processConfigFile(String[] configFiles) {
+ Map<String, String> configMap = new HashMap<String, String>();
+ Properties preProcessedCommands = new Properties();
+ for (String configFile : configFiles) {
+ File commandsFile = findConfigFile(configFile);
+ if (commandsFile != null) {
+ try {
+ loadFromFile(preProcessedCommands, commandsFile);
+ } catch (IOException ioe) {
+ s_logger.error("IO Exception loading properties file", ioe);
+ }
+ }
+ else {
+ // in case of a file within a jar in classpath, try to open stream using url
+ try {
+ loadFromJar(preProcessedCommands, configFile);
+ } catch (IOException e) {
+ s_logger.error("IO Exception loading properties file from jar", e);
+ }
+ }
+ }
+
+ for (Object key : preProcessedCommands.keySet()) {
+ String preProcessedCommand = preProcessedCommands.getProperty((String)key);
+ int splitIndex = preProcessedCommand.lastIndexOf(";");
+ String value = preProcessedCommand.substring(splitIndex + 1);
+ configMap.put((String)key, value);
+ }
+
+ return configMap;
+ }
+
+ /**
+ * Load a Properties object with contents from a File.
+ * @param properties the properties object to be loaded
+ * @param file the file to load from
+ * @throws IOException
+ */
+ public static void loadFromFile(final Properties properties, final File file)
+ throws IOException {
+ try (final InputStream stream = new FileInputStream(file)) {
+ properties.load(stream);
+ }
+ }
+
+ /**
+ * Load the file and return the contents as a Properties object.
+ * @param file the file to load
+ * @return A Properties object populated
+ * @throws IOException
+ */
+ public static Properties loadFromFile(final File file)
+ throws IOException {
+ final Properties properties = new Properties();
+ loadFromFile(properties, file);
+ return properties;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/83fd8f60/utils/src/main/java/com/cloud/utils/ReflectUtil.java
----------------------------------------------------------------------
diff --git a/utils/src/main/java/com/cloud/utils/ReflectUtil.java b/utils/src/main/java/com/cloud/utils/ReflectUtil.java
new file mode 100644
index 0000000..c8ae954
--- /dev/null
+++ b/utils/src/main/java/com/cloud/utils/ReflectUtil.java
@@ -0,0 +1,213 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package com.cloud.utils;
+
+import static java.beans.Introspector.getBeanInfo;
+import static java.util.Collections.emptyList;
+import static java.util.Collections.unmodifiableList;
+
+import java.beans.BeanInfo;
+import java.beans.IntrospectionException;
+import java.beans.PropertyDescriptor;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.log4j.Logger;
+import org.reflections.Reflections;
+import org.reflections.util.ConfigurationBuilder;
+import org.reflections.util.ClasspathHelper;
+import org.reflections.scanners.SubTypesScanner;
+import org.reflections.scanners.TypeAnnotationsScanner;
+
+import com.google.common.collect.ImmutableSet;
+
+import com.cloud.utils.exception.CloudRuntimeException;
+
+public class ReflectUtil {
+
+ private static final Logger s_logger = Logger.getLogger(ReflectUtil.class);
+ private static final Logger logger = Logger.getLogger(Reflections.class);
+
+ public static Pair<Class<?>, Field> getAnyField(Class<?> clazz, String fieldName) {
+ try {
+ return new Pair<Class<?>, Field>(clazz, clazz.getDeclaredField(fieldName));
+ } catch (SecurityException e) {
+ throw new CloudRuntimeException("How the heck?", e);
+ } catch (NoSuchFieldException e) {
+ // Do I really want this? No I don't but what can I do? It only throws the NoSuchFieldException.
+ Class<?> parent = clazz.getSuperclass();
+ if (parent != null) {
+ return getAnyField(parent, fieldName);
+ }
+ return null;
+ }
+ }
+
+ // Gets all classes with some annotation from a package
+ public static Set<Class<?>> getClassesWithAnnotation(Class<? extends Annotation> annotation, String[] packageNames) {
+ Reflections reflections;
+ Set<Class<?>> classes = new HashSet<Class<?>>();
+ ConfigurationBuilder builder=new ConfigurationBuilder();
+ for (String packageName : packageNames) {
+ builder.addUrls(ClasspathHelper.forPackage(packageName));
+ }
+ builder.setScanners(new SubTypesScanner(),new TypeAnnotationsScanner());
+ reflections = new Reflections(builder);
+ classes.addAll(reflections.getTypesAnnotatedWith(annotation));
+ return classes;
+ }
+
+ // Checks against posted search classes if cmd is async
+ public static boolean isCmdClassAsync(Class<?> cmdClass, Class<?>[] searchClasses) {
+ boolean isAsync = false;
+ Class<?> superClass = cmdClass;
+
+ while (superClass != null && superClass != Object.class) {
+ String superName = superClass.getName();
+ for (Class<?> baseClass : searchClasses) {
+ if (superName.equals(baseClass.getName())) {
+ isAsync = true;
+ break;
+ }
+ }
+ if (isAsync)
+ break;
+ superClass = superClass.getSuperclass();
+ }
+ return isAsync;
+ }
+
+ // Returns all fields until a base class for a cmd class
+ public static List<Field> getAllFieldsForClass(Class<?> cmdClass, Class<?> baseClass) {
+ List<Field> fields = new ArrayList<Field>();
+ Collections.addAll(fields, cmdClass.getDeclaredFields());
+ Class<?> superClass = cmdClass.getSuperclass();
+ while (baseClass.isAssignableFrom(superClass) && baseClass != superClass) {
+ Field[] superClassFields = superClass.getDeclaredFields();
+ if (superClassFields != null)
+ Collections.addAll(fields, superClassFields);
+ superClass = superClass.getSuperclass();
+ }
+ return fields;
+ }
+
+ /**
+ * Returns all unique fields except excludeClasses for a cmd class
+ * @param cmdClass the class in which fields should be collected
+ * @param excludeClasses the classes whose fields must be ignored
+ * @return list of fields
+ */
+ public static Set<Field> getAllFieldsForClass(Class<?> cmdClass, Class<?>[] excludeClasses) {
+ Set<Field> fields = new HashSet<Field>();
+ Collections.addAll(fields, cmdClass.getDeclaredFields());
+ Class<?> superClass = cmdClass.getSuperclass();
+
+ while (superClass != null && superClass != Object.class) {
+ String superName = superClass.getName();
+ boolean isNameEqualToSuperName = false;
+ for (Class<?> baseClass : excludeClasses) {
+ if (superName.equals(baseClass.getName())) {
+ isNameEqualToSuperName = true;
+ }
+ }
+
+ if (!isNameEqualToSuperName) {
+ Field[] superClassFields = superClass.getDeclaredFields();
+ if (superClassFields != null) {
+ Collections.addAll(fields, superClassFields);
+ }
+ }
+ superClass = superClass.getSuperclass();
+ }
+ return fields;
+ }
+
+ public static List<String> flattenProperties(final Object target, final Class<?> clazz) {
+ return flattenPropeties(target, clazz, "class");
+ }
+
+ public static List<String> flattenPropeties(final Object target, final Class<?> clazz, final String... excludedProperties) {
+ return flattenProperties(target, clazz, ImmutableSet.copyOf(excludedProperties));
+ }
+
+ private static List<String> flattenProperties(final Object target, final Class<?> clazz, final ImmutableSet<String> excludedProperties) {
+
+ assert clazz != null;
+
+ if (target == null) {
+ return emptyList();
+ }
+
+ assert clazz.isAssignableFrom(target.getClass());
+
+ try {
+
+ final BeanInfo beanInfo = getBeanInfo(clazz);
+ final PropertyDescriptor[] descriptors = beanInfo.getPropertyDescriptors();
+
+ final List<String> serializedProperties = new ArrayList<String>();
+ for (final PropertyDescriptor descriptor : descriptors) {
+
+ if (excludedProperties.contains(descriptor.getName())) {
+ continue;
+ }
+
+ serializedProperties.add(descriptor.getName());
+ final Object value = descriptor.getReadMethod().invoke(target);
+ serializedProperties.add(value != null ? value.toString() : "null");
+
+ }
+
+ return unmodifiableList(serializedProperties);
+
+ } catch (IntrospectionException e) {
+ s_logger.warn("Ignored IntrospectionException when serializing class " + target.getClass().getCanonicalName(), e);
+ } catch (IllegalArgumentException e) {
+ s_logger.warn("Ignored IllegalArgumentException when serializing class " + target.getClass().getCanonicalName(), e);
+ } catch (IllegalAccessException e) {
+ s_logger.warn("Ignored IllegalAccessException when serializing class " + target.getClass().getCanonicalName(), e);
+ } catch (InvocationTargetException e) {
+ s_logger.warn("Ignored InvocationTargetException when serializing class " + target.getClass().getCanonicalName(), e);
+ }
+
+ return emptyList();
+
+ }
+
+ public static String getEntityName(Class clz){
+ if(clz == null)
+ return null;
+
+ String entityName = clz.getName();
+ int index = entityName.lastIndexOf(".");
+ if (index != -1) {
+ return entityName.substring(index + 1);
+ }else{
+ return entityName;
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/83fd8f60/utils/src/main/java/com/cloud/utils/ReflectionUse.java
----------------------------------------------------------------------
diff --git a/utils/src/main/java/com/cloud/utils/ReflectionUse.java b/utils/src/main/java/com/cloud/utils/ReflectionUse.java
new file mode 100644
index 0000000..a5a78e2
--- /dev/null
+++ b/utils/src/main/java/com/cloud/utils/ReflectionUse.java
@@ -0,0 +1,31 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package com.cloud.utils;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+@Target({METHOD})
+@Retention(RUNTIME)
+public @interface ReflectionUse {
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/83fd8f60/utils/src/main/java/com/cloud/utils/S3Utils.java
----------------------------------------------------------------------
diff --git a/utils/src/main/java/com/cloud/utils/S3Utils.java b/utils/src/main/java/com/cloud/utils/S3Utils.java
new file mode 100644
index 0000000..6efe76b
--- /dev/null
+++ b/utils/src/main/java/com/cloud/utils/S3Utils.java
@@ -0,0 +1,603 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package com.cloud.utils;
+
+import static com.amazonaws.Protocol.HTTP;
+import static com.amazonaws.Protocol.HTTPS;
+import static com.cloud.utils.StringUtils.join;
+import static java.io.File.createTempFile;
+import static java.lang.String.format;
+import static java.lang.System.currentTimeMillis;
+import static java.util.Collections.emptyList;
+import static java.util.Collections.singletonList;
+import static java.util.Collections.unmodifiableList;
+import static org.apache.commons.lang.ArrayUtils.isEmpty;
+import static org.apache.commons.lang.StringUtils.isBlank;
+import static org.apache.commons.lang.StringUtils.isNotBlank;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.UUID;
+
+import org.apache.commons.lang.ArrayUtils;
+import org.apache.log4j.Logger;
+
+import com.amazonaws.AmazonClientException;
+import com.amazonaws.ClientConfiguration;
+import com.amazonaws.HttpMethod;
+import com.amazonaws.auth.AWSCredentials;
+import com.amazonaws.auth.BasicAWSCredentials;
+import com.amazonaws.services.s3.AmazonS3;
+import com.amazonaws.services.s3.AmazonS3Client;
+import com.amazonaws.services.s3.model.Bucket;
+import com.amazonaws.services.s3.model.CannedAccessControlList;
+import com.amazonaws.services.s3.model.GetObjectRequest;
+import com.amazonaws.services.s3.model.ListObjectsRequest;
+import com.amazonaws.services.s3.model.ObjectListing;
+import com.amazonaws.services.s3.model.ObjectMetadata;
+import com.amazonaws.services.s3.model.PutObjectRequest;
+import com.amazonaws.services.s3.model.S3Object;
+import com.amazonaws.services.s3.model.S3ObjectSummary;
+import com.amazonaws.services.s3.transfer.TransferManager;
+import com.amazonaws.services.s3.transfer.Upload;
+import com.cloud.utils.exception.CloudRuntimeException;
+
+public final class S3Utils {
+
+ private static final Logger LOGGER = Logger.getLogger(S3Utils.class);
+
+ public static final String SEPARATOR = "/";
+
+ private static final int MIN_BUCKET_NAME_LENGTH = 3;
+ private static final int MAX_BUCKET_NAME_LENGTH = 63;
+
+ private S3Utils() {
+ super();
+ }
+
+ public static AmazonS3 acquireClient(final ClientOptions clientOptions) {
+
+ final AWSCredentials credentials = new BasicAWSCredentials(clientOptions.getAccessKey(), clientOptions.getSecretKey());
+
+ final ClientConfiguration configuration = new ClientConfiguration();
+
+ if (clientOptions.isHttps() != null) {
+ configuration.setProtocol(clientOptions.isHttps() == true ? HTTPS : HTTP);
+ }
+
+ if (clientOptions.getConnectionTimeout() != null) {
+ configuration.setConnectionTimeout(clientOptions.getConnectionTimeout());
+ }
+
+ if (clientOptions.getMaxErrorRetry() != null) {
+ configuration.setMaxErrorRetry(clientOptions.getMaxErrorRetry());
+ }
+
+ if (clientOptions.getSocketTimeout() != null) {
+ configuration.setSocketTimeout(clientOptions.getSocketTimeout());
+ }
+
+ if (clientOptions.getUseTCPKeepAlive() != null) {
+ //configuration.setUseTcpKeepAlive(clientOptions.getUseTCPKeepAlive());
+ LOGGER.debug("useTCPKeepAlive not supported by old AWS SDK");
+ }
+
+ if (clientOptions.getConnectionTtl() != null) {
+ //configuration.setConnectionTTL(clientOptions.getConnectionTtl());
+ LOGGER.debug("connectionTtl not supported by old AWS SDK");
+ }
+
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug(format("Creating S3 client with configuration: [protocol: %1$s, connectionTimeOut: " + "%2$s, maxErrorRetry: %3$s, socketTimeout: %4$s, useTCPKeepAlive: %5$s, connectionTtl: %6$s]",
+ configuration.getProtocol(), configuration.getConnectionTimeout(), configuration.getMaxErrorRetry(), configuration.getSocketTimeout(),
+ -1, -1));
+ }
+
+ final AmazonS3Client client = new AmazonS3Client(credentials, configuration);
+
+ if (isNotBlank(clientOptions.getEndPoint())) {
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug(format("Setting the end point for S3 client %1$s to %2$s.", client, clientOptions.getEndPoint()));
+ }
+ client.setEndpoint(clientOptions.getEndPoint());
+ }
+
+ return client;
+
+ }
+
+ public static void putFile(final ClientOptions clientOptions, final File sourceFile, final String bucketName, final String key) {
+
+ assert clientOptions != null;
+ assert sourceFile != null;
+ assert !isBlank(bucketName);
+ assert !isBlank(key);
+
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug(format("Sending file %1$s as S3 object %2$s in " + "bucket %3$s", sourceFile.getName(), key, bucketName));
+ }
+
+ acquireClient(clientOptions).putObject(bucketName, key, sourceFile);
+
+ }
+
+ public static void putObject(final ClientOptions clientOptions, final InputStream sourceStream, final String bucketName, final String key) {
+
+ assert clientOptions != null;
+ assert sourceStream != null;
+ assert !isBlank(bucketName);
+ assert !isBlank(key);
+
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug(format("Sending stream as S3 object %1$s in " + "bucket %2$s", key, bucketName));
+ }
+
+ acquireClient(clientOptions).putObject(bucketName, key, sourceStream, null);
+
+ }
+
+ public static void putObject(final ClientOptions clientOptions, final PutObjectRequest req) {
+
+ assert clientOptions != null;
+ assert req != null;
+
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug(format("Sending stream as S3 object using PutObjectRequest"));
+ }
+
+ acquireClient(clientOptions).putObject(req);
+
+ }
+
+ // multi-part upload file
+ public static void mputFile(final ClientOptions clientOptions, final File sourceFile, final String bucketName, final String key) throws InterruptedException {
+
+ assert clientOptions != null;
+ assert sourceFile != null;
+ assert !isBlank(bucketName);
+ assert !isBlank(key);
+
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug(format("Multipart sending file %1$s as S3 object %2$s in " + "bucket %3$s", sourceFile.getName(), key, bucketName));
+ }
+ TransferManager tm = new TransferManager(S3Utils.acquireClient(clientOptions));
+ Upload upload = tm.upload(bucketName, key, sourceFile);
+ upload.waitForCompletion();
+ }
+
+ // multi-part upload object
+ public static void mputObject(final ClientOptions clientOptions, final InputStream sourceStream, final String bucketName, final String key)
+ throws InterruptedException {
+
+ assert clientOptions != null;
+ assert sourceStream != null;
+ assert !isBlank(bucketName);
+ assert !isBlank(key);
+
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug(format("Multipart sending stream as S3 object %1$s in " + "bucket %2$s", key, bucketName));
+ }
+ TransferManager tm = new TransferManager(S3Utils.acquireClient(clientOptions));
+ Upload upload = tm.upload(bucketName, key, sourceStream, null);
+ upload.waitForCompletion();
+ }
+
+ // multi-part upload object
+ public static void mputObject(final ClientOptions clientOptions, final PutObjectRequest req) throws InterruptedException {
+
+ assert clientOptions != null;
+ assert req != null;
+
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug("Multipart sending object to S3 using PutObjectRequest");
+ }
+ TransferManager tm = new TransferManager(S3Utils.acquireClient(clientOptions));
+ Upload upload = tm.upload(req);
+ upload.waitForCompletion();
+
+ }
+
+ public static void setObjectAcl(final ClientOptions clientOptions, final String bucketName, final String key, final CannedAccessControlList acl) {
+
+ assert clientOptions != null;
+ assert acl != null;
+
+ acquireClient(clientOptions).setObjectAcl(bucketName, key, acl);
+
+ }
+
+ public static URL generatePresignedUrl(final ClientOptions clientOptions, final String bucketName, final String key, final Date expiration) {
+
+ assert clientOptions != null;
+ assert !isBlank(bucketName);
+ assert !isBlank(key);
+
+ return acquireClient(clientOptions).generatePresignedUrl(bucketName, key, expiration, HttpMethod.GET);
+
+ }
+
+ // Note that whenever S3Object is returned, client code needs to close the internal stream to avoid resource leak.
+ public static S3Object getObject(final ClientOptions clientOptions, final String bucketName, final String key) {
+
+ assert clientOptions != null;
+ assert !isBlank(bucketName);
+ assert !isBlank(key);
+
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug(format("Get S3 object %1$s in " + "bucket %2$s", key, bucketName));
+ }
+
+ return acquireClient(clientOptions).getObject(bucketName, key);
+
+ }
+
+ @SuppressWarnings("unchecked")
+ public static File getFile(final ClientOptions clientOptions, final String bucketName, final String key, final File targetDirectory,
+ final FileNamingStrategy namingStrategy) {
+
+ assert clientOptions != null;
+ assert isNotBlank(bucketName);
+ assert isNotBlank(key);
+ assert targetDirectory != null && targetDirectory.isDirectory();
+ assert namingStrategy != null;
+
+ final AmazonS3 connection = acquireClient(clientOptions);
+
+ File tempFile = null;
+ try {
+
+ tempFile = createTempFile(join("-", targetDirectory.getName(), currentTimeMillis(), "part"), "tmp", targetDirectory);
+ tempFile.deleteOnExit();
+
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug(format("Downloading object %1$s from bucket %2$s to temp file %3$s", key, bucketName, tempFile.getName()));
+ }
+
+ try {
+ connection.getObject(new GetObjectRequest(bucketName, key), tempFile);
+ } catch (AmazonClientException ex) {
+ // hack to handle different ETAG format generated from RiakCS for multi-part uploaded object
+ String msg = ex.getMessage();
+ if (!msg.contains("verify integrity")) {
+ throw ex;
+ }
+ }
+
+ final File targetFile = new File(targetDirectory, namingStrategy.determineFileName(key));
+ tempFile.renameTo(targetFile);
+
+ return targetFile;
+
+ } catch (FileNotFoundException e) {
+
+ throw new CloudRuntimeException(format("Failed open file %1$s in order to get object %2$s from bucket %3$s.", targetDirectory.getAbsoluteFile(), bucketName,
+ key), e);
+
+ } catch (IOException e) {
+
+ throw new CloudRuntimeException(format("Unable to allocate temporary file in directory %1$s to download %2$s:%3$s from S3",
+ targetDirectory.getAbsolutePath(), bucketName, key), e);
+
+ } finally {
+
+ if (tempFile != null) {
+ tempFile.delete();
+ }
+
+ }
+
+ }
+
+ public static List<File> getDirectory(final ClientOptions clientOptions, final String bucketName, final String sourcePath, final File targetDirectory,
+ final FileNamingStrategy namingStrategy) {
+
+ assert clientOptions != null;
+ assert isNotBlank(bucketName);
+ assert isNotBlank(sourcePath);
+ assert targetDirectory != null;
+
+ final AmazonS3 connection = acquireClient(clientOptions);
+
+ // List the objects in the source directory on S3
+ final List<S3ObjectSummary> objectSummaries = listDirectory(bucketName, sourcePath, connection);
+ final List<File> files = new ArrayList<File>();
+
+ for (final S3ObjectSummary objectSummary : objectSummaries) {
+
+ files.add(getFile(clientOptions, bucketName, objectSummary.getKey(), targetDirectory, namingStrategy));
+
+ }
+
+ return unmodifiableList(files);
+
+ }
+
+ public static List<S3ObjectSummary> getDirectory(final ClientOptions clientOptions, final String bucketName, final String sourcePath) {
+ assert clientOptions != null;
+ assert isNotBlank(bucketName);
+ assert isNotBlank(sourcePath);
+
+ final AmazonS3 connection = acquireClient(clientOptions);
+
+ // List the objects in the source directory on S3
+ return listDirectory(bucketName, sourcePath, connection);
+ }
+
+ private static List<S3ObjectSummary> listDirectory(final String bucketName, final String directory, final AmazonS3 client) {
+
+ List<S3ObjectSummary> objects = new ArrayList<S3ObjectSummary>();
+ ListObjectsRequest listObjectsRequest = new ListObjectsRequest().withBucketName(bucketName).withPrefix(directory + SEPARATOR);
+
+ ObjectListing ol = client.listObjects(listObjectsRequest);
+ if(ol.isTruncated()) {
+ do {
+ objects.addAll(ol.getObjectSummaries());
+ listObjectsRequest.setMarker(ol.getNextMarker());
+ ol = client.listObjects(listObjectsRequest);
+ } while (ol.isTruncated());
+ }
+ else {
+ objects.addAll(ol.getObjectSummaries());
+ }
+
+ if (objects.isEmpty()) {
+ return emptyList();
+ }
+
+ return unmodifiableList(objects);
+ }
+
+ public static void putDirectory(final ClientOptions clientOptions, final String bucketName, final File directory, final FilenameFilter fileNameFilter,
+ final ObjectNamingStrategy namingStrategy) {
+
+ assert clientOptions != null;
+ assert isNotBlank(bucketName);
+ assert directory != null && directory.isDirectory();
+ assert fileNameFilter != null;
+ assert namingStrategy != null;
+
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug(format("Putting directory %1$s in S3 bucket %2$s.", directory.getAbsolutePath(), bucketName));
+ }
+
+ // Determine the list of files to be sent using the passed filter ...
+ final File[] files = directory.listFiles(fileNameFilter);
+
+ if (LOGGER.isTraceEnabled()) {
+ LOGGER.trace(format("Putting files (%1$s) in S3 bucket %2$s.", ArrayUtils.toString(files, "no files found"), bucketName));
+ }
+
+ // Skip spinning up an S3 connection when no files will be sent ...
+ if (isEmpty(files)) {
+ return;
+ }
+
+ final AmazonS3 client = acquireClient(clientOptions);
+
+ // Send the files to S3 using the passed ObjectNaming strategy to
+ // determine the key ...
+ for (final File file : files) {
+ final String key = namingStrategy.determineKey(file);
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug(format("Putting file %1$s into bucket %2$s with key %3$s.", file.getAbsolutePath(), bucketName, key));
+ }
+ client.putObject(bucketName, key, file);
+ }
+
+ }
+
+ public static void deleteObject(final ClientOptions clientOptions, final String bucketName, final String key) {
+
+ assert clientOptions != null;
+ assert isNotBlank(bucketName);
+ assert isNotBlank(key);
+
+ final AmazonS3 client = acquireClient(clientOptions);
+
+ client.deleteObject(bucketName, key);
+
+ }
+
+ public static void deleteDirectory(final ClientOptions clientOptions, final String bucketName, final String directoryName) {
+
+ assert clientOptions != null;
+ assert isNotBlank(bucketName);
+ assert isNotBlank(directoryName);
+
+ final AmazonS3 client = acquireClient(clientOptions);
+
+ final List<S3ObjectSummary> objects = listDirectory(bucketName, directoryName, client);
+
+ for (final S3ObjectSummary object : objects) {
+
+ client.deleteObject(bucketName, object.getKey());
+
+ }
+
+ client.deleteObject(bucketName, directoryName);
+
+ }
+
+ public static boolean canConnect(final ClientOptions clientOptions) {
+
+ try {
+
+ acquireClient(clientOptions);
+ return true;
+
+ } catch (AmazonClientException e) {
+
+ LOGGER.warn("Ignored Exception while checking connection options", e);
+ return false;
+
+ }
+
+ }
+
+ public static boolean doesBucketExist(final ClientOptions clientOptions, final String bucketName) {
+
+ assert clientOptions != null;
+ assert !isBlank(bucketName);
+
+ try {
+
+ final List<Bucket> buckets = acquireClient(clientOptions).listBuckets();
+
+ for (Bucket bucket : buckets) {
+ if (bucket.getName().equals(bucketName)) {
+ return true;
+ }
+ }
+
+ return false;
+
+ } catch (AmazonClientException e) {
+
+ LOGGER.warn("Ignored Exception while checking bucket existence", e);
+ return false;
+
+ }
+
+ }
+
+ public static boolean canReadWriteBucket(final ClientOptions clientOptions, final String bucketName) {
+
+ assert clientOptions != null;
+ assert isNotBlank(bucketName);
+
+ try {
+
+ final AmazonS3 client = acquireClient(clientOptions);
+
+ final String fileContent = "testing put and delete";
+ final InputStream inputStream = new ByteArrayInputStream(fileContent.getBytes());
+ final String key = UUID.randomUUID().toString() + ".txt";
+
+ final ObjectMetadata metadata = new ObjectMetadata();
+ metadata.setContentLength(fileContent.length());
+
+ client.putObject(bucketName, key, inputStream, metadata);
+ client.deleteObject(bucketName, key);
+
+ return true;
+
+ } catch (AmazonClientException e) {
+
+ return false;
+
+ }
+
+ }
+
+ public static List<String> checkClientOptions(ClientOptions clientOptions) {
+
+ assert clientOptions != null;
+
+ List<String> errorMessages = new ArrayList<String>();
+
+ errorMessages.addAll(checkRequiredField("access key", clientOptions.getAccessKey()));
+ errorMessages.addAll(checkRequiredField("secret key", clientOptions.getSecretKey()));
+
+ errorMessages.addAll(checkOptionalField("connection timeout", clientOptions.getConnectionTimeout()));
+ errorMessages.addAll(checkOptionalField("socket timeout", clientOptions.getSocketTimeout()));
+ errorMessages.addAll(checkOptionalField("max error retries", clientOptions.getMaxErrorRetry()));
+ errorMessages.addAll(checkOptionalField("connection ttl", clientOptions.getConnectionTtl()));
+
+ return unmodifiableList(errorMessages);
+
+ }
+
+ public static List<String> checkBucketName(final String bucketLabel, final String bucket) {
+
+ assert isNotBlank(bucketLabel);
+ assert isNotBlank(bucket);
+
+ final List<String> errorMessages = new ArrayList<String>();
+
+ if (bucket.length() < MIN_BUCKET_NAME_LENGTH) {
+ errorMessages.add(format("The length of %1$s " + "for the %2$s must have a length of at least %3$s " + "characters", bucket, bucketLabel,
+ MIN_BUCKET_NAME_LENGTH));
+ }
+
+ if (bucket.length() > MAX_BUCKET_NAME_LENGTH) {
+ errorMessages.add(format("The length of %1$s " + "for the %2$s must not have a length of at greater" + " than %3$s characters", bucket, bucketLabel,
+ MAX_BUCKET_NAME_LENGTH));
+ }
+
+ return unmodifiableList(errorMessages);
+
+ }
+
+ private static List<String> checkOptionalField(final String fieldName, final Integer fieldValue) {
+ if (fieldValue != null && fieldValue < 0) {
+ return singletonList(format("The value of %1$s must " + "be greater than zero.", fieldName));
+ }
+ return emptyList();
+ }
+
+ private static List<String> checkRequiredField(String fieldName, String fieldValue) {
+ if (isBlank(fieldValue)) {
+ return singletonList(format("A %1$s must be specified.", fieldName));
+ }
+ return emptyList();
+ }
+
+ public interface ClientOptions {
+
+ String getAccessKey();
+
+ String getSecretKey();
+
+ String getEndPoint();
+
+ Boolean isHttps();
+
+ Integer getConnectionTimeout();
+
+ Integer getMaxErrorRetry();
+
+ Integer getSocketTimeout();
+
+ Boolean getUseTCPKeepAlive();
+
+ Integer getConnectionTtl();
+ }
+
+ public interface ObjectNamingStrategy {
+
+ String determineKey(File file);
+
+ }
+
+ public interface FileNamingStrategy {
+
+ String determineFileName(String key);
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/83fd8f60/utils/src/main/java/com/cloud/utils/SerialVersionUID.java
----------------------------------------------------------------------
diff --git a/utils/src/main/java/com/cloud/utils/SerialVersionUID.java b/utils/src/main/java/com/cloud/utils/SerialVersionUID.java
new file mode 100644
index 0000000..e4ea217
--- /dev/null
+++ b/utils/src/main/java/com/cloud/utils/SerialVersionUID.java
@@ -0,0 +1,69 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+package com.cloud.utils;
+
+/**
+ * purposes. This is purely on an honor system though. You should always
+ **/
+public interface SerialVersionUID {
+ public static final long Base = 0x564D4F70 << 32; // 100 brownie points if you guess what this is and tell me.
+
+ public static final long UUID = Base | 0x1;
+ public static final long CloudRuntimeException = Base | 0x2;
+ public static final long CloudStartupServlet = Base | 0x3;
+ public static final long CloudServiceImpl = Base | 0x4;
+ public static final long AccountLimitException = Base | 0x5;
+ public static final long InsufficientVirtualNetworkCapacityException = Base | 0x7;
+ public static final long NetworkUnavailableException = Base | 0x8;
+ public static final long Ip = Base | 0x9;
+ public static final long UnsupportedVersionException = Base | 0xb;
+ public static final long DataCenterIpAddressPK = Base | 0xc;
+ public static final long UnableToExecuteException = Base | 0xd;
+ public static final long ExecutionException = Base | 0xe;
+ public static final long VnetKey = Base | 0xf;
+ public static final long InsufficientServerCapacityException = Base | 0x10;
+ public static final long InsufficientAddressCapacityException = Base | 0x11;
+ public static final long ManagementServerException = Base | 0x12;
+ public static final long HAStateException = Base | 0x13;
+ public static final long InsufficientStorageCapacityException = Base | 0x14;
+ public static final long InsufficientCapacityException = Base | 0x15;
+ public static final long ConcurrentOperationException = Base | 0x16;
+ public static final long AgentUnavailableException = Base | 0x17;
+ public static final long OperationTimedoutException = Base | 0x18;
+ public static final long StorageUnavailableException = Base | 0x19;
+ public static final long InfficientVirtualNetworkCapacityException = Base | 0x1a;
+ public static final long DiscoveryException = Base | 0x1b;
+ public static final long ConflictingNetworkSettingException = Base | 0x1c;
+ public static final long CloudAuthenticationException = Base | 0x1d;
+ public static final long AsyncCommandQueued = Base | 0x1e;
+ public static final long ResourceUnavailableException = Base | 0x1f;
+ public static final long ConnectionException = Base | 0x20;
+ public static final long PermissionDeniedException = Base | 0x21;
+ public static final long sshException = Base | 0x22;
+ public static final long HttpCallException = Base | 0x23;
+ public static final long VirtualMachineMigrationException = Base | 0x24;
+ public static final long DiscoveredWithErrorException = Base | 0x25;
+ public static final long NoTransitionException = Base | 0x26;
+ public static final long CloudExecutionException = Base | 0x27;
+ public static final long CallFailedException = Base | 0x28;
+ public static final long UnableDeleteHostException = Base | 0x29;
+ public static final long AffinityConflictException = Base | 0x2a;
+ public static final long JobCancellationException = Base | 0x2b;
+}