cloudstack-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From sate...@apache.org
Subject [16/50] [abbrv] git commit: updated refs/heads/deploy-from-snapshot to 44ba14d
Date Thu, 16 Jun 2016 08:12:17 GMT
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/83fd8f60/utils/src/main/java/com/cloud/utils/exception/ExceptionUtil.java
----------------------------------------------------------------------
diff --git a/utils/src/main/java/com/cloud/utils/exception/ExceptionUtil.java b/utils/src/main/java/com/cloud/utils/exception/ExceptionUtil.java
new file mode 100644
index 0000000..351d2ab
--- /dev/null
+++ b/utils/src/main/java/com/cloud/utils/exception/ExceptionUtil.java
@@ -0,0 +1,54 @@
+//
+// 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.exception;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+public class ExceptionUtil {
+    public static String toString(Throwable th) {
+        return toString(th, true);
+    }
+
+    public static String toString(Throwable th, boolean printStack) {
+        final StringWriter writer = new StringWriter();
+        writer.append("Exception: " + th.getClass().getName() + "\n");
+        writer.append("Message: ");
+        writer.append(th.getMessage()).append("\n");
+
+        if (printStack) {
+            writer.append("Stack: ");
+            th.printStackTrace(new PrintWriter(writer));
+        }
+        return writer.toString();
+    }
+
+    @SuppressWarnings("unchecked")
+    public static <T extends Throwable> void rethrow(Throwable t, Class<T> clz) throws T {
+        if (clz.isAssignableFrom(t.getClass()))
+            throw (T)t;
+    }
+
+    public static <T extends Throwable> void rethrowRuntime(Throwable t) {
+        rethrow(t, RuntimeException.class);
+        rethrow(t, Error.class);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/83fd8f60/utils/src/main/java/com/cloud/utils/exception/ExecutionException.java
----------------------------------------------------------------------
diff --git a/utils/src/main/java/com/cloud/utils/exception/ExecutionException.java b/utils/src/main/java/com/cloud/utils/exception/ExecutionException.java
new file mode 100644
index 0000000..7b3bc61
--- /dev/null
+++ b/utils/src/main/java/com/cloud/utils/exception/ExecutionException.java
@@ -0,0 +1,49 @@
+//
+// 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.exception;
+
+import com.cloud.utils.SerialVersionUID;
+
+/**
+ * a public method.
+ *
+ */
+public class ExecutionException extends Exception {
+    private static final long serialVersionUID = SerialVersionUID.ExecutionException;
+
+    protected int csErrorCode;
+
+    public ExecutionException(String msg, Throwable cause) {
+        super(msg, cause);
+        setCSErrorCode(CSExceptionErrorCode.getCSErrCode(this.getClass().getName()));
+    }
+
+    public ExecutionException(String msg) {
+        super(msg);
+    }
+
+    public void setCSErrorCode(int cserrcode) {
+        this.csErrorCode = cserrcode;
+    }
+
+    public int getCSErrorCode() {
+        return this.csErrorCode;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/83fd8f60/utils/src/main/java/com/cloud/utils/exception/HypervisorVersionChangedException.java
----------------------------------------------------------------------
diff --git a/utils/src/main/java/com/cloud/utils/exception/HypervisorVersionChangedException.java b/utils/src/main/java/com/cloud/utils/exception/HypervisorVersionChangedException.java
new file mode 100644
index 0000000..55c273b
--- /dev/null
+++ b/utils/src/main/java/com/cloud/utils/exception/HypervisorVersionChangedException.java
@@ -0,0 +1,35 @@
+//
+// 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.exception;
+
+import com.cloud.utils.SerialVersionUID;
+
+public class HypervisorVersionChangedException extends CloudRuntimeException {
+
+    private static final long serialVersionUID = SerialVersionUID.CloudRuntimeException;
+
+    public HypervisorVersionChangedException(String message) {
+        super(message);
+    }
+
+    protected HypervisorVersionChangedException() {
+        super();
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/83fd8f60/utils/src/main/java/com/cloud/utils/fsm/ChangeEvent.java
----------------------------------------------------------------------
diff --git a/utils/src/main/java/com/cloud/utils/fsm/ChangeEvent.java b/utils/src/main/java/com/cloud/utils/fsm/ChangeEvent.java
new file mode 100644
index 0000000..15f4f6e
--- /dev/null
+++ b/utils/src/main/java/com/cloud/utils/fsm/ChangeEvent.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.fsm;
+
+public class ChangeEvent {
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/83fd8f60/utils/src/main/java/com/cloud/utils/fsm/FiniteState.java
----------------------------------------------------------------------
diff --git a/utils/src/main/java/com/cloud/utils/fsm/FiniteState.java b/utils/src/main/java/com/cloud/utils/fsm/FiniteState.java
new file mode 100644
index 0000000..e6f2cd0
--- /dev/null
+++ b/utils/src/main/java/com/cloud/utils/fsm/FiniteState.java
@@ -0,0 +1,58 @@
+//
+// 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.fsm;
+
+import java.util.List;
+import java.util.Set;
+
+/**
+ *
+ * @param <S> State
+ * @param <E> Event
+ */
+public interface FiniteState<S, E> {
+    /**
+     * @return the state machine being used.
+     */
+    StateMachine<S, E> getStateMachine();
+
+    /**
+     * get next state based on the event.
+     * @param event
+     * @return next State
+     */
+    S getNextState(E event);
+
+    /**
+     * Get the states that could have traveled to the current state
+     * via this event.
+     * @param event
+     * @return array of states
+     */
+    List<S> getFromStates(E event);
+
+    /**
+     * Get the possible events that can happen from the current state.
+     * @return array of events.
+     */
+    Set<E> getPossibleEvents();
+
+    String getDescription();
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/83fd8f60/utils/src/main/java/com/cloud/utils/fsm/FiniteState2.java
----------------------------------------------------------------------
diff --git a/utils/src/main/java/com/cloud/utils/fsm/FiniteState2.java b/utils/src/main/java/com/cloud/utils/fsm/FiniteState2.java
new file mode 100644
index 0000000..14b9a5e
--- /dev/null
+++ b/utils/src/main/java/com/cloud/utils/fsm/FiniteState2.java
@@ -0,0 +1,34 @@
+//
+// 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.fsm;
+
+import java.util.Set;
+
+public interface FiniteState2<T, E> {
+
+    StateMachine2<T, ? extends ChangeEvent, ? extends StateObject<?>> getStateMachine();
+
+    T getNextState(ChangeEvent e) throws NoTransitionException;
+
+    T getFromStates(ChangeEvent e);
+
+    Set<ChangeEvent> getPossibleEvents();
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/83fd8f60/utils/src/main/java/com/cloud/utils/fsm/FiniteStateObject.java
----------------------------------------------------------------------
diff --git a/utils/src/main/java/com/cloud/utils/fsm/FiniteStateObject.java b/utils/src/main/java/com/cloud/utils/fsm/FiniteStateObject.java
new file mode 100644
index 0000000..a57e3b4
--- /dev/null
+++ b/utils/src/main/java/com/cloud/utils/fsm/FiniteStateObject.java
@@ -0,0 +1,25 @@
+//
+// 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.fsm;
+
+public interface FiniteStateObject<S, E> {
+
+    void setState(S state);
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/83fd8f60/utils/src/main/java/com/cloud/utils/fsm/NoTransitionException.java
----------------------------------------------------------------------
diff --git a/utils/src/main/java/com/cloud/utils/fsm/NoTransitionException.java b/utils/src/main/java/com/cloud/utils/fsm/NoTransitionException.java
new file mode 100644
index 0000000..241e456
--- /dev/null
+++ b/utils/src/main/java/com/cloud/utils/fsm/NoTransitionException.java
@@ -0,0 +1,36 @@
+//
+// 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.fsm;
+
+import com.cloud.utils.SerialVersionUID;
+
+/**
+ * Thrown by the state machine when there is no transition from one state
+ * to another.
+ *
+ */
+public class NoTransitionException extends Exception {
+
+    private static final long serialVersionUID = SerialVersionUID.NoTransitionException;
+
+    public NoTransitionException(String msg) {
+        super(msg);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/83fd8f60/utils/src/main/java/com/cloud/utils/fsm/State.java
----------------------------------------------------------------------
diff --git a/utils/src/main/java/com/cloud/utils/fsm/State.java b/utils/src/main/java/com/cloud/utils/fsm/State.java
new file mode 100644
index 0000000..0af0e61
--- /dev/null
+++ b/utils/src/main/java/com/cloud/utils/fsm/State.java
@@ -0,0 +1,27 @@
+//
+// 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.fsm;
+
+/**
+ * State represents one state for that object
+ */
+public interface State<T> {
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/83fd8f60/utils/src/main/java/com/cloud/utils/fsm/StateDao.java
----------------------------------------------------------------------
diff --git a/utils/src/main/java/com/cloud/utils/fsm/StateDao.java b/utils/src/main/java/com/cloud/utils/fsm/StateDao.java
new file mode 100644
index 0000000..43ce25c
--- /dev/null
+++ b/utils/src/main/java/com/cloud/utils/fsm/StateDao.java
@@ -0,0 +1,25 @@
+//
+// 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.fsm;
+
+public interface StateDao<S, E, V> {
+    boolean updateState(S currentState, E event, S nextState, V vo, Object data);
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/83fd8f60/utils/src/main/java/com/cloud/utils/fsm/StateListener.java
----------------------------------------------------------------------
diff --git a/utils/src/main/java/com/cloud/utils/fsm/StateListener.java b/utils/src/main/java/com/cloud/utils/fsm/StateListener.java
new file mode 100644
index 0000000..96e8be9
--- /dev/null
+++ b/utils/src/main/java/com/cloud/utils/fsm/StateListener.java
@@ -0,0 +1,43 @@
+//
+// 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.fsm;
+
+public interface StateListener<S, E, V> {
+    /**
+     * Event is triggered before state machine transition finished.
+     * If you want to get the state of vm before state machine changed, you need to listen on this event
+     * @param oldState VM's old state
+     * @param event that triggered this VM state change
+     * @param newState VM's new state
+     * @param vo the VM instance
+     * @param opaque host id
+     * @return
+     */
+    public boolean preStateTransitionEvent(S oldState, E event, S newState, V vo, boolean status, Object opaque);
+
+    /**
+    * Event is triggered after state machine transition finished
+    * @param transition The Transition fo the Event
+    * @param vo the VM instance
+    * @param status the state transition is allowed or not
+    * @return
+    */
+    public boolean postStateTransitionEvent(StateMachine2.Transition<S, E> transition, V vo, boolean status, Object opaque);
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/83fd8f60/utils/src/main/java/com/cloud/utils/fsm/StateMachine.java
----------------------------------------------------------------------
diff --git a/utils/src/main/java/com/cloud/utils/fsm/StateMachine.java b/utils/src/main/java/com/cloud/utils/fsm/StateMachine.java
new file mode 100644
index 0000000..d6d5b4d
--- /dev/null
+++ b/utils/src/main/java/com/cloud/utils/fsm/StateMachine.java
@@ -0,0 +1,147 @@
+//
+// 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.fsm;
+
+import java.util.ArrayList;
+import java.util.Formatter;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Specifically, it implements the Moore machine.
+ * so someone else can add/modify states easily without regression.
+ * business logic anyways.
+ *
+ * @param <S> state
+ * @param <E> event
+ */
+public class StateMachine<S, E> {
+    private final HashMap<S, StateEntry> _states = new HashMap<S, StateEntry>();
+    private final StateEntry _initialStateEntry;
+
+    public StateMachine() {
+        _initialStateEntry = new StateEntry(null);
+    }
+
+    public void addTransition(S currentState, E event, S toState) {
+        StateEntry entry = null;
+        if (currentState == null) {
+            entry = _initialStateEntry;
+        } else {
+            entry = _states.get(currentState);
+            if (entry == null) {
+                entry = new StateEntry(currentState);
+                _states.put(currentState, entry);
+            }
+        }
+
+        entry.addTransition(event, toState);
+
+        entry = _states.get(toState);
+        if (entry == null) {
+            entry = new StateEntry(toState);
+            _states.put(toState, entry);
+        }
+        entry.addFromTransition(event, currentState);
+    }
+
+    public Set<E> getPossibleEvents(S s) {
+        StateEntry entry = _states.get(s);
+        return entry.nextStates.keySet();
+    }
+
+    public S getNextState(S s, E e) {
+        StateEntry entry = null;
+        if (s == null) {
+            entry = _initialStateEntry;
+        } else {
+            entry = _states.get(s);
+            assert entry != null : "Cannot retrieve transitions for state " + s.toString();
+        }
+
+        return entry.nextStates.get(e);
+    }
+
+    public List<S> getFromStates(S s, E e) {
+        StateEntry entry = _states.get(s);
+        if (entry == null) {
+            return new ArrayList<S>();
+        }
+
+        return entry.prevStates.get(e);
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder str = new StringBuilder(1024);
+        _initialStateEntry.buildString(str);
+        for (StateEntry entry : _states.values()) {
+            entry.buildString(str);
+        }
+        return str.toString();
+    }
+
+    private class StateEntry {
+        public S state;
+        public HashMap<E, S> nextStates;
+        public HashMap<E, List<S>> prevStates;
+
+        public StateEntry(S state) {
+            this.state = state;
+            nextStates = new HashMap<E, S>();
+            prevStates = new HashMap<E, List<S>>();
+        }
+
+        public void addTransition(E e, S s) {
+            assert !nextStates.containsKey(e) : "State " + getStateStr() + " already contains a transition to state " + nextStates.get(e).toString() + " via event " +
+                e.toString() + ".  Please revisit the rule you're adding to state " + s.toString();
+            nextStates.put(e, s);
+        }
+
+        public void addFromTransition(E e, S s) {
+            List<S> l = prevStates.get(e);
+            if (l == null) {
+                l = new ArrayList<S>();
+                prevStates.put(e, l);
+            }
+
+            assert !l.contains(s) : "Already contains the from transition " + e.toString() + " from state " + s.toString() + " to " + getStateStr();
+            l.add(s);
+        }
+
+        protected String getStateStr() {
+            return state == null ? "Initial" : state.toString();
+        }
+
+        public void buildString(StringBuilder str) {
+            str.append("State: ").append(getStateStr()).append("\n");
+            for (Map.Entry<E, S> nextState : nextStates.entrySet()) {
+                str.append("  --> Event: ");
+                Formatter format = new Formatter();
+                str.append(format.format("%-30s", nextState.getKey().toString()));
+                str.append("----> State: ");
+                str.append(nextState.getValue().toString());
+                str.append("\n");
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/83fd8f60/utils/src/main/java/com/cloud/utils/fsm/StateMachine2.java
----------------------------------------------------------------------
diff --git a/utils/src/main/java/com/cloud/utils/fsm/StateMachine2.java b/utils/src/main/java/com/cloud/utils/fsm/StateMachine2.java
new file mode 100644
index 0000000..431d961
--- /dev/null
+++ b/utils/src/main/java/com/cloud/utils/fsm/StateMachine2.java
@@ -0,0 +1,261 @@
+//
+// 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.fsm;
+
+import java.util.ArrayList;
+import java.util.Formatter;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Specifically, it implements the Moore machine.
+ * so someone else can add/modify states easily without regression.
+ * business logic anyways.
+ *
+ * @param <S> state
+ * @param <E> event
+ */
+public class StateMachine2<S, E, V extends StateObject<S>> {
+    private final HashMap<S, StateEntry> _states = new HashMap<S, StateEntry>();
+    private final StateEntry _initialStateEntry;
+
+    private List<StateListener<S, E, V>> _listeners = new ArrayList<StateListener<S, E, V>>();
+
+    public StateMachine2() {
+        _initialStateEntry = new StateEntry(null);
+
+    }
+
+    public void addTransition(S currentState, E event, S toState) {
+      addTransition(new Transition<S, E>(currentState, event, toState, null));
+    }
+
+
+    public void addTransition(Transition<S, E> transition) {
+      S currentState = transition.getCurrentState();
+      E event = transition.getEvent();
+      S toState = transition.getToState();
+      StateEntry entry = null;
+      if (currentState == null) {
+        entry = _initialStateEntry;
+      } else {
+        entry = _states.get(currentState);
+        if (entry == null) {
+          entry = new StateEntry(currentState);
+          _states.put(currentState, entry);
+        }
+      }
+
+      entry.addTransition(event, toState, transition);
+
+      entry = _states.get(toState);
+      if (entry == null) {
+        entry = new StateEntry(toState);
+        _states.put(toState, entry);
+      }
+      entry.addFromTransition(event, currentState);
+    }
+
+    public Set<E> getPossibleEvents(S s) {
+        StateEntry entry = _states.get(s);
+        return entry.nextStates.keySet();
+    }
+
+    public S getNextState(S s, E e) throws NoTransitionException {
+        return getTransition(s, e).getToState();
+    }
+
+    public Transition<S, E> getTransition(S s, E e) throws NoTransitionException {
+      StateEntry entry = null;
+      if (s == null) {
+        entry = _initialStateEntry;
+      } else {
+        entry = _states.get(s);
+        assert entry != null : "Cannot retrieve transitions for state " + s;
+      }
+
+      Transition<S, E> transition = entry.nextStates.get(e);
+      if (transition == null) {
+        throw new NoTransitionException("Unable to transition to a new state from " + s + " via " + e);
+      }
+      return transition;
+    }
+
+    public List<S> getFromStates(S s, E e) {
+        StateEntry entry = _states.get(s);
+        if (entry == null) {
+            return new ArrayList<S>();
+        }
+
+        return entry.prevStates.get(e);
+    }
+
+    public boolean transitTo(V vo, E e, Object opaque, StateDao<S, E, V> dao) throws NoTransitionException {
+        S currentState = vo.getState();
+        S nextState = getNextState(currentState, e);
+        Transition<S, E> transition = getTransition(currentState, e);
+
+        boolean transitionStatus = true;
+        if (nextState == null) {
+            transitionStatus = false;
+        }
+
+        for (StateListener<S, E, V> listener : _listeners) {
+            listener.preStateTransitionEvent(currentState, e, nextState, vo, transitionStatus, opaque);
+        }
+
+        transitionStatus = dao.updateState(currentState, e, nextState, vo, opaque);
+        if (!transitionStatus) {
+            return false;
+        }
+
+        for (StateListener<S, E, V> listener : _listeners) {
+            listener.postStateTransitionEvent(transition, vo, transitionStatus, opaque);
+        }
+
+        return true;
+    }
+
+    public boolean registerListener(StateListener<S, E, V> listener) {
+        synchronized (_listeners) {
+            return _listeners.add(listener);
+        }
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder str = new StringBuilder(1024);
+        _initialStateEntry.buildString(str);
+        for (StateEntry entry : _states.values()) {
+            entry.buildString(str);
+        }
+        return str.toString();
+    }
+
+    public static class Transition<S, E> {
+
+      private S currentState;
+
+      private E event;
+
+      private S toState;
+
+      private List<Impact> impacts;
+
+      public static enum Impact {
+        USAGE
+      }
+
+      public Transition(S currentState, E event, S toState, List<Impact> impacts) {
+        this.currentState = currentState;
+        this.event = event;
+        this.toState = toState;
+        this.impacts = impacts;
+      }
+
+      public S getCurrentState() {
+        return currentState;
+      }
+
+      public E getEvent() {
+        return event;
+      }
+
+      public S getToState() {
+        return toState;
+      }
+
+      public boolean isImpacted(Impact impact) {
+        if (impacts == null || impacts.isEmpty()) {
+          return false;
+        }
+        return impacts.contains(impact);
+      }
+
+      @Override
+      public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        Transition that = (Transition) o;
+
+        if (currentState != null ? !currentState.equals(that.currentState) : that.currentState != null) return false;
+        if (event != null ? !event.equals(that.event) : that.event != null) return false;
+        if (toState != null ? !toState.equals(that.toState) : that.toState != null) return false;
+
+        return true;
+      }
+
+      @Override
+      public int hashCode() {
+        int result = currentState != null ? currentState.hashCode() : 0;
+        result = 31 * result + (event != null ? event.hashCode() : 0);
+        result = 31 * result + (toState != null ? toState.hashCode() : 0);
+        return result;
+      }
+    }
+
+    private class StateEntry {
+        public S state;
+        public HashMap<E, Transition<S, E>> nextStates;
+        public HashMap<E, List<S>> prevStates;
+
+        public StateEntry(S state) {
+            this.state = state;
+            prevStates = new HashMap<E, List<S>>();
+            nextStates = new HashMap<E, Transition<S, E>>();
+        }
+
+        public void addTransition(E e, S s, Transition<S, E> transition) {
+            assert !nextStates.containsKey(e) : "State " + getStateStr() + " already contains a transition to state " + nextStates.get(e).toString() + " via event " +
+                e.toString() + ".  Please revisit the rule you're adding to state " + s.toString();
+            nextStates.put(e, transition);
+        }
+
+        public void addFromTransition(E e, S s) {
+            List<S> l = prevStates.get(e);
+            if (l == null) {
+                l = new ArrayList<S>();
+                prevStates.put(e, l);
+            }
+
+            assert !l.contains(s) : "Already contains the from transition " + e.toString() + " from state " + s.toString() + " to " + getStateStr();
+            l.add(s);
+        }
+
+        protected String getStateStr() {
+            return state == null ? "Initial" : state.toString();
+        }
+
+        public void buildString(StringBuilder str) {
+            str.append("State: ").append(getStateStr()).append("\n");
+            for (Map.Entry<E, Transition<S, E>> nextState : nextStates.entrySet()) {
+                str.append("  --> Event: ");
+                Formatter format = new Formatter();
+                str.append(format.format("%-30s", nextState.getKey().toString()));
+                str.append("----> State: ");
+                str.append(nextState.getValue().toString());
+                str.append("\n");
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/83fd8f60/utils/src/main/java/com/cloud/utils/fsm/StateObject.java
----------------------------------------------------------------------
diff --git a/utils/src/main/java/com/cloud/utils/fsm/StateObject.java b/utils/src/main/java/com/cloud/utils/fsm/StateObject.java
new file mode 100644
index 0000000..85dd441
--- /dev/null
+++ b/utils/src/main/java/com/cloud/utils/fsm/StateObject.java
@@ -0,0 +1,27 @@
+//
+// 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.fsm;
+
+public interface StateObject<S> {
+    /**
+     * @return finite state.
+     */
+    S getState();
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/83fd8f60/utils/src/main/java/com/cloud/utils/mgmt/JmxUtil.java
----------------------------------------------------------------------
diff --git a/utils/src/main/java/com/cloud/utils/mgmt/JmxUtil.java b/utils/src/main/java/com/cloud/utils/mgmt/JmxUtil.java
new file mode 100644
index 0000000..49076f7
--- /dev/null
+++ b/utils/src/main/java/com/cloud/utils/mgmt/JmxUtil.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.mgmt;
+
+import java.lang.management.ManagementFactory;
+import java.util.ArrayList;
+
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.InstanceNotFoundException;
+import javax.management.MBeanRegistrationException;
+import javax.management.MBeanServer;
+import javax.management.MBeanServerFactory;
+import javax.management.MalformedObjectNameException;
+import javax.management.NotCompliantMBeanException;
+import javax.management.ObjectName;
+
+public class JmxUtil {
+    public static ObjectName registerMBean(ManagementBean mbean) throws MalformedObjectNameException, InstanceAlreadyExistsException, MBeanRegistrationException,
+        NotCompliantMBeanException {
+
+        return registerMBean(mbean.getName(), null, mbean);
+    }
+
+    public static ObjectName registerMBean(String objTypeName, String objInstanceName, Object mbean) throws MalformedObjectNameException, InstanceAlreadyExistsException,
+        MBeanRegistrationException, NotCompliantMBeanException {
+
+        String name = "com.cloud:type=" + objTypeName;
+        if (objInstanceName != null && !objInstanceName.isEmpty())
+            name += ", name=" + objInstanceName;
+        ObjectName objectName = new ObjectName(name);
+
+        ArrayList<MBeanServer> server = MBeanServerFactory.findMBeanServer(null);
+        if (server.size() > 0) {
+            MBeanServer mBeanServer = server.get(0);
+            if (!mBeanServer.isRegistered(objectName))
+                mBeanServer.registerMBean(mbean, objectName);
+            return objectName;
+        } else {
+            MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
+            if (!mBeanServer.isRegistered(objectName))
+                mBeanServer.registerMBean(mbean, objectName);
+            return objectName;
+        }
+    }
+
+    public static void unregisterMBean(String objTypeName, String objInstanceName) throws MalformedObjectNameException, MBeanRegistrationException,
+        InstanceNotFoundException {
+
+        ObjectName name = composeMBeanName(objTypeName, objInstanceName);
+        unregisterMBean(name);
+    }
+
+    public static void unregisterMBean(ObjectName name) throws MalformedObjectNameException, MBeanRegistrationException, InstanceNotFoundException {
+
+        ArrayList<MBeanServer> server = MBeanServerFactory.findMBeanServer(null);
+        if (server.size() > 0) {
+            MBeanServer mBeanServer = server.get(0);
+            mBeanServer.unregisterMBean(name);
+        } else {
+            MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
+            mBeanServer.unregisterMBean(name);
+        }
+    }
+
+    private static ObjectName composeMBeanName(String objTypeName, String objInstanceName) throws MalformedObjectNameException {
+
+        String name = "com.cloud:type=" + objTypeName;
+        if (objInstanceName != null && !objInstanceName.isEmpty())
+            name += ", name=" + objInstanceName;
+
+        return new ObjectName(name);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/83fd8f60/utils/src/main/java/com/cloud/utils/mgmt/ManagementBean.java
----------------------------------------------------------------------
diff --git a/utils/src/main/java/com/cloud/utils/mgmt/ManagementBean.java b/utils/src/main/java/com/cloud/utils/mgmt/ManagementBean.java
new file mode 100644
index 0000000..387052e
--- /dev/null
+++ b/utils/src/main/java/com/cloud/utils/mgmt/ManagementBean.java
@@ -0,0 +1,27 @@
+//
+// 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.mgmt;
+
+/**
+ * we ever need common use methods here.
+ */
+public interface ManagementBean {
+    String getName();
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/83fd8f60/utils/src/main/java/com/cloud/utils/mgmt/PropertyMapDynamicBean.java
----------------------------------------------------------------------
diff --git a/utils/src/main/java/com/cloud/utils/mgmt/PropertyMapDynamicBean.java b/utils/src/main/java/com/cloud/utils/mgmt/PropertyMapDynamicBean.java
new file mode 100644
index 0000000..d1689eb
--- /dev/null
+++ b/utils/src/main/java/com/cloud/utils/mgmt/PropertyMapDynamicBean.java
@@ -0,0 +1,120 @@
+//
+// 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.mgmt;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import javax.management.Attribute;
+import javax.management.AttributeList;
+import javax.management.AttributeNotFoundException;
+import javax.management.DynamicMBean;
+import javax.management.InvalidAttributeValueException;
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanException;
+import javax.management.MBeanInfo;
+import javax.management.ReflectionException;
+
+public class PropertyMapDynamicBean implements DynamicMBean {
+
+    private Map<String, Object> _propMap = new HashMap<String, Object>();
+
+    public PropertyMapDynamicBean() {
+    }
+
+    public PropertyMapDynamicBean(Map<String, Object> propMap) {
+        _propMap = propMap;
+    }
+
+    @Override
+    public synchronized Object getAttribute(String name) throws AttributeNotFoundException, MBeanException, ReflectionException {
+        if (_propMap != null) {
+            return _propMap.get(name);
+        }
+
+        throw new AttributeNotFoundException("No such property " + name);
+    }
+
+    @Override
+    public synchronized AttributeList getAttributes(String[] names) {
+        AttributeList list = new AttributeList();
+        for (String name : names) {
+            Object value = _propMap.get(name);
+            if (value != null)
+                list.add(new Attribute(name, value));
+        }
+        return list;
+    }
+
+    @Override
+    public synchronized MBeanInfo getMBeanInfo() {
+        SortedSet<String> names = new TreeSet<String>();
+
+        for (String name : _propMap.keySet())
+            names.add(name);
+
+        MBeanAttributeInfo[] attrs = new MBeanAttributeInfo[names.size()];
+        Iterator<String> it = names.iterator();
+        for (int i = 0; i < attrs.length; i++) {
+            String name = it.next();
+            attrs[i] = new MBeanAttributeInfo(name, "java.lang.String", name, true,   // isReadable
+                true,   // isWritable
+                false); // isIs
+        }
+
+        return new MBeanInfo(this.getClass().getName(), "Dynamic MBean", attrs, null, null, null);
+    }
+
+    @Override
+    public synchronized Object invoke(String name, Object[] args, String[] sig) throws MBeanException, ReflectionException {
+        throw new ReflectionException(new NoSuchMethodException(name));
+    }
+
+    @Override
+    public synchronized void setAttribute(Attribute attr) throws AttributeNotFoundException, InvalidAttributeValueException, MBeanException, ReflectionException {
+        String name = attr.getName();
+        if (name != null)
+            _propMap.put(name, attr.getValue());
+    }
+
+    @Override
+    public synchronized AttributeList setAttributes(AttributeList list) {
+        Attribute[] attrs = list.toArray(new Attribute[0]);
+        AttributeList retList = new AttributeList();
+        for (Attribute attr : attrs) {
+            String name = attr.getName();
+            Object value = attr.getValue();
+            _propMap.put(name, value);
+            retList.add(new Attribute(name, value));
+        }
+        return retList;
+    }
+
+    public synchronized void addProp(String name, Object value) {
+        _propMap.put(name, value);
+    }
+
+    public synchronized Object getProp(String name) {
+        return _propMap.get(name);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/83fd8f60/utils/src/main/java/com/cloud/utils/net/Ip.java
----------------------------------------------------------------------
diff --git a/utils/src/main/java/com/cloud/utils/net/Ip.java b/utils/src/main/java/com/cloud/utils/net/Ip.java
new file mode 100644
index 0000000..09312bc
--- /dev/null
+++ b/utils/src/main/java/com/cloud/utils/net/Ip.java
@@ -0,0 +1,98 @@
+//
+// 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.net;
+
+import java.io.Serializable;
+
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.SerialVersionUID;
+
+/**
+ * Simple Ip implementation class that works with both ip4 and ip6.
+ *
+ */
+public class Ip implements Serializable, Comparable<Ip> {
+
+    private static final long serialVersionUID = SerialVersionUID.Ip;
+
+    long ip;
+
+    public Ip(long ip) {
+        this.ip = ip;
+    }
+
+    public Ip(String ip) {
+        this.ip = NetUtils.ip2Long(ip);
+    }
+
+    protected Ip() {
+    }
+
+    public String addr() {
+        return toString();
+    }
+
+    public long longValue() {
+        return ip;
+    }
+
+    @Override
+    public String toString() {
+        return NetUtils.long2Ip(ip);
+    }
+
+    public boolean isIp4() {
+        return ip <= 2L * Integer.MAX_VALUE + 1;
+    }
+
+    public boolean isIp6() {
+        return ip > Integer.MAX_VALUE;
+    }
+
+    @Override
+    public int hashCode() {
+        return NumbersUtil.hash(ip);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof Ip) {
+            return ip == ((Ip)obj).ip;
+        }
+        return false;
+    }
+
+    public boolean isSameAddressAs(Object obj) {
+        if (this.equals(obj)) {
+            return true;
+        } else if (obj instanceof String) {
+            return ip == NetUtils.ip2Long((String)obj);
+        } else if (obj instanceof Long) {
+            return ip == (Long)obj;
+        } else {
+            return false;
+        }
+    }
+
+    @Override
+    public int compareTo(Ip that) {
+        return (int)(this.ip - that.ip);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/83fd8f60/utils/src/main/java/com/cloud/utils/net/Ip4Address.java
----------------------------------------------------------------------
diff --git a/utils/src/main/java/com/cloud/utils/net/Ip4Address.java b/utils/src/main/java/com/cloud/utils/net/Ip4Address.java
new file mode 100644
index 0000000..0bd814d
--- /dev/null
+++ b/utils/src/main/java/com/cloud/utils/net/Ip4Address.java
@@ -0,0 +1,80 @@
+//
+// 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.net;
+
+public class Ip4Address {
+    String _addr;
+    String _mac;
+    static final String s_empty_mac = "00:00:00:00:00:00";
+
+    public Ip4Address(String addr, String mac) {
+        _addr = addr;
+        _mac = mac;
+    }
+
+    public Ip4Address(long addr, long mac) {
+        _addr = NetUtils.long2Ip(addr);
+        _mac = NetUtils.long2Mac(mac);
+    }
+
+    public Ip4Address(String addr) {
+        this(addr, s_empty_mac);
+    }
+
+    public Ip4Address(long addr) {
+        this(NetUtils.long2Ip(addr), s_empty_mac);
+    }
+
+    public String ip4() {
+        return _addr;
+    }
+
+    public String mac() {
+        return _mac;
+    }
+
+    public long toLong() {
+        return NetUtils.ip2Long(_addr);
+    }
+
+    @Override
+    public boolean equals(Object that) {
+
+        if (that instanceof Ip4Address) {
+            Ip4Address ip4 = (Ip4Address)that;
+            return _addr.equals(ip4._addr) && (_mac == ip4._mac || _mac.equals(ip4._mac));
+        } else {
+            return false;
+        }
+    }
+
+    public boolean isSameAddressAs(Object other) {
+        if (other instanceof String) { // Assume that is an ip4 address in String form
+            return _addr.equals(other);
+        } else {
+            return equals(other);
+        }
+    }
+
+    @Override
+    public int hashCode(){
+        return _mac.hashCode()*_addr.hashCode();
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/83fd8f60/utils/src/main/java/com/cloud/utils/net/MacAddress.java
----------------------------------------------------------------------
diff --git a/utils/src/main/java/com/cloud/utils/net/MacAddress.java b/utils/src/main/java/com/cloud/utils/net/MacAddress.java
new file mode 100644
index 0000000..b9118cf
--- /dev/null
+++ b/utils/src/main/java/com/cloud/utils/net/MacAddress.java
@@ -0,0 +1,367 @@
+//
+// 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.net;
+
+import static com.cloud.utils.AutoCloseableUtil.closeAutoCloseable;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Formatter;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.utils.NumbersUtil;
+
+/**
+ * copied from the public domain utility from John Burkard.
+ * @author <a href="mailto:jb@eaio.com">Johann Burkard</a>
+ * @version 2.1.3
+ **/
+public class MacAddress {
+    private static final Logger s_logger = Logger.getLogger(MacAddress.class);
+    private long _addr = 0;
+
+    protected MacAddress() {
+    }
+
+    public MacAddress(long addr) {
+        _addr = addr;
+    }
+
+    public long toLong() {
+        return _addr;
+    }
+
+    public byte[] toByteArray() {
+        byte[] bytes = new byte[6];
+        bytes[0] = (byte)((_addr >> 40) & 0xff);
+        bytes[1] = (byte)((_addr >> 32) & 0xff);
+        bytes[2] = (byte)((_addr >> 24) & 0xff);
+        bytes[3] = (byte)((_addr >> 16) & 0xff);
+        bytes[4] = (byte)((_addr >> 8) & 0xff);
+        bytes[5] = (byte)((_addr >> 0) & 0xff);
+        return bytes;
+    }
+
+    public String toString(String separator) {
+        StringBuilder buff = new StringBuilder();
+        Formatter formatter = new Formatter(buff);
+        formatter.format("%02x%s%02x%s%02x%s%02x%s%02x%s%02x", _addr >> 40 & 0xff, separator, _addr >> 32 & 0xff, separator, _addr >> 24 & 0xff, separator,
+            _addr >> 16 & 0xff, separator, _addr >> 8 & 0xff, separator, _addr & 0xff);
+        return buff.toString();
+
+        /*
+
+        String str = Long.toHexString(_addr);
+
+        for (int i = str.length() - 1; i >= 0; i--) {
+            buff.append(str.charAt(i));
+            if (separator != null && (str.length() - i) % 2 == 0) {
+                buff.append(separator);
+            }
+        }
+        return buff.reverse().toString();
+         */
+    }
+
+    @Override
+    public String toString() {
+        return toString(":");
+    }
+
+    private static MacAddress s_address;
+    static {
+        String macAddress = null;
+
+        Process p = null;
+        BufferedReader in = null;
+
+        try {
+            String osname = System.getProperty("os.name");
+
+            if (osname.startsWith("Windows")) {
+                p = Runtime.getRuntime().exec(new String[] {"ipconfig", "/all"}, null);
+            } else if (osname.startsWith("Solaris") || osname.startsWith("SunOS")) {
+                // Solaris code must appear before the generic code
+                String hostName = MacAddress.getFirstLineOfCommand(new String[] {"uname", "-n"});
+                if (hostName != null) {
+                    p = Runtime.getRuntime().exec(new String[] {"/usr/sbin/arp", hostName}, null);
+                }
+            } else if (new File("/usr/sbin/lanscan").exists()) {
+                p = Runtime.getRuntime().exec(new String[] {"/usr/sbin/lanscan"}, null);
+            } else if (new File("/sbin/ifconfig").exists()) {
+                p = Runtime.getRuntime().exec(new String[] {"/sbin/ifconfig", "-a"}, null);
+            }
+
+            if (p != null) {
+                in = new BufferedReader(new InputStreamReader(p.getInputStream()), 128);
+                String l = null;
+                while ((l = in.readLine()) != null) {
+                    macAddress = MacAddress.parse(l);
+                    if (macAddress != null) {
+                        short parsedShortMacAddress = MacAddress.parseShort(macAddress);
+                        if (parsedShortMacAddress != 0xff && parsedShortMacAddress != 0x00)
+                            break;
+                    }
+                    macAddress = null;
+                }
+            }
+
+        } catch (SecurityException ex) {
+            s_logger.info("[ignored] security exception in static initializer of MacAddress", ex);
+        } catch (IOException ex) {
+            s_logger.info("[ignored] io exception in static initializer of MacAddress");
+        } finally {
+            if (p != null) {
+                closeAutoCloseable(in, "closing init process input stream");
+                closeAutoCloseable(p.getErrorStream(), "closing init process error output stream");
+                closeAutoCloseable(p.getOutputStream(), "closing init process std output stream");
+                p.destroy();
+            }
+        }
+
+        long clockSeqAndNode = 0;
+
+        if (macAddress != null) {
+            if (macAddress.indexOf(':') != -1) {
+                clockSeqAndNode |= MacAddress.parseLong(macAddress);
+            } else if (macAddress.startsWith("0x")) {
+                clockSeqAndNode |= MacAddress.parseLong(macAddress.substring(2));
+            }
+        } else {
+            try {
+                byte[] local = InetAddress.getLocalHost().getAddress();
+                clockSeqAndNode |= (local[0] << 24) & 0xFF000000L;
+                clockSeqAndNode |= (local[1] << 16) & 0xFF0000;
+                clockSeqAndNode |= (local[2] << 8) & 0xFF00;
+                clockSeqAndNode |= local[3] & 0xFF;
+            } catch (UnknownHostException ex) {
+                clockSeqAndNode |= (long)(Math.random() * 0x7FFFFFFF);
+            }
+        }
+
+        s_address = new MacAddress(clockSeqAndNode);
+    }
+
+    public static MacAddress getMacAddress() {
+        return s_address;
+    }
+
+    private static String getFirstLineOfCommand(String[] commands) throws IOException {
+
+        Process p = null;
+        BufferedReader reader = null;
+
+        try {
+            p = Runtime.getRuntime().exec(commands);
+            reader = new BufferedReader(new InputStreamReader(p.getInputStream()), 128);
+
+            return reader.readLine();
+        } finally {
+            if (p != null) {
+                closeAutoCloseable(reader, "closing process input stream");
+                closeAutoCloseable(p.getErrorStream(), "closing process error output stream");
+                closeAutoCloseable(p.getOutputStream(), "closing process std output stream");
+                p.destroy();
+            }
+        }
+
+    }
+
+    /**
+     * The MAC address parser attempts to find the following patterns:
+     * <ul>
+     * <li>.{1,2}:.{1,2}:.{1,2}:.{1,2}:.{1,2}:.{1,2}</li>
+     * <li>.{1,2}-.{1,2}-.{1,2}-.{1,2}-.{1,2}-.{1,2}</li>
+     * </ul>
+     *
+     * This is copied from the author below.  The author encouraged copying
+     * it.
+     *
+     */
+    static String parse(String in) {
+
+        // lanscan
+
+        int hexStart = in.indexOf("0x");
+        if (hexStart != -1) {
+            int hexEnd = in.indexOf(' ', hexStart);
+            if (hexEnd != -1) {
+                return in.substring(hexStart, hexEnd);
+            }
+        }
+
+        int octets = 0;
+        int lastIndex, old, end;
+
+        if (in.indexOf('-') > -1) {
+            in = in.replace('-', ':');
+        }
+
+        lastIndex = in.lastIndexOf(':');
+
+        if (lastIndex > in.length() - 2)
+            return null;
+
+        end = Math.min(in.length(), lastIndex + 3);
+
+        ++octets;
+        old = lastIndex;
+        while (octets != 5 && lastIndex != -1 && lastIndex > 1) {
+            lastIndex = in.lastIndexOf(':', --lastIndex);
+            if (old - lastIndex == 3 || old - lastIndex == 2) {
+                ++octets;
+                old = lastIndex;
+            }
+        }
+
+        if (octets == 5 && lastIndex > 1) {
+            return in.substring(lastIndex - 2, end).trim();
+        }
+        return null;
+    }
+
+    public static void main(String[] args) {
+        MacAddress addr = MacAddress.getMacAddress();
+        System.out.println("addr in integer is " + addr.toLong());
+        System.out.println("addr in bytes is " + NumbersUtil.bytesToString(addr.toByteArray(), 0, addr.toByteArray().length));
+        System.out.println("addr in char is " + addr.toString(":"));
+    }
+
+    /**
+     * Parses a <code>long</code> from a hex encoded number. This method will skip
+     * all characters that are not 0-9 and a-f (the String is lower cased first).
+     * Returns 0 if the String does not contain any interesting characters.
+     *
+     * @param s the String to extract a <code>long</code> from, may not be <code>null</code>
+     * @return a <code>long</code>
+     * @throws NullPointerException if the String is <code>null</code>
+     */
+    public static long parseLong(String s) throws NullPointerException {
+        s = s.toLowerCase();
+        long out = 0;
+        byte shifts = 0;
+        char c;
+        for (int i = 0; i < s.length() && shifts < 16; i++) {
+            c = s.charAt(i);
+            if ((c > 47) && (c < 58)) {
+                out <<= 4;
+                ++shifts;
+                out |= c - 48;
+            } else if ((c > 96) && (c < 103)) {
+                ++shifts;
+                out <<= 4;
+                out |= c - 87;
+            }
+        }
+        return out;
+    }
+
+    /**
+     * Parses an <code>int</code> from a hex encoded number. This method will skip
+     * all characters that are not 0-9 and a-f (the String is lower cased first).
+     * Returns 0 if the String does not contain any interesting characters.
+     *
+     * @param s the String to extract an <code>int</code> from, may not be <code>null</code>
+     * @return an <code>int</code>
+     * @throws NullPointerException if the String is <code>null</code>
+     */
+    public static int parseInt(String s) throws NullPointerException {
+        s = s.toLowerCase();
+        int out = 0;
+        byte shifts = 0;
+        char c;
+        for (int i = 0; i < s.length() && shifts < 8; i++) {
+            c = s.charAt(i);
+            if ((c > 47) && (c < 58)) {
+                out <<= 4;
+                ++shifts;
+                out |= c - 48;
+            } else if ((c > 96) && (c < 103)) {
+                ++shifts;
+                out <<= 4;
+                out |= c - 87;
+            }
+        }
+        return out;
+    }
+
+    /**
+     * Parses a <code>short</code> from a hex encoded number. This method will skip
+     * all characters that are not 0-9 and a-f (the String is lower cased first).
+     * Returns 0 if the String does not contain any interesting characters.
+     *
+     * @param s the String to extract a <code>short</code> from, may not be <code>null</code>
+     * @return a <code>short</code>
+     * @throws NullPointerException if the String is <code>null</code>
+     */
+    public static short parseShort(String s) throws NullPointerException {
+        s = s.toLowerCase();
+        short out = 0;
+        byte shifts = 0;
+        char c;
+        for (int i = 0; i < s.length() && shifts < 4; i++) {
+            c = s.charAt(i);
+            if ((c > 47) && (c < 58)) {
+                out <<= 4;
+                ++shifts;
+                out |= c - 48;
+            } else if ((c > 96) && (c < 103)) {
+                ++shifts;
+                out <<= 4;
+                out |= c - 87;
+            }
+        }
+        return out;
+    }
+
+    /**
+     * Parses a <code>byte</code> from a hex encoded number. This method will skip
+     * all characters that are not 0-9 and a-f (the String is lower cased first).
+     * Returns 0 if the String does not contain any interesting characters.
+     *
+     * @param s the String to extract a <code>byte</code> from, may not be <code>null</code>
+     * @return a <code>byte</code>
+     * @throws NullPointerException if the String is <code>null</code>
+     */
+    public static byte parseByte(String s) throws NullPointerException {
+        s = s.toLowerCase();
+        byte out = 0;
+        byte shifts = 0;
+        char c;
+        for (int i = 0; i < s.length() && shifts < 2; i++) {
+            c = s.charAt(i);
+            if ((c > 47) && (c < 58)) {
+                out <<= 4;
+                ++shifts;
+                out |= c - 48;
+            } else if ((c > 96) && (c < 103)) {
+                ++shifts;
+                out <<= 4;
+                out |= c - 87;
+            }
+        }
+        return out;
+    }
+}


Mime
View raw message