You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ke...@apache.org on 2013/02/01 20:38:10 UTC

[49/50] [abbrv] Sync master to javelin one more time

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/7b75f0d9/plugins/event-bus/rabbitmq/src/org/apache/cloudstack/mom/rabbitmq/RabbitMQEventBus.java
----------------------------------------------------------------------
diff --cc plugins/event-bus/rabbitmq/src/org/apache/cloudstack/mom/rabbitmq/RabbitMQEventBus.java
index 0000000,3a06c42..ce0930d
mode 000000,100644..100644
--- a/plugins/event-bus/rabbitmq/src/org/apache/cloudstack/mom/rabbitmq/RabbitMQEventBus.java
+++ b/plugins/event-bus/rabbitmq/src/org/apache/cloudstack/mom/rabbitmq/RabbitMQEventBus.java
@@@ -1,0 -1,555 +1,556 @@@
+ /*
+  * 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 org.apache.cloudstack.mom.rabbitmq;
+ 
+ import com.rabbitmq.client.*;
+ import org.apache.cloudstack.framework.events.*;
+ import org.apache.log4j.Logger;
+ 
+ import com.cloud.utils.Ternary;
++import com.cloud.utils.component.ManagerBase;
+ 
+ import javax.ejb.Local;
+ import javax.naming.ConfigurationException;
+ import java.io.IOException;
+ import java.net.ConnectException;
+ import java.util.Map;
+ import java.util.UUID;
+ import java.util.concurrent.ConcurrentHashMap;
+ import java.util.concurrent.ExecutorService;
+ import java.util.concurrent.Executors;
+ 
+ @Local(value=EventBus.class)
 -public class RabbitMQEventBus implements EventBus {
++public class RabbitMQEventBus extends ManagerBase implements EventBus {
+ 
+     // details of AMQP server
+     private static String _amqpHost;
+     private static Integer _port;
+     private static String _username;
+     private static String _password;
+ 
+     // AMQP exchange name where all CloudStack events will be published
+     private static String _amqpExchangeName;
+ 
+     // hashmap to book keep the registered subscribers
+     private static ConcurrentHashMap<String, Ternary<String, Channel, EventSubscriber>> _subscribers;
+ 
+     // connection to AMQP server,
+     private static Connection _connection=null;
+ 
+     // AMQP server should consider messages acknowledged once delivered if _autoAck is true
+     private static boolean _autoAck = true;
+ 
+     private ExecutorService executorService;
+     private String _name;
+     private static DisconnectHandler disconnectHandler;
+     private static Integer _retryInterval;
+     private static final Logger s_logger = Logger.getLogger(RabbitMQEventBus.class);
+ 
+     @Override
+     public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+ 
+         _amqpHost = (String) params.get("server");
+         if (_amqpHost == null || _amqpHost.isEmpty()) {
+             throw new ConfigurationException("Unable to get the AMQP server details");
+         }
+ 
+         _username = (String) params.get("username");
+         if (_username == null || _username.isEmpty()) {
+             throw new ConfigurationException("Unable to get the username details");
+         }
+ 
+         _password = (String) params.get("password");
+         if (_password == null || _password.isEmpty()) {
+             throw new ConfigurationException("Unable to get the password details");
+         }
+ 
+         _amqpExchangeName = (String) params.get("exchangename");
+         if (_amqpExchangeName == null || _amqpExchangeName.isEmpty()) {
+             throw new ConfigurationException("Unable to get the _exchange details on the AMQP server");
+         }
+ 
+         try {
+             String portStr =  (String) params.get("port");
+             if (portStr == null || portStr.isEmpty()) {
+                 throw new ConfigurationException("Unable to get the port details of AMQP server");
+             }
+             _port = Integer.parseInt(portStr);
+ 
+             String retryIntervalStr = (String) params.get("retryinterval");
+             if (retryIntervalStr == null || retryIntervalStr.isEmpty()) {
+                 // default to 10s to try out reconnect
+                 retryIntervalStr = "10000";
+             }
+             _retryInterval = Integer.parseInt(retryIntervalStr);
+         } catch (NumberFormatException e) {
+             throw new ConfigurationException("Invalid port number/retry interval");
+         }
+ 
+         _subscribers = new ConcurrentHashMap<String, Ternary<String, Channel, EventSubscriber>>();
+ 
+         executorService = Executors.newCachedThreadPool();
+         disconnectHandler = new DisconnectHandler();
+         _name = name;
+         return true;
+     }
+ 
+     /** Call to subscribe to interested set of events
+      *
+      * @param topic defines category and type of the events being subscribed to
+      * @param subscriber subscriber that intends to receive event notification
+      * @return UUID that represents the subscription with event bus
+      * @throws EventBusException
+      */
+     @Override
+     public UUID subscribe(EventTopic topic, EventSubscriber subscriber) throws EventBusException {
+ 
+         if (subscriber == null || topic == null) {
+             throw new EventBusException("Invalid EventSubscriber/EventTopic object passed.");
+         }
+ 
+         // create a UUID, that will be used for managing subscriptions and also used as queue name
+         // for on the queue used for the subscriber on the AMQP broker
+         UUID queueId = UUID.randomUUID();
+         String queueName = queueId.toString();
+ 
+         try {
+             String bindingKey = createBindingKey(topic);
+ 
+             // store the subscriber details before creating channel
+             _subscribers.put(queueName, new Ternary(bindingKey, null, subscriber));
+ 
+             // create a channel dedicated for this subscription
+             Connection connection = getConnection();
+             Channel channel = createChannel(connection);
+ 
+             // create a queue and bind it to the exchange with binding key formed from event topic
+             createExchange(channel, _amqpExchangeName);
+             channel.queueDeclare(queueName, false, false, false, null);
+             channel.queueBind(queueName, _amqpExchangeName, bindingKey);
+ 
+             // register a callback handler to receive the events that a subscriber subscribed to
+             channel.basicConsume(queueName, _autoAck, queueName,
+                     new DefaultConsumer(channel) {
+                         @Override
+                         public void handleDelivery(String queueName,
+                                                    Envelope envelope,
+                                                    AMQP.BasicProperties properties,
+                                                    byte[] body)
+                             throws IOException {
+                             Ternary<String, Channel, EventSubscriber> queueDetails = _subscribers.get(queueName);
+                             if (queueDetails != null) {
+                                 EventSubscriber subscriber = queueDetails.third();
+                                 String routingKey =  envelope.getRoutingKey();
+                                 String eventSource = getEventSourceFromRoutingKey(routingKey);
+                                 String eventCategory = getEventCategoryFromRoutingKey(routingKey);
+                                 String eventType = getEventTypeFromRoutingKey(routingKey);
+                                 String resourceType = getResourceTypeFromRoutingKey(routingKey);
+                                 String resourceUUID = getResourceUUIDFromRoutingKey(routingKey);
+                                 Event event = new Event(eventSource, eventCategory, eventType,
+                                         resourceType, resourceUUID);
+                                 event.setDescription(new String(body));
+ 
+                                 // deliver the event to call back object provided by subscriber
+                                 subscriber.onEvent(event);
+                             }
+                         }
+                     }
+             );
+ 
+             // update the channel details for the subscription
+             Ternary<String, Channel, EventSubscriber> queueDetails = _subscribers.get(queueName);
+             queueDetails.second(channel);
+             _subscribers.put(queueName, queueDetails);
+ 
+         } catch (AlreadyClosedException closedException) {
+             s_logger.warn("Connection to AMQP service is lost. Subscription:" + queueName +
+                     " will be active after reconnection");
+         } catch (ConnectException connectException) {
+             s_logger.warn("Connection to AMQP service is lost. Subscription:" + queueName +
+                     " will be active after reconnection");
+         } catch (Exception e) {
+             throw new EventBusException("Failed to subscribe to event due to " + e.getMessage());
+         }
+ 
+         return queueId;
+     }
+ 
+     @Override
+     public void unsubscribe(UUID subscriberId, EventSubscriber subscriber) throws EventBusException {
+         try {
+             String classname =  subscriber.getClass().getName();
+             String queueName = UUID.nameUUIDFromBytes(classname.getBytes()).toString();
+             Ternary<String, Channel, EventSubscriber> queueDetails = _subscribers.get(queueName);
+             Channel channel = queueDetails.second();
+             channel.basicCancel(queueName);
+             _subscribers.remove(queueName, queueDetails);
+         } catch (Exception e) {
+             throw new EventBusException("Failed to unsubscribe from event bus due to " + e.getMessage());
+         }
+     }
+ 
+     // publish event on to the exchange created on AMQP server
+     @Override
+     public void publish(Event event) throws EventBusException {
+ 
+         String routingKey = createRoutingKey(event);
+         String eventDescription = event.getDescription();
+ 
+         try {
+             Connection connection = getConnection();
+             Channel channel = createChannel(connection);
+             createExchange(channel, _amqpExchangeName);
+             publishEventToExchange(channel, _amqpExchangeName, routingKey, eventDescription);
+             channel.close();
+         } catch (AlreadyClosedException e) {
+             closeConnection();
+             throw new EventBusException("Failed to publish event to message broker as connection to AMQP broker in lost");
+         } catch (Exception e) {
+             throw new EventBusException("Failed to publish event to message broker due to " + e.getMessage());
+         }
+     }
+ 
+     /** creates a routing key from the event details.
+      *  created routing key will be used while publishing the message to exchange on AMQP server
+      */
+     private String createRoutingKey(Event event) {
+ 
+         StringBuilder routingKey = new StringBuilder();
+ 
+         String eventSource =  replaceNullWithWildcard(event.getEventSource());
+         eventSource = eventSource.replace(".", "-");
+ 
+         String eventCategory = replaceNullWithWildcard(event.getEventCategory());
+         eventCategory = eventCategory.replace(".", "-");
+ 
+         String eventType = replaceNullWithWildcard(event.getEventType());
+         eventType = eventType.replace(".", "-");
+ 
+         String resourceType = replaceNullWithWildcard(event.getResourceType());
+         resourceType = resourceType.replace(".", "-");
+ 
+         String resourceUuid = replaceNullWithWildcard(event.getResourceUUID());
+         resourceUuid = resourceUuid.replace(".", "-");
+ 
+         // routing key will be of format: eventSource.eventCategory.eventType.resourceType.resourceUuid
+         routingKey.append(eventSource);
+         routingKey.append(".");
+         routingKey.append(eventCategory);
+         routingKey.append(".");
+         routingKey.append(eventType);
+         routingKey.append(".");
+         routingKey.append(resourceType);
+         routingKey.append(".");
+         routingKey.append(resourceUuid);
+ 
+         return routingKey.toString();
+     }
+ 
+     /** creates a binding key from the event topic that subscriber specified
+      *  binding key will be used to bind the queue created for subscriber to exchange on AMQP server
+      */
+     private String createBindingKey(EventTopic topic) {
+ 
+         StringBuilder bindingKey = new StringBuilder();
+ 
+         String eventSource =  replaceNullWithWildcard(topic.getEventSource());
+         eventSource = eventSource.replace(".", "-");
+ 
+         String eventCategory = replaceNullWithWildcard(topic.getEventCategory());
+         eventCategory = eventCategory.replace(".", "-");
+ 
+         String eventType = replaceNullWithWildcard(topic.getEventType());
+         eventType = eventType.replace(".", "-");
+ 
+         String resourceType = replaceNullWithWildcard(topic.getResourceType());
+         resourceType = resourceType.replace(".", "-");
+ 
+         String resourceUuid = replaceNullWithWildcard(topic.getResourceUUID());
+         resourceUuid = resourceUuid.replace(".", "-");
+ 
+         // binding key will be of format: eventSource.eventCategory.eventType.resourceType.resourceUuid
+         bindingKey.append(eventSource);
+         bindingKey.append(".");
+         bindingKey.append(eventCategory);
+         bindingKey.append(".");
+         bindingKey.append(eventType);
+         bindingKey.append(".");
+         bindingKey.append(resourceType);
+         bindingKey.append(".");
+         bindingKey.append(resourceUuid);
+ 
+         return bindingKey.toString();
+     }
+ 
+     private synchronized Connection getConnection() throws Exception {
+         if (_connection == null) {
+             try {
+                 return createConnection();
+             } catch (Exception e) {
+                 s_logger.error("Failed to create a connection to AMQP server due to " + e.getMessage());
+                 throw e;
+             }
+         } else {
+             return _connection;
+         }
+     }
+ 
+     private synchronized Connection createConnection() throws Exception {
+         try {
+             ConnectionFactory factory = new ConnectionFactory();
+             factory.setUsername(_username);
+             factory.setPassword(_password);
+             factory.setVirtualHost("/");
+             factory.setHost(_amqpHost);
+             factory.setPort(_port);
+             Connection connection = factory.newConnection();
+             connection.addShutdownListener(disconnectHandler);
+             _connection = connection;
+             return _connection;
+         } catch (Exception e) {
+             throw e;
+         }
+     }
+ 
+     private synchronized void closeConnection() {
+         try {
+             if (_connection != null) {
+                 _connection.close();
+             }
+         } catch (Exception e) {
+             s_logger.warn("Failed to close connection to AMQP server due to " + e.getMessage());
+         }
+         _connection = null;
+     }
+ 
+     private synchronized void abortConnection () {
+         if (_connection == null)
+             return;
+ 
+         try {
+             _connection.abort();
+         } catch (Exception e) {
+             s_logger.warn("Failed to abort connection due to " + e.getMessage());
+         }
+         _connection = null;
+     }
+ 
+     private String replaceNullWithWildcard(String key) {
+         if (key == null || key.isEmpty()) {
+             return "*";
+         } else {
+             return key;
+         }
+     }
+ 
+     private Channel createChannel(Connection connection) throws Exception {
+         try {
+             return connection.createChannel();
+         } catch (java.io.IOException exception) {
+             s_logger.warn("Failed to create a channel due to " + exception.getMessage());
+             throw exception;
+         }
+     }
+ 
+     private void createExchange(Channel channel, String exchangeName) throws Exception {
+         try {
+             channel.exchangeDeclare(exchangeName, "topic", true);
+         } catch (java.io.IOException exception) {
+             s_logger.error("Failed to create exchange" + exchangeName + " on RabbitMQ server");
+             throw exception;
+         }
+     }
+ 
+     private void publishEventToExchange(Channel channel, String exchangeName,
+                                         String routingKey, String eventDescription) throws Exception {
+         try {
+             byte[] messageBodyBytes = eventDescription.getBytes();
+             channel.basicPublish(exchangeName, routingKey, MessageProperties.PERSISTENT_TEXT_PLAIN, messageBodyBytes);
+         } catch (Exception e) {
+             s_logger.error("Failed to publish event " + routingKey + " on exchange " + exchangeName +
+                     "  of message broker due to " + e.getMessage());
+             throw e;
+         }
+     }
+ 
+     private String getEventCategoryFromRoutingKey(String routingKey) {
+         String[] keyParts =  routingKey.split("\\.");
+         return keyParts[1];
+     }
+ 
+     private String getEventTypeFromRoutingKey(String routingKey) {
+         String[] keyParts =  routingKey.split("\\.");
+         return keyParts[2];
+     }
+ 
+     private String getEventSourceFromRoutingKey(String routingKey) {
+         String[] keyParts =  routingKey.split("\\.");
+         return keyParts[0];
+     }
+ 
+     private String getResourceTypeFromRoutingKey(String routingKey) {
+         String[] keyParts =  routingKey.split("\\.");
+         return keyParts[3];
+     }
+ 
+     private String getResourceUUIDFromRoutingKey(String routingKey) {
+         String[] keyParts =  routingKey.split("\\.");
+         return keyParts[4];
+     }
+ 
+     @Override
+     public String getName() {
+         return _name;
+     }
+ 
+     @Override
+     public boolean start() {
+         ReconnectionTask reconnect = new ReconnectionTask(); // initiate connection to AMQP server
+         executorService.submit(reconnect);
+         return true;
+     }
+ 
+     @Override
+     public boolean stop() {
+ 
+         if (_connection.isOpen()) {
+             for (String subscriberId : _subscribers.keySet()) {
+                 Ternary<String, Channel, EventSubscriber> subscriberDetails = _subscribers.get(subscriberId);
+                 Channel channel =  subscriberDetails.second();
+                 String queueName = subscriberId;
+                 try {
+                     channel.queueDelete(queueName);
+                     channel.abort();
+                 } catch (IOException ioe) {
+                     s_logger.warn("Failed to delete queue: " + queueName + " on AMQP server due to " + ioe.getMessage() );
+                 }
+             }
+         }
+ 
+         closeConnection();
+         return true;
+     }
+ 
+     // logic to deal with loss of connection to AMQP server
+     private class DisconnectHandler implements ShutdownListener {
+ 
+         @Override
+         public void shutdownCompleted(ShutdownSignalException shutdownSignalException) {
+             if (!shutdownSignalException.isInitiatedByApplication()) {
+ 
+                 for (String subscriberId : _subscribers.keySet()) {
+                     Ternary<String, Channel, EventSubscriber> subscriberDetails = _subscribers.get(subscriberId);
+                     subscriberDetails.second(null);
+                     _subscribers.put(subscriberId, subscriberDetails);
+                 }
+ 
+                 abortConnection(); // disconnected to AMQP server, so abort the connection and channels
+                 s_logger.warn("Connection has been shutdown by AMQP server. Attempting to reconnect.");
+ 
+                 // initiate re-connect process
+                 ReconnectionTask reconnect = new ReconnectionTask();
+                 executorService.submit(reconnect);
+             }
+         }
+     }
+ 
+     // retry logic to connect back to AMQP server after loss of connection
+     private class ReconnectionTask implements Runnable {
+ 
+         boolean connected = false;
+         Connection connection = null;
+ 
+         public void run() {
+ 
+             while (!connected) {
+                 try {
+                     Thread.sleep(_retryInterval);
+                 } catch (InterruptedException ie) {
+                     // ignore timer interrupts
+                 }
+ 
+                 try {
+                     try {
+                         connection = createConnection();
+                         connected = true;
+                     } catch (IOException ie) {
+                         continue; // can't establish connection to AMQP server yet, so continue
+                     }
+ 
+                     // prepare consumer on AMQP server for each of subscriber
+                     for (String subscriberId : _subscribers.keySet()) {
+                         Ternary<String, Channel, EventSubscriber> subscriberDetails = _subscribers.get(subscriberId);
+                         String bindingKey = subscriberDetails.first();
+                         EventSubscriber subscriber = subscriberDetails.third();
+ 
+                         /** create a queue with subscriber ID as queue name and bind it to the exchange
+                          *  with binding key formed from event topic
+                          */
+                         Channel channel = createChannel(connection);
+                         createExchange(channel, _amqpExchangeName);
+                         channel.queueDeclare(subscriberId, false, false, false, null);
+                         channel.queueBind(subscriberId, _amqpExchangeName, bindingKey);
+ 
+                         // register a callback handler to receive the events that a subscriber subscribed to
+                         channel.basicConsume(subscriberId, _autoAck, subscriberId,
+                                 new DefaultConsumer(channel) {
+                                     @Override
+                                     public void handleDelivery(String queueName,
+                                                                Envelope envelope,
+                                                                AMQP.BasicProperties properties,
+                                                                byte[] body)
+                                             throws IOException {
+ 
+                                         Ternary<String, Channel, EventSubscriber> subscriberDetails
+                                                 = _subscribers.get(queueName); // queue name == subscriber ID
+ 
+                                         if (subscriberDetails != null) {
+                                             EventSubscriber subscriber = subscriberDetails.third();
+                                             String routingKey =  envelope.getRoutingKey();
+                                             String eventSource = getEventSourceFromRoutingKey(routingKey);
+                                             String eventCategory = getEventCategoryFromRoutingKey(routingKey);
+                                             String eventType = getEventTypeFromRoutingKey(routingKey);
+                                             String resourceType = getResourceTypeFromRoutingKey(routingKey);
+                                             String resourceUUID = getResourceUUIDFromRoutingKey(routingKey);
+ 
+                                             // create event object from the message details obtained from AMQP server
+                                             Event event = new Event(eventSource, eventCategory, eventType,
+                                                     resourceType, resourceUUID);
+                                             event.setDescription(new String(body));
+ 
+                                             // deliver the event to call back object provided by subscriber
+                                             subscriber.onEvent(event);
+                                         }
+                                     }
+                                 }
+                         );
+ 
+                         // update the channel details for the subscription
+                         subscriberDetails.second(channel);
+                         _subscribers.put(subscriberId, subscriberDetails);
+                     }
+                 } catch (Exception e) {
+                     s_logger.warn("Failed to recreate queues and binding for the subscribers due to " + e.getMessage());
+                 }
+             }
+             return;
+         }
+     }
+ }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/7b75f0d9/plugins/network-elements/ovs/src/com/cloud/network/guru/OvsGuestNetworkGuru.java
----------------------------------------------------------------------
diff --cc plugins/network-elements/ovs/src/com/cloud/network/guru/OvsGuestNetworkGuru.java
index 18abc59,2104322..781b4b9
--- a/plugins/network-elements/ovs/src/com/cloud/network/guru/OvsGuestNetworkGuru.java
+++ b/plugins/network-elements/ovs/src/com/cloud/network/guru/OvsGuestNetworkGuru.java
@@@ -17,10 -17,9 +17,11 @@@
  package com.cloud.network.guru;
  
  import javax.ejb.Local;
 +import javax.inject.Inject;
  
+ import com.cloud.event.ActionEventUtils;
  import org.apache.log4j.Logger;
 +import org.springframework.stereotype.Component;
  
  import com.cloud.dc.DataCenter;
  import com.cloud.dc.DataCenter.NetworkType;

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/7b75f0d9/plugins/pom.xml
----------------------------------------------------------------------
diff --cc plugins/pom.xml
index a3a3189,f91c6ee..4daa71d
mode 100755,100644..100755
--- a/plugins/pom.xml
+++ b/plugins/pom.xml
@@@ -41,9 -41,9 +41,10 @@@
      <module>hypervisors/ovm</module>
      <module>hypervisors/xen</module>
      <module>hypervisors/kvm</module>
+     <module>event-bus/rabbitmq</module>
      <module>hypervisors/simulator</module>
      <module>hypervisors/baremetal</module>
 +    <module>hypervisors/ucs</module>
      <module>network-elements/elastic-loadbalancer</module>
      <module>network-elements/ovs</module>
      <module>network-elements/nicira-nvp</module>

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/7b75f0d9/server/pom.xml
----------------------------------------------------------------------
diff --cc server/pom.xml
index 5160a8d,ef1b68a..690f57f
--- a/server/pom.xml
+++ b/server/pom.xml
@@@ -81,20 -81,10 +81,25 @@@
        <scope>test</scope>
      </dependency>
      <dependency>
 +      <groupId>org.reflections</groupId>
 +      <artifactId>reflections</artifactId>
 +      <version>0.9.8</version>
 +    </dependency>
 +    <dependency>
 +      <groupId>org.apache.cloudstack</groupId>
 +      <artifactId>cloud-engine-api</artifactId>
 +      <version>${project.version}</version>
 +    </dependency>
 +    <dependency>
 +      <groupId>org.apache.cloudstack</groupId>
 +      <artifactId>cloud-api</artifactId>
 +      <version>${project.version}</version>
 +    </dependency>
++    <dependency>
+       <groupId>org.apache.cloudstack</groupId>
+       <artifactId>cloud-framework-events</artifactId>
+       <version>${project.version}</version>
+     </dependency>
    </dependencies>
    <build>
      <defaultGoal>install</defaultGoal>

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/7b75f0d9/server/src/com/cloud/alert/AlertManagerImpl.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/7b75f0d9/server/src/com/cloud/api/ApiDBUtils.java
----------------------------------------------------------------------
diff --cc server/src/com/cloud/api/ApiDBUtils.java
index a464b93,143e280..8e950ab
--- a/server/src/com/cloud/api/ApiDBUtils.java
+++ b/server/src/com/cloud/api/ApiDBUtils.java
@@@ -16,73 -16,8 +16,75 @@@
  // under the License.
  package com.cloud.api;
  
 +import java.util.ArrayList;
 +import java.util.EnumSet;
 +import java.util.List;
 +import java.util.Map;
 +import java.util.Set;
 +
 +import javax.annotation.PostConstruct;
 +import javax.inject.Inject;
 +
 +import org.apache.cloudstack.api.ApiConstants.HostDetails;
 +import org.apache.cloudstack.api.ApiConstants.VMDetails;
 +import org.apache.cloudstack.api.response.AccountResponse;
 +import org.apache.cloudstack.api.response.AsyncJobResponse;
 +import org.apache.cloudstack.api.response.DiskOfferingResponse;
 +import org.apache.cloudstack.api.response.DomainRouterResponse;
 +import org.apache.cloudstack.api.response.EventResponse;
 +import org.apache.cloudstack.api.response.HostResponse;
 +import org.apache.cloudstack.api.response.InstanceGroupResponse;
 +import org.apache.cloudstack.api.response.ProjectAccountResponse;
 +import org.apache.cloudstack.api.response.ProjectInvitationResponse;
 +import org.apache.cloudstack.api.response.ProjectResponse;
 +import org.apache.cloudstack.api.response.ResourceTagResponse;
 +import org.apache.cloudstack.api.response.SecurityGroupResponse;
 +import org.apache.cloudstack.api.response.ServiceOfferingResponse;
 +import org.apache.cloudstack.api.response.StoragePoolResponse;
 +import org.apache.cloudstack.api.response.UserResponse;
 +import org.apache.cloudstack.api.response.UserVmResponse;
 +import org.apache.cloudstack.api.response.VolumeResponse;
 +import org.apache.cloudstack.api.response.ZoneResponse;
 +
 +import org.springframework.stereotype.Component;
 +
 +import com.cloud.api.query.dao.AccountJoinDao;
 +import com.cloud.api.query.dao.AsyncJobJoinDao;
 +import com.cloud.api.query.dao.DataCenterJoinDao;
 +import com.cloud.api.query.dao.DiskOfferingJoinDao;
 +import com.cloud.api.query.dao.DomainRouterJoinDao;
 +import com.cloud.api.query.dao.HostJoinDao;
 +import com.cloud.api.query.dao.InstanceGroupJoinDao;
 +import com.cloud.api.query.dao.ProjectAccountJoinDao;
 +import com.cloud.api.query.dao.ProjectInvitationJoinDao;
 +import com.cloud.api.query.dao.ProjectJoinDao;
 +import com.cloud.api.query.dao.ResourceTagJoinDao;
 +import com.cloud.api.query.dao.SecurityGroupJoinDao;
 +import com.cloud.api.query.dao.ServiceOfferingJoinDao;
 +import com.cloud.api.query.dao.StoragePoolJoinDao;
 +import com.cloud.api.query.dao.UserAccountJoinDao;
 +import com.cloud.api.query.dao.UserVmJoinDao;
 +import com.cloud.api.query.dao.VolumeJoinDao;
 +import com.cloud.api.query.vo.AccountJoinVO;
 +import com.cloud.api.query.vo.AsyncJobJoinVO;
 +import com.cloud.api.query.vo.DataCenterJoinVO;
 +import com.cloud.api.query.vo.DiskOfferingJoinVO;
 +import com.cloud.api.query.vo.DomainRouterJoinVO;
 +import com.cloud.api.query.vo.EventJoinVO;
 +import com.cloud.api.query.vo.HostJoinVO;
 +import com.cloud.api.query.vo.InstanceGroupJoinVO;
 +import com.cloud.api.query.vo.ProjectAccountJoinVO;
 +import com.cloud.api.query.vo.ProjectInvitationJoinVO;
 +import com.cloud.api.query.vo.ProjectJoinVO;
 +import com.cloud.api.query.vo.ResourceTagJoinVO;
 +import com.cloud.api.query.vo.SecurityGroupJoinVO;
 +import com.cloud.api.query.vo.ServiceOfferingJoinVO;
 +import com.cloud.api.query.vo.StoragePoolJoinVO;
 +import com.cloud.api.query.vo.UserAccountJoinVO;
 +import com.cloud.api.query.vo.UserVmJoinVO;
 +import com.cloud.api.query.vo.VolumeJoinVO;
+ import com.cloud.api.query.dao.*;
+ import com.cloud.api.query.vo.*;
  import com.cloud.async.AsyncJob;
  import com.cloud.async.AsyncJobManager;
  import com.cloud.async.AsyncJobVO;
@@@ -122,48 -46,10 +114,52 @@@ import com.cloud.network.Network
  import com.cloud.network.Network.Capability;
  import com.cloud.network.Network.Provider;
  import com.cloud.network.Network.Service;
 +import com.cloud.network.NetworkManager;
 +import com.cloud.network.NetworkModel;
 +import com.cloud.network.NetworkProfile;
  import com.cloud.network.Networks.TrafficType;
 +import com.cloud.network.PhysicalNetworkServiceProvider;
 +import com.cloud.network.as.AutoScalePolicy;
 +import com.cloud.network.as.AutoScalePolicyConditionMapVO;
 +import com.cloud.network.as.AutoScalePolicyVO;
 +import com.cloud.network.as.AutoScaleVmGroupPolicyMapVO;
 +import com.cloud.network.as.AutoScaleVmGroupVO;
 +import com.cloud.network.as.AutoScaleVmProfileVO;
 +import com.cloud.network.as.ConditionVO;
 +import com.cloud.network.as.CounterVO;
 +import com.cloud.network.as.dao.AutoScalePolicyConditionMapDao;
 +import com.cloud.network.as.dao.AutoScalePolicyDao;
 +import com.cloud.network.as.dao.AutoScaleVmGroupDao;
 +import com.cloud.network.as.dao.AutoScaleVmGroupPolicyMapDao;
 +import com.cloud.network.as.dao.AutoScaleVmProfileDao;
 +import com.cloud.network.as.dao.ConditionDao;
 +import com.cloud.network.as.dao.CounterDao;
 +import com.cloud.network.dao.FirewallRulesCidrsDao;
 +import com.cloud.network.dao.FirewallRulesDao;
 +import com.cloud.network.dao.IPAddressDao;
 +import com.cloud.network.dao.IPAddressVO;
 +import com.cloud.network.dao.LoadBalancerDao;
 +import com.cloud.network.dao.LoadBalancerVO;
 +import com.cloud.network.dao.NetworkDao;
 +import com.cloud.network.dao.NetworkDomainDao;
 +import com.cloud.network.dao.NetworkDomainVO;
 +import com.cloud.network.dao.NetworkRuleConfigDao;
 +import com.cloud.network.dao.NetworkRuleConfigVO;
 +import com.cloud.network.dao.NetworkVO;
 +import com.cloud.network.dao.PhysicalNetworkDao;
 +import com.cloud.network.dao.PhysicalNetworkServiceProviderDao;
 +import com.cloud.network.dao.PhysicalNetworkServiceProviderVO;
 +import com.cloud.network.dao.PhysicalNetworkTrafficTypeDao;
 +import com.cloud.network.dao.PhysicalNetworkTrafficTypeVO;
 +import com.cloud.network.dao.PhysicalNetworkVO;
 +import com.cloud.network.dao.Site2SiteCustomerGatewayDao;
 +import com.cloud.network.dao.Site2SiteCustomerGatewayVO;
 +import com.cloud.network.dao.Site2SiteVpnGatewayDao;
 +import com.cloud.network.dao.Site2SiteVpnGatewayVO;
++import com.cloud.network.*;
+ import com.cloud.network.as.*;
+ import com.cloud.network.as.dao.*;
+ import com.cloud.network.dao.*;
  import com.cloud.network.router.VirtualRouter;
  import com.cloud.network.rules.FirewallRuleVO;
  import com.cloud.network.security.SecurityGroup;

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/7b75f0d9/server/src/com/cloud/api/ApiResponseHelper.java
----------------------------------------------------------------------
diff --cc server/src/com/cloud/api/ApiResponseHelper.java
index 9aae154,0ae4f0f..3821aab
--- a/server/src/com/cloud/api/ApiResponseHelper.java
+++ b/server/src/com/cloud/api/ApiResponseHelper.java
@@@ -16,127 -16,9 +16,85 @@@
  // under the License.
  package com.cloud.api;
  
- import static java.util.Collections.emptyList;
- import static java.util.Collections.singletonList;
- 
- import java.text.DecimalFormat;
- import java.util.ArrayList;
- import java.util.EnumSet;
- import java.util.HashMap;
- import java.util.HashSet;
- import java.util.List;
- import java.util.Map;
- import java.util.Set;
- import java.util.StringTokenizer;
- 
- import org.apache.cloudstack.api.BaseCmd;
- import org.apache.cloudstack.api.ResponseGenerator;
- import org.apache.log4j.Logger;
- 
- import org.apache.cloudstack.acl.ControlledEntity;
- import org.apache.cloudstack.acl.ControlledEntity.ACLType;
- import org.apache.cloudstack.api.ApiConstants.HostDetails;
- import org.apache.cloudstack.api.ApiConstants.VMDetails;
- import org.apache.cloudstack.api.command.user.job.QueryAsyncJobResultCmd;
- import org.apache.cloudstack.api.response.AccountResponse;
- 
  import com.cloud.api.query.ViewResponseHelper;
- import com.cloud.api.query.vo.AccountJoinVO;
- import com.cloud.api.query.vo.AsyncJobJoinVO;
- import com.cloud.api.query.vo.ControlledViewEntity;
- import com.cloud.api.query.vo.DataCenterJoinVO;
- import com.cloud.api.query.vo.DiskOfferingJoinVO;
- import com.cloud.api.query.vo.DomainRouterJoinVO;
- import com.cloud.api.query.vo.EventJoinVO;
- import com.cloud.api.query.vo.HostJoinVO;
- import com.cloud.api.query.vo.InstanceGroupJoinVO;
- import com.cloud.api.query.vo.ProjectAccountJoinVO;
- import com.cloud.api.query.vo.ProjectInvitationJoinVO;
- import com.cloud.api.query.vo.ProjectJoinVO;
- import com.cloud.api.query.vo.ResourceTagJoinVO;
- import com.cloud.api.query.vo.SecurityGroupJoinVO;
- import com.cloud.api.query.vo.ServiceOfferingJoinVO;
- import com.cloud.api.query.vo.StoragePoolJoinVO;
- import com.cloud.api.query.vo.UserAccountJoinVO;
- import com.cloud.api.query.vo.UserVmJoinVO;
- import com.cloud.api.query.vo.VolumeJoinVO;
+ import com.cloud.api.query.vo.*;
  import com.cloud.api.response.ApiResponseSerializer;
 +import org.apache.cloudstack.api.response.AsyncJobResponse;
 +import org.apache.cloudstack.api.response.AutoScalePolicyResponse;
 +import org.apache.cloudstack.api.response.AutoScaleVmGroupResponse;
 +import org.apache.cloudstack.api.response.AutoScaleVmProfileResponse;
 +import org.apache.cloudstack.api.response.CapabilityResponse;
 +import org.apache.cloudstack.api.response.CapacityResponse;
 +import org.apache.cloudstack.api.response.ClusterResponse;
 +import org.apache.cloudstack.api.response.ConditionResponse;
 +import org.apache.cloudstack.api.response.ConfigurationResponse;
 +import org.apache.cloudstack.api.response.ControlledEntityResponse;
 +import org.apache.cloudstack.api.response.CounterResponse;
 +import org.apache.cloudstack.api.response.CreateCmdResponse;
 +import org.apache.cloudstack.api.response.DiskOfferingResponse;
 +import org.apache.cloudstack.api.response.DomainResponse;
 +import org.apache.cloudstack.api.response.DomainRouterResponse;
 +import org.apache.cloudstack.api.response.EventResponse;
 +import org.apache.cloudstack.api.response.ExtractResponse;
 +import org.apache.cloudstack.api.response.FirewallResponse;
 +import org.apache.cloudstack.api.response.FirewallRuleResponse;
 +import org.apache.cloudstack.api.response.GuestOSResponse;
 +import org.apache.cloudstack.api.response.HostResponse;
 +import org.apache.cloudstack.api.response.HypervisorCapabilitiesResponse;
 +import org.apache.cloudstack.api.response.ControlledViewEntityResponse;
 +import org.apache.cloudstack.api.response.IPAddressResponse;
 +import org.apache.cloudstack.api.response.InstanceGroupResponse;
 +import org.apache.cloudstack.api.response.IpForwardingRuleResponse;
 +import org.apache.cloudstack.api.response.LBStickinessPolicyResponse;
 +import org.apache.cloudstack.api.response.LBStickinessResponse;
 +import org.apache.cloudstack.api.response.LDAPConfigResponse;
 +import org.apache.cloudstack.api.response.LoadBalancerResponse;
 +import org.apache.cloudstack.api.response.NetworkACLResponse;
 +import org.apache.cloudstack.api.response.NetworkOfferingResponse;
 +import org.apache.cloudstack.api.response.NetworkResponse;
 +import org.apache.cloudstack.api.response.PhysicalNetworkResponse;
 +import org.apache.cloudstack.api.response.PodResponse;
 +import org.apache.cloudstack.api.response.PrivateGatewayResponse;
 +import org.apache.cloudstack.api.response.ProjectAccountResponse;
 +import org.apache.cloudstack.api.response.ProjectInvitationResponse;
 +import org.apache.cloudstack.api.response.ProjectResponse;
 +import org.apache.cloudstack.api.response.ProviderResponse;
 +import org.apache.cloudstack.api.response.RemoteAccessVpnResponse;
 +import org.apache.cloudstack.api.response.ResourceCountResponse;
 +import org.apache.cloudstack.api.response.ResourceLimitResponse;
 +import org.apache.cloudstack.api.response.ResourceTagResponse;
 +import org.apache.cloudstack.api.response.SecurityGroupResponse;
 +import org.apache.cloudstack.api.response.SecurityGroupRuleResponse;
 +import org.apache.cloudstack.api.response.ServiceOfferingResponse;
 +import org.apache.cloudstack.api.response.ServiceResponse;
 +import org.apache.cloudstack.api.response.Site2SiteCustomerGatewayResponse;
 +import org.apache.cloudstack.api.response.Site2SiteVpnConnectionResponse;
 +import org.apache.cloudstack.api.response.Site2SiteVpnGatewayResponse;
 +import org.apache.cloudstack.api.response.SnapshotPolicyResponse;
 +import org.apache.cloudstack.api.response.SnapshotResponse;
 +import org.apache.cloudstack.api.response.SnapshotScheduleResponse;
 +import org.apache.cloudstack.api.response.StaticRouteResponse;
 +import org.apache.cloudstack.api.response.StorageNetworkIpRangeResponse;
 +import org.apache.cloudstack.api.response.StoragePoolResponse;
 +import org.apache.cloudstack.api.response.SwiftResponse;
 +import org.apache.cloudstack.api.response.SystemVmInstanceResponse;
 +import org.apache.cloudstack.api.response.SystemVmResponse;
 +import org.apache.cloudstack.api.response.TemplatePermissionsResponse;
 +import org.apache.cloudstack.api.response.TemplateResponse;
 +import org.apache.cloudstack.api.response.TrafficTypeResponse;
 +import org.apache.cloudstack.api.response.UserResponse;
 +import org.apache.cloudstack.api.response.UserVmResponse;
 +import org.apache.cloudstack.api.response.VirtualRouterProviderResponse;
 +import org.apache.cloudstack.api.response.VlanIpRangeResponse;
 +import org.apache.cloudstack.api.response.VolumeResponse;
 +import org.apache.cloudstack.api.response.VpcOfferingResponse;
 +import org.apache.cloudstack.api.response.VpcResponse;
 +import org.apache.cloudstack.api.response.VpnUsersResponse;
 +import org.apache.cloudstack.api.response.ZoneResponse;
 +
 +import org.apache.cloudstack.api.response.S3Response;
 +import org.springframework.stereotype.Component;
 +
  import com.cloud.async.AsyncJob;
  import com.cloud.capacity.Capacity;
  import com.cloud.capacity.CapacityVO;
@@@ -164,34 -38,10 +115,29 @@@ import com.cloud.network.Network
  import com.cloud.network.Network.Capability;
  import com.cloud.network.Network.Provider;
  import com.cloud.network.Network.Service;
 +import com.cloud.network.NetworkProfile;
  import com.cloud.network.Networks.TrafficType;
 -import com.cloud.network.as.*;
 +import com.cloud.network.PhysicalNetwork;
 +import com.cloud.network.PhysicalNetworkServiceProvider;
 +import com.cloud.network.PhysicalNetworkTrafficType;
 +import com.cloud.network.RemoteAccessVpn;
 +import com.cloud.network.Site2SiteCustomerGateway;
 +import com.cloud.network.Site2SiteVpnConnection;
 +import com.cloud.network.Site2SiteVpnGateway;
 +import com.cloud.network.VirtualRouterProvider;
 +import com.cloud.network.VpnUser;
 +import com.cloud.network.as.AutoScalePolicy;
 +import com.cloud.network.as.AutoScaleVmGroup;
 +import com.cloud.network.as.AutoScaleVmProfile;
 +import com.cloud.network.as.AutoScaleVmProfileVO;
 +import com.cloud.network.as.Condition;
 +import com.cloud.network.as.ConditionVO;
 +import com.cloud.network.as.Counter;
 +import com.cloud.network.dao.IPAddressVO;
 +import com.cloud.network.dao.NetworkVO;
 +import com.cloud.network.dao.PhysicalNetworkVO;
  import com.cloud.network.router.VirtualRouter;
- import com.cloud.network.rules.FirewallRule;
- import com.cloud.network.rules.FirewallRuleVO;
- import com.cloud.network.rules.LoadBalancer;
- import com.cloud.network.rules.PortForwardingRule;
- import com.cloud.network.rules.StaticNatRule;
- import com.cloud.network.rules.StickinessPolicy;
+ import com.cloud.network.rules.*;
  import com.cloud.network.security.SecurityGroup;
  import com.cloud.network.security.SecurityRule;
  import com.cloud.network.security.SecurityRule.SecurityRuleType;
@@@ -244,8 -81,23 +176,24 @@@ import com.cloud.vm.InstanceGroup
  import com.cloud.vm.NicProfile;
  import com.cloud.vm.VirtualMachine;
  import com.cloud.vm.VirtualMachine.Type;
+ import org.apache.cloudstack.acl.ControlledEntity;
+ import org.apache.cloudstack.acl.ControlledEntity.ACLType;
+ import org.apache.cloudstack.api.ApiConstants.HostDetails;
+ import org.apache.cloudstack.api.ApiConstants.VMDetails;
+ import org.apache.cloudstack.api.BaseCmd;
+ import org.apache.cloudstack.api.ResponseGenerator;
+ import org.apache.cloudstack.api.command.user.job.QueryAsyncJobResultCmd;
+ import org.apache.cloudstack.api.response.*;
+ import org.apache.cloudstack.region.Region;
+ import org.apache.log4j.Logger;
+ 
+ import java.text.DecimalFormat;
+ import java.util.*;
+ 
+ import static java.util.Collections.emptyList;
+ import static java.util.Collections.singletonList;
  
 +@Component
  public class ApiResponseHelper implements ResponseGenerator {
  
      public final Logger s_logger = Logger.getLogger(ApiResponseHelper.class);
@@@ -2741,7 -2593,17 +2689,17 @@@
          return response;
      }
  
 -	@Override
 +    @Override
+ 	public RegionResponse createRegionResponse(Region region) {
+ 		RegionResponse response = new RegionResponse();
+ 		response.setId(region.getId());
+ 		response.setName(region.getName());
+ 		response.setEndPoint(region.getEndPoint());
+ 		response.setObjectName("region");
+ 		return response;
+ 	}
+ 
+     @Override
      public ResourceTagResponse createResourceTagResponse(ResourceTag resourceTag, boolean keyValueOnly) {
          ResourceTagJoinVO rto = ApiDBUtils.newResourceTagView(resourceTag);
          return ApiDBUtils.newResourceTagResponse(rto, keyValueOnly);
@@@ -3119,9 -2981,7 +3077,7 @@@
          response.setObjectName("vpnconnection");
          return response;
      }
 -    
 +
- 
- 
      @Override
      public GuestOSResponse createGuestOSResponse(GuestOS guestOS) {
          GuestOSResponse response = new GuestOSResponse();

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/7b75f0d9/server/src/com/cloud/api/ApiServer.java
----------------------------------------------------------------------
diff --cc server/src/com/cloud/api/ApiServer.java
index 80fffd3,714a500..aa28125
--- a/server/src/com/cloud/api/ApiServer.java
+++ b/server/src/com/cloud/api/ApiServer.java
@@@ -52,19 -50,11 +52,23 @@@ import javax.inject.Inject
  import javax.servlet.http.HttpServletResponse;
  import javax.servlet.http.HttpSession;
  
 +import org.apache.cloudstack.acl.APIChecker;
 +import org.apache.cloudstack.api.APICommand;
 +import org.apache.cloudstack.api.ApiErrorCode;
 +import org.apache.cloudstack.api.BaseAsyncCmd;
 +import org.apache.cloudstack.api.BaseAsyncCreateCmd;
 +import org.apache.cloudstack.api.BaseCmd;
 +import org.apache.cloudstack.api.BaseListCmd;
 +import org.apache.cloudstack.api.ResponseObject;
 +import org.apache.cloudstack.api.ServerApiException;
 +import org.apache.cloudstack.api.command.admin.host.ListHostsCmd;
 +import org.apache.cloudstack.api.command.admin.router.ListRoutersCmd;
 +import org.apache.cloudstack.api.command.admin.storage.ListStoragePoolsCmd;
 +import org.apache.cloudstack.api.command.admin.user.ListUsersCmd;
+ import com.cloud.event.ActionEventUtils;
+ import com.cloud.utils.ReflectUtil;
+ import org.apache.cloudstack.acl.APILimitChecker;
 -import org.apache.cloudstack.acl.APIChecker;
+ import org.apache.cloudstack.api.*;
  import org.apache.cloudstack.api.command.user.account.ListAccountsCmd;
  import org.apache.cloudstack.api.command.user.account.ListProjectAccountsCmd;
  import org.apache.cloudstack.api.command.user.event.ListEventsCmd;
@@@ -107,11 -91,22 +111,13 @@@ import org.apache.http.protocol.Respons
  import org.apache.http.protocol.ResponseDate;
  import org.apache.http.protocol.ResponseServer;
  import org.apache.log4j.Logger;
 +import org.springframework.stereotype.Component;
  
 -import org.apache.cloudstack.api.command.admin.host.ListHostsCmd;
 -import org.apache.cloudstack.api.command.admin.router.ListRoutersCmd;
 -import org.apache.cloudstack.api.command.admin.storage.ListStoragePoolsCmd;
 -import org.apache.cloudstack.api.command.admin.user.ListUsersCmd;
  import org.apache.cloudstack.api.command.user.offering.ListDiskOfferingsCmd;
  import org.apache.cloudstack.api.command.user.offering.ListServiceOfferingsCmd;
 -import org.apache.cloudstack.api.command.user.project.ListProjectInvitationsCmd;
 -import org.apache.cloudstack.api.command.user.project.ListProjectsCmd;
 -import org.apache.cloudstack.api.command.user.securitygroup.ListSecurityGroupsCmd;
 -import org.apache.cloudstack.api.command.user.tag.ListTagsCmd;
  import com.cloud.api.response.ApiResponseSerializer;
 -import org.apache.cloudstack.api.response.ExceptionResponse;
 -import org.apache.cloudstack.api.response.ListResponse;
+ import org.apache.cloudstack.region.RegionManager;
+ 
  import com.cloud.async.AsyncCommandQueued;
  import com.cloud.async.AsyncJob;
  import com.cloud.async.AsyncJobManager;
@@@ -137,12 -133,11 +142,11 @@@ import com.cloud.user.User
  import com.cloud.user.UserAccount;
  import com.cloud.user.UserContext;
  import com.cloud.user.UserVO;
 +import com.cloud.utils.NumbersUtil;
  import com.cloud.utils.Pair;
- import com.cloud.utils.ReflectUtil;
 -import com.cloud.utils.component.Adapters;
  import com.cloud.utils.StringUtils;
 -import com.cloud.utils.component.ComponentLocator;
 -import com.cloud.utils.component.Inject;
 +import com.cloud.utils.component.ComponentContext;
 +import com.cloud.utils.component.PluggableService;
  import com.cloud.utils.concurrency.NamedThreadFactory;
  import com.cloud.utils.db.SearchCriteria;
  import com.cloud.utils.db.Transaction;

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/7b75f0d9/server/src/com/cloud/baremetal/BareMetalTemplateAdapter.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/7b75f0d9/server/src/com/cloud/baremetal/BareMetalVmManagerImpl.java
----------------------------------------------------------------------
diff --cc server/src/com/cloud/baremetal/BareMetalVmManagerImpl.java
index 411e27e,6ff37ea..8e447bc
--- a/server/src/com/cloud/baremetal/BareMetalVmManagerImpl.java
+++ b/server/src/com/cloud/baremetal/BareMetalVmManagerImpl.java
@@@ -39,10 -21,6 +39,8 @@@ import com.cloud.agent.api.StopAnswer
  import com.cloud.agent.api.baremetal.IpmISetBootDevCommand;
  import com.cloud.agent.api.baremetal.IpmiBootorResetCommand;
  import com.cloud.agent.manager.Commands;
 +import org.apache.cloudstack.api.command.user.vm.StartVMCmd;
- import org.springframework.context.annotation.Primary;
- import org.springframework.stereotype.Component;
 +
  import com.cloud.baremetal.PxeServerManager.PxeServerType;
  import com.cloud.configuration.Resource.ResourceType;
  import com.cloud.configuration.dao.ConfigurationDao;
@@@ -76,11 -47,8 +68,12 @@@ import com.cloud.storage.VMTemplateVO
  import com.cloud.storage.Volume;
  import com.cloud.template.TemplateAdapter;
  import com.cloud.template.TemplateAdapter.TemplateAdapterType;
 -import com.cloud.template.TemplateProfile;
 +import com.cloud.user.Account;
 +import com.cloud.user.AccountVO;
 +import com.cloud.user.SSHKeyPair;
 +import com.cloud.user.User;
 +import com.cloud.user.UserContext;
+ import com.cloud.user.*;
  import com.cloud.uservm.UserVm;
  import com.cloud.utils.NumbersUtil;
  import com.cloud.utils.Pair;
@@@ -101,15 -65,28 +88,13 @@@ import com.cloud.vm.*
  import com.cloud.vm.VirtualMachine.Event;
  import com.cloud.vm.VirtualMachine.State;
  import com.cloud.vm.VirtualMachine.Type;
- import com.cloud.vm.VirtualMachineName;
- import com.cloud.vm.VirtualMachineProfile;
  import com.cloud.vm.VirtualMachineProfile.Param;
 -import org.apache.cloudstack.api.command.user.template.CreateTemplateCmd;
 -import org.apache.cloudstack.api.command.user.vm.DeployVMCmd;
 -import org.apache.cloudstack.api.command.user.vm.StartVMCmd;
 -import org.apache.cloudstack.api.command.user.vm.UpgradeVMCmd;
 -import org.apache.cloudstack.api.command.user.volume.AttachVolumeCmd;
 -import org.apache.cloudstack.api.command.user.volume.DetachVolumeCmd;
 -import org.apache.log4j.Logger;
 -
 -import javax.ejb.Local;
 -import javax.naming.ConfigurationException;
 -import java.util.ArrayList;
 -import java.util.HashMap;
 -import java.util.List;
 -import java.util.Map;
 -import java.util.concurrent.Executors;
  
  @Local(value={BareMetalVmManager.class, BareMetalVmService.class})
 -public class BareMetalVmManagerImpl extends UserVmManagerImpl implements BareMetalVmManager, BareMetalVmService, Manager,
 +public class BareMetalVmManagerImpl extends UserVmManagerImpl implements BareMetalVmManager, BareMetalVmService,
  		StateListener<State, VirtualMachine.Event, VirtualMachine> {
  	private static final Logger s_logger = Logger.getLogger(BareMetalVmManagerImpl.class); 
 -	private ConfigurationDao _configDao;
 +	@Inject ConfigurationDao _configDao;
  	@Inject PxeServerManager _pxeMgr;
  	@Inject ResourceManager _resourceMgr;
  	

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/7b75f0d9/server/src/com/cloud/domain/dao/DomainDaoImpl.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/7b75f0d9/server/src/com/cloud/event/ActionEventUtils.java
----------------------------------------------------------------------
diff --cc server/src/com/cloud/event/ActionEventUtils.java
index 0000000,744f46f..22589f1
mode 000000,100755..100755
--- a/server/src/com/cloud/event/ActionEventUtils.java
+++ b/server/src/com/cloud/event/ActionEventUtils.java
@@@ -1,0 -1,288 +1,296 @@@
+ // 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.event;
+ 
+ import com.cloud.event.dao.EventDao;
+ import com.cloud.server.ManagementServer;
+ import com.cloud.user.Account;
+ import com.cloud.user.AccountVO;
+ import com.cloud.user.User;
+ import com.cloud.user.UserContext;
+ import com.cloud.user.dao.AccountDao;
+ import com.cloud.user.dao.UserDao;
 -import com.cloud.utils.component.Adapters;
+ import com.cloud.utils.component.AnnotationInterceptor;
 -import com.cloud.utils.component.ComponentLocator;
+ import net.sf.cglib.proxy.Callback;
+ import net.sf.cglib.proxy.MethodInterceptor;
+ import net.sf.cglib.proxy.MethodProxy;
+ import org.apache.cloudstack.framework.events.EventBus;
+ import org.apache.cloudstack.framework.events.EventBusException;
+ import org.apache.log4j.Logger;
++import org.springframework.stereotype.Component;
+ 
+ import java.lang.reflect.AnnotatedElement;
+ import java.lang.reflect.Method;
 -import java.util.Enumeration;
+ import java.util.HashMap;
+ import java.util.Map;
+ 
 -public class ActionEventUtils {
++import javax.annotation.PostConstruct;
++import javax.inject.Inject;
+ 
 -    private static EventDao _eventDao = ComponentLocator.getLocator(ManagementServer.Name).getDao(EventDao.class);
 -    private static AccountDao _accountDao = ComponentLocator.getLocator(ManagementServer.Name).getDao(AccountDao.class);
 -    protected static UserDao _userDao = ComponentLocator.getLocator(ManagementServer.Name).getDao(UserDao.class);
++@Component
++public class ActionEventUtils {
+     private static final Logger s_logger = Logger.getLogger(ActionEventUtils.class);
+ 
++    private static EventDao _eventDao;
++    private static AccountDao _accountDao;
++    protected static UserDao _userDao;
++
+     // get the event bus provider if configured
 -    protected static EventBus _eventBus = null;
++    protected static EventBus _eventBus;
+ 
 -    static {
 -        Adapters<EventBus> eventBusImpls = ComponentLocator.getLocator(ManagementServer.Name).getAdapters(EventBus.class);
 -        if (eventBusImpls != null) {
 -            Enumeration<EventBus> eventBusenum = eventBusImpls.enumeration();
 -            if (eventBusenum != null && eventBusenum.hasMoreElements()) {
 -                _eventBus = eventBusenum.nextElement(); // configure event bus if configured
 -            }
 -        }
++    @Inject EventDao eventDao;
++    @Inject AccountDao accountDao;
++    @Inject UserDao userDao;
++    
++    public ActionEventUtils() {
++    }
++    
++    @PostConstruct
++    void init() {
++    	_eventDao = eventDao;
++    	_accountDao = accountDao;
++    	_userDao = userDao;
++    	
++    	// TODO we will do injection of event bus later
+     }
+ 
+     public static Long onActionEvent(Long userId, Long accountId, Long domainId, String type, String description) {
+ 
+         publishOnEventBus(userId, accountId, EventCategory.ACTION_EVENT.getName(),
+                 type, com.cloud.event.Event.State.Completed);
+ 
+         Event event = persistActionEvent(userId, accountId, domainId, null, type, Event.State.Completed,
+                 description, null);
+ 
+         return event.getId();
+     }
+ 
+     /*
+      * Save event after scheduling an async job
+      */
+     public static Long onScheduledActionEvent(Long userId, Long accountId, String type, String description,
+                                               long startEventId) {
+ 
+         publishOnEventBus(userId, accountId, EventCategory.ACTION_EVENT.getName(), type,
+                 com.cloud.event.Event.State.Scheduled);
+ 
+         Event event = persistActionEvent(userId, accountId, null, null, type, Event.State.Scheduled,
+                 description, startEventId);
+ 
+         return event.getId();
+     }
+ 
+     /*
+      * Save event after starting execution of an async job
+      */
+     public static Long onStartedActionEvent(Long userId, Long accountId, String type, String description,
+                                             long startEventId) {
+ 
+         publishOnEventBus(userId, accountId, EventCategory.ACTION_EVENT.getName(), type,
+                 com.cloud.event.Event.State.Started);
+ 
+         Event event = persistActionEvent(userId, accountId, null, null, type, Event.State.Started,
+                 description, startEventId);
+         return event.getId();
+     }
+ 
+     public static Long onCompletedActionEvent(Long userId, Long accountId, String level, String type,
+                                               String description, long startEventId) {
+ 
+         publishOnEventBus(userId, accountId, EventCategory.ACTION_EVENT.getName(), type,
+                 com.cloud.event.Event.State.Completed);
+ 
+         Event event = persistActionEvent(userId, accountId, null, level, type, Event.State.Completed,
+                 description, startEventId);
+ 
+         return event.getId();
+     }
+ 
+     public static Long onCreatedActionEvent(Long userId, Long accountId, String level, String type, String description) {
+ 
+         publishOnEventBus(userId, accountId, EventCategory.ACTION_EVENT.getName(), type,
+                 com.cloud.event.Event.State.Created);
+ 
+         Event event = persistActionEvent(userId, accountId, null, level, type, Event.State.Created, description, null);
+ 
+         return event.getId();
+     }
+ 
+     private static Event persistActionEvent(Long userId, Long accountId, Long domainId, String level, String type,
+                                            Event.State state, String description, Long startEventId) {
+         EventVO event = new EventVO();
+         event.setUserId(userId);
+         event.setAccountId(accountId);
+         event.setType(type);
+         event.setState(state);
+         event.setDescription(description);
+         if (domainId != null) {
+             event.setDomainId(domainId);
+         } else {
+             event.setDomainId(getDomainId(accountId));
+         }
+         if (level != null && !level.isEmpty()) {
+             event.setLevel(level);
+         }
+         if (startEventId != null) {
+             event.setStartId(startEventId);
+         }
+         event = _eventDao.persist(event);
+         return event;
+     }
+ 
+     private static void publishOnEventBus(long userId, long accountId, String eventCategory,
+                                           String eventType, Event.State state) {
+         if (_eventBus == null) {
+             return; // no provider is configured to provide events bus, so just return
+         }
+ 
+         org.apache.cloudstack.framework.events.Event event = new org.apache.cloudstack.framework.events.Event(
+                 ManagementServer.Name,
+                 eventCategory,
+                 eventType,
+                 EventTypes.getEntityForEvent(eventType), null);
+ 
+         Map<String, String> eventDescription = new HashMap<String, String>();
+         Account account = _accountDao.findById(accountId);
+         User user = _userDao.findById(userId);
+         eventDescription.put("user", user.getUuid());
+         eventDescription.put("account", account.getUuid());
+         eventDescription.put("event", eventType);
+         eventDescription.put("status", state.toString());
+         event.setDescription(eventDescription);
+ 
+         try {
+             _eventBus.publish(event);
+         } catch (EventBusException e) {
+             s_logger.warn("Failed to publish action event on the the event bus.");
+         }
+     }
+ 
+     private static long getDomainId(long accountId){
+         AccountVO account = _accountDao.findByIdIncludingRemoved(accountId);
+         return account.getDomainId();
+     }
+ 
+     public static class ActionEventCallback implements MethodInterceptor, AnnotationInterceptor<EventVO> {
+ 
+         @Override
+         public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
+             EventVO event = interceptStart(method);
+             boolean success = true;
+             try {
+                 return methodProxy.invokeSuper(object, args);
+             } catch (Exception e){
+                 success = false;
+                 interceptException(method, event);
+                 throw e;
+             } finally {
+                 if(success){
+                     interceptComplete(method, event);
+                 }
+             }
+         }
+ 
+         @Override
+         public boolean needToIntercept(AnnotatedElement element) {
+             if (!(element instanceof Method)) {
+                 return false;
+ 
+             }
+             Method method = (Method)element;
+             ActionEvent actionEvent = method.getAnnotation(ActionEvent.class);
+             if (actionEvent != null) {
+                 return true;
+             }
+ 
+             return false;
+         }
+ 
+         @Override
+         public EventVO interceptStart(AnnotatedElement element) {
+             EventVO event = null;
+             Method method = (Method)element;
+             ActionEvent actionEvent = method.getAnnotation(ActionEvent.class);
+             if (actionEvent != null) {
+                 boolean async = actionEvent.async();
+                 if(async){
+                     UserContext ctx = UserContext.current();
+                     long userId = ctx.getCallerUserId();
+                     long accountId = ctx.getAccountId();
+                     long startEventId = ctx.getStartEventId();
+                     String eventDescription = actionEvent.eventDescription();
+                     if(ctx.getEventDetails() != null){
+                         eventDescription += ". "+ctx.getEventDetails();
+                     }
+                     ActionEventUtils.onStartedActionEvent(userId, accountId, actionEvent.eventType(), eventDescription, startEventId);
+                 }
+             }
+             return event;
+         }
+ 
+         @Override
+         public void interceptComplete(AnnotatedElement element, EventVO event) {
+             Method method = (Method)element;
+             ActionEvent actionEvent = method.getAnnotation(ActionEvent.class);
+             if (actionEvent != null) {
+                 UserContext ctx = UserContext.current();
+                 long userId = ctx.getCallerUserId();
+                 long accountId = ctx.getAccountId();
+                 long startEventId = ctx.getStartEventId();
+                 String eventDescription = actionEvent.eventDescription();
+                 if(ctx.getEventDetails() != null){
+                     eventDescription += ". "+ctx.getEventDetails();
+                 }
+                 if(actionEvent.create()){
+                     //This start event has to be used for subsequent events of this action
+                     startEventId = ActionEventUtils.onCreatedActionEvent(userId, accountId, EventVO.LEVEL_INFO, actionEvent.eventType(), "Successfully created entity for " + eventDescription);
+                     ctx.setStartEventId(startEventId);
+                 } else {
+                     ActionEventUtils.onCompletedActionEvent(userId, accountId, EventVO.LEVEL_INFO, actionEvent.eventType(), "Successfully completed " + eventDescription, startEventId);
+                 }
+             }
+         }
+ 
+         @Override
+         public void interceptException(AnnotatedElement element, EventVO event) {
+             Method method = (Method)element;
+             ActionEvent actionEvent = method.getAnnotation(ActionEvent.class);
+             if (actionEvent != null) {
+                 UserContext ctx = UserContext.current();
+                 long userId = ctx.getCallerUserId();
+                 long accountId = ctx.getAccountId();
+                 long startEventId = ctx.getStartEventId();
+                 String eventDescription = actionEvent.eventDescription();
+                 if(ctx.getEventDetails() != null){
+                     eventDescription += ". "+ctx.getEventDetails();
+                 }
+                 if(actionEvent.create()){
+                     long eventId = ActionEventUtils.onCreatedActionEvent(userId, accountId, EventVO.LEVEL_ERROR, actionEvent.eventType(), "Error while creating entity for " + eventDescription);
+                     ctx.setStartEventId(eventId);
+                 } else {
+                     ActionEventUtils.onCompletedActionEvent(userId, accountId, EventVO.LEVEL_ERROR, actionEvent.eventType(), "Error while " + eventDescription, startEventId);
+                 }
+             }
+         }
+ 
+         @Override
+         public Callback getCallback() {
+             return this;
+         }
+     }
+ }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/7b75f0d9/server/src/com/cloud/event/AlertGenerator.java
----------------------------------------------------------------------
diff --cc server/src/com/cloud/event/AlertGenerator.java
index 0000000,4286377..2dc7f3e
mode 000000,100644..100644
--- a/server/src/com/cloud/event/AlertGenerator.java
+++ b/server/src/com/cloud/event/AlertGenerator.java
@@@ -1,0 -1,87 +1,93 @@@
+ // 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.event;
+ 
+ import com.cloud.dc.DataCenterVO;
+ import com.cloud.dc.HostPodVO;
+ import com.cloud.dc.dao.DataCenterDao;
+ import com.cloud.dc.dao.HostPodDao;
+ import com.cloud.server.ManagementServer;
 -import com.cloud.utils.component.Adapters;
 -import com.cloud.utils.component.ComponentLocator;
+ import org.apache.cloudstack.framework.events.*;
+ import org.apache.log4j.Logger;
++import org.springframework.stereotype.Component;
+ 
+ import java.util.Enumeration;
+ import java.util.HashMap;
+ import java.util.Map;
+ 
++import javax.annotation.PostConstruct;
++import javax.inject.Inject;
++
++@Component
+ public class AlertGenerator {
+ 
+     private static final Logger s_logger = Logger.getLogger(AlertGenerator.class);
 -    private static DataCenterDao _dcDao =  ComponentLocator.getLocator(ManagementServer.Name).getDao(DataCenterDao.class);
 -    private static HostPodDao _podDao = ComponentLocator.getLocator(ManagementServer.Name).getDao(HostPodDao.class);
++    private static DataCenterDao _dcDao;
++    private static HostPodDao _podDao;
+ 
+     // get the event bus provider if configured
+     protected static EventBus _eventBus = null;
 -    static {
 -        Adapters<EventBus> eventBusImpls = ComponentLocator.getLocator(ManagementServer.Name).getAdapters(EventBus.class);
 -        if (eventBusImpls != null) {
 -            Enumeration<EventBus> eventBusenum = eventBusImpls.enumeration();
 -            if (eventBusenum != null && eventBusenum.hasMoreElements()) {
 -                _eventBus = eventBusenum.nextElement(); // configure event bus if configured
 -            }
 -        }
 -    }
+ 
++    @Inject DataCenterDao dcDao;
++    @Inject HostPodDao podDao;
++    
++    public AlertGenerator() {
++    }
++    
++    @PostConstruct
++    void init() {
++    	_dcDao = dcDao;
++    	_podDao = podDao;
++    }
++    
+     public static void publishAlertOnEventBus(String alertType, long dataCenterId, Long podId, String subject, String body) {
+         if (_eventBus == null) {
+             return; // no provider is configured to provider events bus, so just return
+         }
+ 
+         org.apache.cloudstack.framework.events.Event event =
+                 new org.apache.cloudstack.framework.events.Event(ManagementServer.Name,
+                         EventCategory.ALERT_EVENT.getName(),
+                         alertType,
+                         null,
+                         null);
+ 
+         Map<String, String> eventDescription = new HashMap<String, String>();
+         DataCenterVO dc = _dcDao.findById(dataCenterId);
+         HostPodVO pod = _podDao.findById(podId);
+ 
+         eventDescription.put("event", alertType);
+         if (dc != null) {
+             eventDescription.put("dataCenterId", dc.getUuid());
+         } else {
+             eventDescription.put("dataCenterId", null);
+         }
+         if (pod != null) {
+             eventDescription.put("podId", pod.getUuid());
+         } else {
+             eventDescription.put("podId", null);
+         }
+         event.setDescription(eventDescription);
+ 
+         try {
+             _eventBus.publish(event);
+         } catch (EventBusException e) {
+             s_logger.warn("Failed to publish alert on the the event bus.");
+         }
+     }
+ }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/7b75f0d9/server/src/com/cloud/event/UsageEventUtils.java
----------------------------------------------------------------------
diff --cc server/src/com/cloud/event/UsageEventUtils.java
index 0000000,0e6edb9..d59262a
mode 000000,100644..100644
--- a/server/src/com/cloud/event/UsageEventUtils.java
+++ b/server/src/com/cloud/event/UsageEventUtils.java
@@@ -1,0 -1,136 +1,143 @@@
+ // 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.event;
+ 
+ import com.cloud.dc.DataCenterVO;
+ import com.cloud.dc.dao.DataCenterDao;
+ import com.cloud.event.dao.UsageEventDao;
+ import com.cloud.server.ManagementServer;
+ import com.cloud.user.Account;
+ import com.cloud.user.dao.AccountDao;
 -import com.cloud.utils.component.Adapters;
 -import com.cloud.utils.component.ComponentLocator;
+ import org.apache.cloudstack.framework.events.EventBus;
+ import org.apache.cloudstack.framework.events.Event;
+ import org.apache.cloudstack.framework.events.EventBusException;
+ import org.apache.log4j.Logger;
++import org.springframework.stereotype.Component;
+ 
 -import java.util.Enumeration;
+ import java.util.HashMap;
+ import java.util.Map;
+ 
++import javax.annotation.PostConstruct;
++import javax.inject.Inject;
++
++@Component
+ public class UsageEventUtils {
+ 
 -    private static UsageEventDao _usageEventDao = ComponentLocator.getLocator(ManagementServer.Name).getDao(UsageEventDao.class);
 -    private static AccountDao _accountDao = ComponentLocator.getLocator(ManagementServer.Name).getDao(AccountDao.class);
 -    private static DataCenterDao _dcDao =  ComponentLocator.getLocator(ManagementServer.Name).getDao(DataCenterDao.class);
++    private static UsageEventDao _usageEventDao;
++    private static AccountDao _accountDao;
++    private static DataCenterDao _dcDao;
+     private static final Logger s_logger = Logger.getLogger(UsageEventUtils.class);
+ 
+     // get the event bus provider if configured
 -    protected static EventBus _eventBus = null;
 -    static {
 -        Adapters<EventBus> eventBusImpls = ComponentLocator.getLocator(ManagementServer.Name).getAdapters(EventBus.class);
 -        if (eventBusImpls != null) {
 -            Enumeration<EventBus> eventBusenum = eventBusImpls.enumeration();
 -            if (eventBusenum != null && eventBusenum.hasMoreElements()) {
 -                _eventBus = eventBusenum.nextElement(); // configure event bus if configured
 -            }
 -        }
 -    }
++    protected static EventBus _eventBus;
+ 
++    @Inject UsageEventDao usageEventDao;
++    @Inject AccountDao accountDao;
++    @Inject DataCenterDao dcDao;
++    
++    public UsageEventUtils() {
++    }
++    
++    @PostConstruct
++    void init() {
++    	_usageEventDao = usageEventDao;
++    	_accountDao = accountDao;
++    	_dcDao = dcDao;
++    }
++    
+     public static void publishUsageEvent(String usageType, long accountId, long zoneId,
+                                          long resourceId, String resourceName,
+                                          Long offeringId, Long templateId, Long size,
+                                          String entityType, String entityUUID) {
+         saveUsageEvent(usageType, accountId, zoneId, resourceId, resourceName, offeringId, templateId, size);
+         publishUsageEvent(usageType, accountId, zoneId, entityType, entityUUID);
+     }
+ 
+     public static void publishUsageEvent(String usageType, long accountId, long zoneId, long resourceId,
+                                          String resourceName, String entityType, String entityUUID) {
+         saveUsageEvent(usageType, accountId, zoneId, resourceId, resourceName);
+         publishUsageEvent(usageType, accountId, zoneId, entityType, entityUUID);
+     }
+ 
+     public static void publishUsageEvent(String usageType, long accountId, long zoneId,
+                                          long ipAddressId, String ipAddress, boolean isSourceNat,
+                                          String guestType, boolean isSystem, String entityType, String entityUUID) {
+         saveUsageEvent(usageType, accountId, zoneId, ipAddressId, ipAddress, isSourceNat, guestType, isSystem);
+         publishUsageEvent(usageType, accountId, zoneId, entityType, entityUUID);
+     }
+ 
+     public static void publishUsageEvent(String usageType, long accountId, long zoneId, long resourceId,
+                                          String resourceName, Long offeringId, Long templateId, String resourceType,
+                                          String entityType, String entityUUID) {
+         saveUsageEvent(usageType, accountId, zoneId, resourceId, resourceName, offeringId, templateId, resourceType);
+         publishUsageEvent(usageType, accountId, zoneId, entityType, entityUUID);
+     }
+ 
+     public static void publishUsageEvent(String usageType, long accountId,long zoneId, long vmId,
+                                          long securityGroupId, String entityType, String entityUUID) {
+         saveUsageEvent(usageType, accountId, zoneId, vmId, securityGroupId);
+         publishUsageEvent(usageType, accountId, zoneId, entityType, entityUUID);
+     }
+ 
+     public static void saveUsageEvent(String usageType, long accountId, long zoneId, long resourceId, String resourceName, Long offeringId, Long templateId, Long size) {
+         _usageEventDao.persist( new UsageEventVO(usageType, accountId, zoneId, resourceId, resourceName, offeringId, templateId, size));
+     }
+ 
+     public static void saveUsageEvent(String usageType, long accountId, long zoneId, long resourceId, String resourceName) {
+         _usageEventDao.persist( new UsageEventVO(usageType, accountId, zoneId, resourceId, resourceName));
+     }
+ 
+     public static void saveUsageEvent(String usageType, long accountId, long zoneId, long ipAddressId, String ipAddress, boolean isSourceNat, String guestType, boolean isSystem) {
+         _usageEventDao.persist( new UsageEventVO(usageType, accountId, zoneId, ipAddressId, ipAddress, isSourceNat, guestType, isSystem));
+     }
+ 
+     public static void saveUsageEvent(String usageType, long accountId, long zoneId, long resourceId, String resourceName, Long offeringId, Long templateId, String resourceType) {
+         _usageEventDao.persist( new UsageEventVO(usageType, accountId, zoneId, resourceId, resourceName, offeringId, templateId, resourceType));
+     }
+ 
+     public static void saveUsageEvent(String usageType, long accountId,long zoneId, long vmId, long securityGroupId) {
+         _usageEventDao.persist( new UsageEventVO( usageType, accountId, zoneId, vmId, securityGroupId));
+     }
+ 
+     private static void publishUsageEvent(String usageEventType, Long accountId, Long zoneId, String resourceType, String resourceUUID) {
+ 
+         if (_eventBus == null) {
+             return; // no provider is configured to provider events bus, so just return
+         }
+ 
+         Account account = _accountDao.findById(accountId);
+         DataCenterVO dc = _dcDao.findById(zoneId);
+ 
+         Event event = new Event(ManagementServer.Name, EventCategory.USAGE_EVENT.getName(), usageEventType,
+                 resourceType, resourceUUID);
+ 
+         Map<String, String> eventDescription = new HashMap<String, String>();
+         eventDescription.put("account", account.getUuid());
+         eventDescription.put("zone", dc.getUuid());
+         eventDescription.put("event", usageEventType);
+         eventDescription.put("resource", resourceType);
+         eventDescription.put("id", resourceUUID);
+         event.setDescription(eventDescription);
+ 
+         try {
+             _eventBus.publish(event);
+         } catch (EventBusException e) {
+             s_logger.warn("Failed to publish usage event on the the event bus.");
+         }
+     }
+ }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/7b75f0d9/server/src/com/cloud/network/NetworkManagerImpl.java
----------------------------------------------------------------------
diff --cc server/src/com/cloud/network/NetworkManagerImpl.java
index 643f1a4,218583b..68e100f
--- a/server/src/com/cloud/network/NetworkManagerImpl.java
+++ b/server/src/com/cloud/network/NetworkManagerImpl.java
@@@ -16,41 -16,9 +16,34 @@@
  // under the License.
  package com.cloud.network;
  
 +import java.net.URI;
 +import java.util.ArrayList;
 +import java.util.Arrays;
 +import java.util.Collections;
 +import java.util.Comparator;
 +import java.util.Date;
 +import java.util.HashMap;
 +import java.util.HashSet;
 +import java.util.List;
 +import java.util.Map;
 +import java.util.Random;
 +import java.util.Set;
 +import java.util.concurrent.Executors;
 +import java.util.concurrent.ScheduledExecutorService;
 +import java.util.concurrent.TimeUnit;
 +
 +import javax.ejb.Local;
 +import javax.inject.Inject;
 +import javax.naming.ConfigurationException;
 +
 +import org.apache.cloudstack.acl.ControlledEntity.ACLType;
 +import org.apache.cloudstack.acl.SecurityChecker.AccessType;
 +import org.apache.log4j.Logger;
 +import org.springframework.stereotype.Component;
 +
  import com.cloud.agent.AgentManager;
  import com.cloud.agent.Listener;
- import com.cloud.agent.api.AgentControlAnswer;
- import com.cloud.agent.api.AgentControlCommand;
- import com.cloud.agent.api.Answer;
- import com.cloud.agent.api.CheckNetworkAnswer;
- import com.cloud.agent.api.CheckNetworkCommand;
- import com.cloud.agent.api.Command;
- import com.cloud.agent.api.StartupCommand;
- import com.cloud.agent.api.StartupRoutingCommand;
+ import com.cloud.agent.api.*;
  import com.cloud.agent.api.to.NicTO;
  import com.cloud.alert.AlertManager;
  import com.cloud.api.ApiDBUtils;
@@@ -161,31 -79,20 +124,19 @@@ import com.cloud.user.*
  import com.cloud.user.dao.AccountDao;
  import com.cloud.utils.NumbersUtil;
  import com.cloud.utils.Pair;
 -import com.cloud.utils.component.Adapters;
 -import com.cloud.utils.component.Inject;
 -import com.cloud.utils.component.Manager;
 +import com.cloud.utils.component.AdapterBase;
- import com.cloud.utils.component.Manager;
 +import com.cloud.utils.component.ManagerBase;
  import com.cloud.utils.concurrency.NamedThreadFactory;
- import com.cloud.utils.db.DB;
- import com.cloud.utils.db.Filter;
+ import com.cloud.utils.db.*;
  import com.cloud.utils.db.JoinBuilder.JoinType;
- import com.cloud.utils.db.SearchBuilder;
- import com.cloud.utils.db.SearchCriteria;
  import com.cloud.utils.db.SearchCriteria.Op;
- import com.cloud.utils.db.Transaction;
  import com.cloud.utils.exception.CloudRuntimeException;
+ import com.cloud.utils.fsm.NoTransitionException;
+ import com.cloud.utils.fsm.StateMachine2;
  import com.cloud.utils.net.Ip;
  import com.cloud.utils.net.NetUtils;
- import com.cloud.vm.Nic;
- import com.cloud.vm.NicProfile;
- import com.cloud.vm.NicVO;
- import com.cloud.vm.ReservationContext;
- import com.cloud.vm.ReservationContextImpl;
- import com.cloud.vm.UserVmVO;
- import com.cloud.vm.VMInstanceVO;
- import com.cloud.vm.VirtualMachine;
+ import com.cloud.vm.*;
  import com.cloud.vm.VirtualMachine.Type;
- import com.cloud.vm.VirtualMachineProfile;
- import com.cloud.vm.VirtualMachineProfileImpl;
  import com.cloud.vm.dao.NicDao;
  import com.cloud.vm.dao.UserVmDao;
  import com.cloud.vm.dao.VMInstanceDao;
@@@ -419,11 -340,9 +374,9 @@@ public class NetworkManagerImpl extend
              VlanVO vlan = _vlanDao.findById(addr.getVlanId());
  
              String guestType = vlan.getVlanType().toString();
- 
-             UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_NET_IP_ASSIGN, owner.getId(), 
+             UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NET_IP_ASSIGN, owner.getId(),
 -                    addr.getDataCenterId(), addr.getId(), addr.getAddress().toString(), addr.isSourceNat(), guestType,
 +                    addr.getDataCenterId(), addr.getId(), addr.getAddress().toString(), addr.isSourceNat(), guestType, 
-                     addr.getSystem());
-             _usageEventDao.persist(usageEvent);
+                     addr.getSystem(), addr.getClass().getName(), addr.getUuid());
              // don't increment resource count for direct ip addresses
              if (addr.getAssociatedWithNetworkId() != null) {
                  _resourceLimitMgr.incrementResourceCount(owner.getId(), ResourceType.public_ip);
@@@ -2079,10 -2014,13 +2040,13 @@@
          if (network.getState() != Network.State.Implemented && network.getState() != Network.State.Shutdown) {
              s_logger.debug("Network is not implemented: " + network);
              return false;
 -        }
 +        } 
- 
+         try {
+             stateTransitTo(network, Event.DestroyNetwork);
+         } catch (NoTransitionException e) {
 -            network.setState(Network.State.Shutdown);
 -            _networksDao.update(network.getId(), network);
 +        network.setState(Network.State.Shutdown);
 +        _networksDao.update(network.getId(), network);
+         }
  
          boolean success = shutdownNetworkElementsAndResources(context, cleanupElements, network);
  
@@@ -2097,15 -2035,22 +2061,22 @@@
              guru.shutdown(profile, _networkOfferingDao.findById(network.getNetworkOfferingId()));
  
              applyProfileToNetwork(network, profile);
- 
+             try {
+                 stateTransitTo(network, Event.OperationSucceeded);
+             } catch (NoTransitionException e) {
 -                network.setState(Network.State.Allocated);
 -                network.setRestartRequired(false);
 +            network.setState(Network.State.Allocated);
 +            network.setRestartRequired(false);
+             }
              _networksDao.update(network.getId(), network);
              _networksDao.clearCheckForGc(networkId);
              result = true;
          } else {
+             try {
+                 stateTransitTo(network, Event.OperationFailed);
+             } catch (NoTransitionException e) {
 -                network.setState(Network.State.Implemented);
 -                _networksDao.update(network.getId(), network);
 +            network.setState(Network.State.Implemented);
 +            _networksDao.update(network.getId(), network);
+             }
              result = false;
          }
          txn.commit();
@@@ -2772,10 -2720,9 +2746,9 @@@
  
                  String guestType = vlan.getVlanType().toString();
  
-                 UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_NET_IP_RELEASE,
+                 UsageEventUtils.publishUsageEvent(EventTypes.EVENT_NET_IP_RELEASE,
 -                        ip.getAllocatedToAccountId(), ip.getDataCenterId(), addrId, ip.getAddress().addr(),
 +                        ip.getAllocatedToAccountId(), ip.getDataCenterId(), addrId, ip.getAddress().addr(), 
-                         ip.isSourceNat(), guestType, ip.getSystem());
-                 _usageEventDao.persist(usageEvent);
+                         ip.isSourceNat(), guestType, ip.getSystem(), ip.getClass().getName(), ip.getUuid());
              }
  
              ip = _ipAddressDao.markAsUnavailable(addrId);