http://git-wip-us.apache.org/repos/asf/ambari/blob/565c2ea2/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/AlertGroupEventCreator.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/AlertGroupEventCreator.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/AlertGroupEventCreator.java
new file mode 100644
index 0000000..8ef5052
--- /dev/null
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/AlertGroupEventCreator.java
@@ -0,0 +1,170 @@
+/*
+ * 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.ambari.server.audit.request.eventcreator;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.ambari.server.api.services.Request;
+import org.apache.ambari.server.api.services.Result;
+import org.apache.ambari.server.api.services.ResultStatus;
+import org.apache.ambari.server.audit.event.AuditEvent;
+import 
org.apache.ambari.server.audit.event.request.AddAlertGroupRequestAuditEvent;
+import 
org.apache.ambari.server.audit.event.request.ChangeAlertGroupRequestAuditEvent;
+import 
org.apache.ambari.server.audit.event.request.DeleteAlertGroupRequestAuditEvent;
+import org.apache.ambari.server.audit.request.RequestAuditEventCreator;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.joda.time.DateTime;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.User;
+
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * This creator handles alert group requests
+ * For resource type {@link Resource.Type#AlertGroup}
+ * and request types {@link Request.Type#POST}, {@link Request.Type#PUT} and 
{@link Request.Type#DELETE}
+ */
+public class AlertGroupEventCreator implements RequestAuditEventCreator {
+
+  /**
+   * Set of {@link Request.Type}s that are handled by this plugin
+   */
+  private Set<Request.Type> requestTypes = 
ImmutableSet.<Request.Type>builder().add(Request.Type.PUT, Request.Type.POST, 
Request.Type.DELETE).build();
+
+  /**
+   * Set of {@link Resource.Type}s that are handled by this plugin
+   */
+  private Set<Resource.Type> resourceTypes = 
ImmutableSet.<Resource.Type>builder().add(Resource.Type.AlertGroup).build();
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public Set<Request.Type> getRequestTypes() {
+    return requestTypes;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public Set<Resource.Type> getResourceTypes() {
+    return resourceTypes;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public Set<ResultStatus.STATUS> getResultStatuses() {
+    return null;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public AuditEvent createAuditEvent(Request request, Result result) {
+    String username = ((User) 
SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUsername();
+
+    switch (request.getRequestType()) {
+      case POST:
+        return AddAlertGroupRequestAuditEvent.builder()
+          .withTimestamp(DateTime.now())
+          .withRequestType(request.getRequestType())
+          .withResultStatus(result.getStatus())
+          .withUrl(request.getURI())
+          .withRemoteIp(request.getRemoteAddress())
+          .withUserName(username)
+          .withName(getName(request))
+          .withDefinitionIds(getDefinitionIds(request))
+          .withNotificationIds(getNotificationIds(request))
+          .build();
+      case PUT:
+        return ChangeAlertGroupRequestAuditEvent.builder()
+          .withTimestamp(DateTime.now())
+          .withRequestType(request.getRequestType())
+          .withResultStatus(result.getStatus())
+          .withUrl(request.getURI())
+          .withRemoteIp(request.getRemoteAddress())
+          .withUserName(username)
+          .withName(getName(request))
+          .withDefinitionIds(getDefinitionIds(request))
+          .withNotificationIds(getNotificationIds(request))
+          .build();
+      case DELETE:
+        return DeleteAlertGroupRequestAuditEvent.builder()
+          .withTimestamp(DateTime.now())
+          .withRequestType(request.getRequestType())
+          .withResultStatus(result.getStatus())
+          .withUrl(request.getURI())
+          .withRemoteIp(request.getRemoteAddress())
+          .withUserName(username)
+          
.withId(request.getResource().getKeyValueMap().get(Resource.Type.AlertGroup))
+          .build();
+      default:
+        return null;
+    }
+  }
+
+  /**
+   * Returns the alert group name from the request
+   * @param request
+   * @return
+   */
+  private String getName(Request request) {
+    if (!request.getBody().getNamedPropertySets().isEmpty()) {
+      return 
String.valueOf(request.getBody().getNamedPropertySets().iterator().next().getProperties().get(PropertyHelper.getPropertyId("AlertGroup",
 "name")));
+    }
+    return null;
+  }
+
+  /**
+   * Returns definition ids from the request
+   * @param request
+   * @return
+   */
+  private List<String> getDefinitionIds(Request request) {
+    if (!request.getBody().getNamedPropertySets().isEmpty()) {
+      List<String> list = (List<String>) 
request.getBody().getNamedPropertySets().iterator().next().getProperties().get(PropertyHelper.getPropertyId("AlertGroup",
 "definitions"));
+      if (list != null) {
+        return list;
+      }
+    }
+    return Collections.emptyList();
+  }
+
+  /**
+   * Returns notification ids from the request
+   * @param request
+   * @return
+   */
+  private List<String> getNotificationIds(Request request) {
+    if (!request.getBody().getNamedPropertySets().isEmpty()) {
+      List<String> list = (List<String>) 
request.getBody().getNamedPropertySets().iterator().next().getProperties().get(PropertyHelper.getPropertyId("AlertGroup",
 "targets"));
+      if (list != null) {
+        return list;
+      }
+    }
+    return Collections.emptyList();
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/565c2ea2/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/AlertTargetEventCreator.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/AlertTargetEventCreator.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/AlertTargetEventCreator.java
new file mode 100644
index 0000000..a5ba525
--- /dev/null
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/AlertTargetEventCreator.java
@@ -0,0 +1,165 @@
+/*
+ * 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.ambari.server.audit.request.eventcreator;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.ambari.server.api.services.Request;
+import org.apache.ambari.server.api.services.Result;
+import org.apache.ambari.server.api.services.ResultStatus;
+import org.apache.ambari.server.audit.event.AuditEvent;
+import 
org.apache.ambari.server.audit.event.request.AddAlertTargetRequestAuditEvent;
+import 
org.apache.ambari.server.audit.event.request.ChangeAlertTargetRequestAuditEvent;
+import 
org.apache.ambari.server.audit.event.request.DeleteAlertTargetRequestAuditEvent;
+import org.apache.ambari.server.audit.request.RequestAuditEventCreator;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.joda.time.DateTime;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.User;
+
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * This creator handles alert target requests
+ * For resource type {@link Resource.Type#AlertTarget}
+ * and request types {@link Request.Type#POST}, {@link Request.Type#PUT} and 
{@link Request.Type#DELETE}
+ */
+public class AlertTargetEventCreator implements RequestAuditEventCreator {
+
+  /**
+   * Set of {@link Request.Type}s that are handled by this plugin
+   */
+  private Set<Request.Type> requestTypes = 
ImmutableSet.<Request.Type>builder().add(Request.Type.PUT, Request.Type.POST, 
Request.Type.DELETE).build();
+
+  /**
+   * Set of {@link Resource.Type}s that are handled by this plugin
+   */
+  private Set<Resource.Type> resourceTypes = 
ImmutableSet.<Resource.Type>builder().add(Resource.Type.AlertTarget).build();
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public Set<Request.Type> getRequestTypes() {
+    return requestTypes;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public Set<Resource.Type> getResourceTypes() {
+    return resourceTypes;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public Set<ResultStatus.STATUS> getResultStatuses() {
+    return null;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public AuditEvent createAuditEvent(Request request, Result result) {
+    String username = ((User) 
SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUsername();
+
+    switch (request.getRequestType()) {
+      case POST:
+        return AddAlertTargetRequestAuditEvent.builder()
+          .withTimestamp(DateTime.now())
+          .withRequestType(request.getRequestType())
+          .withResultStatus(result.getStatus())
+          .withUrl(request.getURI())
+          .withRemoteIp(request.getRemoteAddress())
+          .withUserName(username)
+          .withName(getProperty(request, "name"))
+          .withDescription(getProperty(request, "description"))
+          .withAlertStates(getPropertyList(request, "alert_states"))
+          .withGroupIds(getPropertyList(request, "groups"))
+          .withNotificationType(getProperty(request, "notification_type"))
+          .withEmailFrom(getProperty(request, "properties/mail.smtp.from"))
+          .withEmailRecipients(getPropertyList(request, 
"properties/ambari.dispatch.recipients"))
+          .build();
+      case PUT:
+        return ChangeAlertTargetRequestAuditEvent.builder()
+          .withTimestamp(DateTime.now())
+          .withRequestType(request.getRequestType())
+          .withResultStatus(result.getStatus())
+          .withUrl(request.getURI())
+          .withRemoteIp(request.getRemoteAddress())
+          .withUserName(username)
+          .withName(getProperty(request, "name"))
+          .withDescription(getProperty(request, "description"))
+          .withAlertStates(getPropertyList(request, "alert_states"))
+          .withGroupIds(getPropertyList(request, "groups"))
+          .withNotificationType(getProperty(request, "notification_type"))
+          .withEmailFrom(getProperty(request, "properties/mail.smtp.from"))
+          .withEmailRecipients(getPropertyList(request, 
"properties/ambari.dispatch.recipients"))
+          .build();
+      case DELETE:
+        return DeleteAlertTargetRequestAuditEvent.builder()
+          .withTimestamp(DateTime.now())
+          .withRequestType(request.getRequestType())
+          .withResultStatus(result.getStatus())
+          .withUrl(request.getURI())
+          .withRemoteIp(request.getRemoteAddress())
+          .withUserName(username)
+          
.withId(request.getResource().getKeyValueMap().get(Resource.Type.AlertTarget))
+          .build();
+      default:
+        return null;
+    }
+  }
+
+  /**
+   * Returns a property list from the request, named by the parameter 
propertyName
+   * @param request
+   * @param propertyName
+   * @return
+   */
+  private List<String> getPropertyList(Request request, String propertyName) {
+    if (!request.getBody().getNamedPropertySets().isEmpty()) {
+      List<String> list = (List<String>) 
request.getBody().getNamedPropertySets().iterator().next().getProperties().get(PropertyHelper.getPropertyId("AlertTarget",
 propertyName));
+      if (list != null) {
+        return list;
+      }
+    }
+    return Collections.emptyList();
+  }
+
+  /**
+   * Returns a property from the request, named by the parameter propertyName
+   * @param request
+   * @param propertyName
+   * @return
+   */
+  private String getProperty(Request request, String propertyName) {
+    if (!request.getBody().getPropertySets().isEmpty()) {
+      return 
String.valueOf(request.getBody().getPropertySets().iterator().next().get(PropertyHelper.getPropertyId("AlertTarget",
 propertyName)));
+    }
+    return null;
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/565c2ea2/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/BlueprintEventCreator.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/BlueprintEventCreator.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/BlueprintEventCreator.java
new file mode 100644
index 0000000..94a8950
--- /dev/null
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/BlueprintEventCreator.java
@@ -0,0 +1,110 @@
+/*
+ * 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.ambari.server.audit.request.eventcreator;
+
+import java.util.Set;
+
+import org.apache.ambari.server.api.services.Request;
+import org.apache.ambari.server.api.services.Result;
+import org.apache.ambari.server.api.services.ResultStatus;
+import org.apache.ambari.server.audit.event.AuditEvent;
+import 
org.apache.ambari.server.audit.event.request.AddBlueprintRequestAuditEvent;
+import 
org.apache.ambari.server.audit.event.request.DeleteBlueprintRequestAuditEvent;
+import org.apache.ambari.server.audit.request.RequestAuditEventCreator;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.joda.time.DateTime;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.User;
+
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * This creator handles blueprint add and remove requests
+ * For resource type {@link Resource.Type#Blueprint}
+ * and request types {@link Request.Type#POST} and {@link Request.Type#POST}
+ */
+public class BlueprintEventCreator implements RequestAuditEventCreator {
+
+  /**
+   * Set of {@link Request.Type}s that are handled by this plugin
+   */
+  private Set<Request.Type> requestTypes = 
ImmutableSet.<Request.Type>builder().add(Request.Type.POST, 
Request.Type.DELETE).build();
+
+  /**
+   * Set of {@link Resource.Type}s that are handled by this plugin
+   */
+  private Set<Resource.Type> resourceTypes = 
ImmutableSet.<Resource.Type>builder().add(Resource.Type.Blueprint).build();
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public Set<Request.Type> getRequestTypes() {
+    return requestTypes;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public Set<Resource.Type> getResourceTypes() {
+    return resourceTypes;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public Set<ResultStatus.STATUS> getResultStatuses() {
+    return null;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public AuditEvent createAuditEvent(Request request, Result result) {
+    String username = ((User) 
SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUsername();
+
+    switch (request.getRequestType()) {
+      case POST:
+        return AddBlueprintRequestAuditEvent.builder()
+          .withTimestamp(DateTime.now())
+          .withRequestType(request.getRequestType())
+          .withResultStatus(result.getStatus())
+          .withUrl(request.getURI())
+          .withRemoteIp(request.getRemoteAddress())
+          .withUserName(username)
+          
.withBlueprintName(request.getResource().getKeyValueMap().get(Resource.Type.Blueprint))
+          .build();
+      case DELETE:
+        return DeleteBlueprintRequestAuditEvent.builder()
+          .withTimestamp(DateTime.now())
+          .withRequestType(request.getRequestType())
+          .withResultStatus(result.getStatus())
+          .withUrl(request.getURI())
+          .withRemoteIp(request.getRemoteAddress())
+          .withUserName(username)
+          
.withBlueprintName(request.getResource().getKeyValueMap().get(Resource.Type.Blueprint))
+          .build();
+      default:
+        return null;
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/565c2ea2/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/BlueprintExportEventCreator.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/BlueprintExportEventCreator.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/BlueprintExportEventCreator.java
new file mode 100644
index 0000000..5a26998
--- /dev/null
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/BlueprintExportEventCreator.java
@@ -0,0 +1,95 @@
+/*
+ * 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.ambari.server.audit.request.eventcreator;
+
+import java.util.Set;
+
+import org.apache.ambari.server.api.services.Request;
+import org.apache.ambari.server.api.services.Result;
+import org.apache.ambari.server.api.services.ResultStatus;
+import org.apache.ambari.server.audit.event.AuditEvent;
+import 
org.apache.ambari.server.audit.event.request.BlueprintExportRequestAuditEvent;
+import org.apache.ambari.server.audit.request.RequestAuditEventCreator;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.joda.time.DateTime;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.User;
+
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * This creator handles blueprint export requests
+ * For resource type {@link Resource.Type#Cluster}
+ * and request types {@link Request.Type#GET}
+ */
+public class BlueprintExportEventCreator implements RequestAuditEventCreator {
+
+  /**
+   * Set of {@link Request.Type}s that are handled by this plugin
+   */
+  private Set<Request.Type> requestTypes = 
ImmutableSet.<Request.Type>builder().add(Request.Type.GET).build();
+
+  /**
+   * Set of {@link Resource.Type}s that are handled by this plugin
+   */
+  private Set<Resource.Type> resourceTypes = 
ImmutableSet.<Resource.Type>builder().add(Resource.Type.Cluster).build();
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public Set<Request.Type> getRequestTypes() {
+    return requestTypes;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public Set<Resource.Type> getResourceTypes() {
+    return resourceTypes;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public Set<ResultStatus.STATUS> getResultStatuses() {
+    return null;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public AuditEvent createAuditEvent(Request request, Result result) {
+    String username = ((User) 
SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUsername();
+    if (!request.getURI().contains("format=blueprint")) {
+      return null;
+    }
+    return BlueprintExportRequestAuditEvent.builder()
+      .withTimestamp(DateTime.now())
+      .withRequestType(request.getRequestType())
+      .withResultStatus(result.getStatus())
+      .withUrl(request.getURI())
+      .withRemoteIp(request.getRemoteAddress())
+      .withUserName(username)
+      .build();
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/565c2ea2/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/ComponentEventCreator.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/ComponentEventCreator.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/ComponentEventCreator.java
new file mode 100644
index 0000000..0fc0041
--- /dev/null
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/ComponentEventCreator.java
@@ -0,0 +1,189 @@
+/*
+ * 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.ambari.server.audit.request.eventcreator;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.ambari.server.api.services.Request;
+import org.apache.ambari.server.api.services.Result;
+import org.apache.ambari.server.api.services.ResultStatus;
+import org.apache.ambari.server.audit.event.AuditEvent;
+import 
org.apache.ambari.server.audit.event.request.StartOperationRequestAuditEvent;
+import org.apache.ambari.server.audit.request.RequestAuditEventCreator;
+import org.apache.ambari.server.controller.internal.RequestOperationLevel;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.joda.time.DateTime;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.User;
+
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * This creator handles operation requests (start, stop, install, etc)
+ * For resource type {@link 
org.apache.ambari.server.controller.spi.Resource.Type#HostComponent}
+ * and request types {@link 
org.apache.ambari.server.api.services.Request.Type#POST}, {@link 
org.apache.ambari.server.api.services.Request.Type#PUT} and {@link 
org.apache.ambari.server.api.services.Request.Type#DELETE}
+ */
+public class ComponentEventCreator implements RequestAuditEventCreator {
+
+  /**
+   * Set of {@link Request.Type}s that are handled by this plugin
+   */
+  private Set<Request.Type> requestTypes = 
ImmutableSet.<Request.Type>builder().add(Request.Type.PUT, Request.Type.POST, 
Request.Type.DELETE).build();
+
+  /**
+   * Set of {@link Resource.Type}s that are handled by this plugin
+   */
+  private Set<Resource.Type> resourceTypes = 
ImmutableSet.<Resource.Type>builder().add(Resource.Type.HostComponent).build();
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public Set<Request.Type> getRequestTypes() {
+    return requestTypes;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public Set<Resource.Type> getResourceTypes() {
+    return resourceTypes;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public Set<ResultStatus.STATUS> getResultStatuses() {
+    // null makes this default
+    return null;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public AuditEvent createAuditEvent(Request request, Result result) {
+    String username = ((User) 
SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUsername();
+
+    String operation = getOperation(request);
+
+    Long requestId = null;
+    if (containsRequestId(result)) {
+      requestId = getRequestId(result);
+    }
+
+    StartOperationRequestAuditEvent.StartOperationAuditEventBuilder 
auditEventBuilder = StartOperationRequestAuditEvent.builder()
+      .withOperation(operation)
+      .withUserName(username)
+      .withRemoteIp(request.getRemoteAddress())
+      .withTimestamp(DateTime.now())
+      .withRequestId(String.valueOf(requestId));
+
+    if (result.getStatus().isErrorState()) {
+      auditEventBuilder.withReasonOfFailure(result.getStatus().getMessage());
+    }
+
+    return auditEventBuilder.build();
+  }
+
+  /**
+   * Generates operation name based on the request. It checks the operation 
level, the host name, the service name, the status
+   * and whether this is a maintenance mode switch change.
+   * @param request
+   * @return
+   */
+  private String getOperation(Request request) {
+    if (request.getRequestType() == Request.Type.DELETE) {
+      return "Delete component " + 
request.getResource().getKeyValueMap().get(Resource.Type.HostComponent);
+    }
+
+    if 
(request.getBody().getRequestInfoProperties().containsKey(RequestOperationLevel.OPERATION_LEVEL_ID))
 {
+      String operation = "";
+      switch 
(request.getBody().getRequestInfoProperties().get(RequestOperationLevel.OPERATION_LEVEL_ID))
 {
+        case "CLUSTER":
+          for (Map<String, Object> map : request.getBody().getPropertySets()) {
+            if (map.containsKey(PropertyHelper.getPropertyId("HostRoles", 
"cluster_name"))) {
+              operation = 
String.valueOf(map.get(PropertyHelper.getPropertyId("HostRoles", "state"))) + 
": all services"
+                + " on all hosts"
+                + (request.getBody().getQueryString().length() > 0 ? " that 
matches " + request.getBody().getQueryString() : "")
+                + " (" + 
request.getBody().getRequestInfoProperties().get(RequestOperationLevel.OPERATION_CLUSTER_ID)
 + ")";
+              break;
+            }
+          }
+          break;
+        case "HOST":
+          for (Map<String, Object> map : request.getBody().getPropertySets()) {
+            if (map.containsKey(PropertyHelper.getPropertyId("HostRoles", 
"cluster_name"))) {
+              String query = 
request.getBody().getRequestInfoProperties().get("query");
+              operation = 
String.valueOf(map.get(PropertyHelper.getPropertyId("HostRoles", "state"))) + 
": " + query.substring(query.indexOf("(") + 1, query.length() - 1)
+                + " on " + 
request.getBody().getRequestInfoProperties().get("operation_level/host_names")
+                + " (" + 
request.getBody().getRequestInfoProperties().get(RequestOperationLevel.OPERATION_CLUSTER_ID)
 + ")";
+              break;
+            }
+          }
+          break;
+        case "HOST_COMPONENT":
+          for (Map<String, Object> map : request.getBody().getPropertySets()) {
+            if (map.containsKey(PropertyHelper.getPropertyId("HostRoles", 
"component_name"))) {
+              operation = 
String.valueOf(map.get(PropertyHelper.getPropertyId("HostRoles", "state"))) + 
": " + String.valueOf(map.get(PropertyHelper.getPropertyId("HostRoles", 
"component_name")))
+                + "/" + 
request.getBody().getRequestInfoProperties().get(RequestOperationLevel.OPERATION_SERVICE_ID)
+                + " on " + 
request.getBody().getRequestInfoProperties().get("operation_level/host_name")
+                + " (" + 
request.getBody().getRequestInfoProperties().get(RequestOperationLevel.OPERATION_CLUSTER_ID)
 + ")";
+              break;
+            }
+          }
+          break;
+      }
+      return operation;
+    }
+
+    for (Map<String, Object> map : request.getBody().getPropertySets()) {
+      if (map.containsKey(PropertyHelper.getPropertyId("HostRoles", 
"maintenance_state"))) {
+        return "Turn " + map.get(PropertyHelper.getPropertyId("HostRoles", 
"maintenance_state")) + " Maintenance Mode for " + 
map.get(PropertyHelper.getPropertyId("HostRoles", "component_name"));
+      }
+    }
+
+    return null;
+  }
+
+  /**
+   * Returns request id from the result
+   * @param result
+   * @return
+   */
+  private Long getRequestId(Result result) {
+    return (Long) 
result.getResultTree().getChild("request").getObject().getPropertiesMap().get("Requests").get("id");
+  }
+
+  /**
+   * Checks if request id can be found in the result
+   * @param result
+   * @return
+   */
+  private boolean containsRequestId(Result result) {
+    return result.getResultTree().getChild("request") != null
+      && result.getResultTree().getChild("request").getObject() != null
+      && 
result.getResultTree().getChild("request").getObject().getPropertiesMap().get("Requests")
 != null
+      && 
result.getResultTree().getChild("request").getObject().getPropertiesMap().get("Requests").get("id")
 != null;
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/565c2ea2/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/ConfigurationChangeEventCreator.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/ConfigurationChangeEventCreator.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/ConfigurationChangeEventCreator.java
new file mode 100644
index 0000000..2f9a80f
--- /dev/null
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/ConfigurationChangeEventCreator.java
@@ -0,0 +1,151 @@
+/*
+ * 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.ambari.server.audit.request.eventcreator;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.ambari.server.api.services.Request;
+import org.apache.ambari.server.api.services.Result;
+import org.apache.ambari.server.api.services.ResultStatus;
+import org.apache.ambari.server.audit.event.AuditEvent;
+import 
org.apache.ambari.server.audit.event.request.ClusterNameChangeRequestAuditEvent;
+import 
org.apache.ambari.server.audit.event.request.ConfigurationChangeRequestAuditEvent;
+import org.apache.ambari.server.audit.request.RequestAuditEventCreator;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.joda.time.DateTime;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.User;
+
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * This creator handles operation requests (start, stop, install, etc)
+ * For resource type {@link Resource.Type#HostComponent}
+ * and request types {@link Request.Type#POST}, {@link Request.Type#PUT} and 
{@link Request.Type#DELETE}
+ */
+public class ConfigurationChangeEventCreator implements 
RequestAuditEventCreator {
+
+  /**
+   * Set of {@link Request.Type}s that are handled by this plugin
+   */
+  private Set<Request.Type> requestTypes = 
ImmutableSet.<Request.Type>builder().add(Request.Type.PUT, Request.Type.POST, 
Request.Type.DELETE).build();
+
+  /**
+   * Set of {@link Resource.Type}s that are handled by this plugin
+   */
+  private Set<Resource.Type> resourceTypes = 
ImmutableSet.<Resource.Type>builder().add(Resource.Type.Cluster).build();
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public Set<Request.Type> getRequestTypes() {
+    return requestTypes;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public Set<Resource.Type> getResourceTypes() {
+    return resourceTypes;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public Set<ResultStatus.STATUS> getResultStatuses() {
+    return null;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public AuditEvent createAuditEvent(Request request, Result result) {
+    String username = ((User) 
SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUsername();
+
+    if (!request.getBody().getPropertySets().isEmpty()) {
+      Map<String, Object> map = 
request.getBody().getPropertySets().iterator().next();
+      if (map.size() == 1 && 
map.containsKey(PropertyHelper.getPropertyId("Clusters", "cluster_name"))) {
+        String newName = 
String.valueOf(map.get(PropertyHelper.getPropertyId("Clusters", 
"cluster_name")));
+        String oldName = 
request.getResource().getKeyValueMap().get(Resource.Type.Cluster);
+        return ClusterNameChangeRequestAuditEvent.builder()
+          .withTimestamp(DateTime.now())
+          .withRequestType(request.getRequestType())
+          .withResultStatus(result.getStatus())
+          .withUrl(request.getURI())
+          .withRemoteIp(request.getRemoteAddress())
+          .withUserName(username)
+          .withOldName(oldName)
+          .withNewName(newName)
+          .build();
+      }
+    }
+
+    return ConfigurationChangeRequestAuditEvent.builder()
+      .withTimestamp(DateTime.now())
+      .withRequestType(request.getRequestType())
+      .withResultStatus(result.getStatus())
+      .withUrl(request.getURI())
+      .withRemoteIp(request.getRemoteAddress())
+      .withUserName(username)
+      .withVersionNote(getServiceConfigVersionNote(result))
+      .withVersionNumber(getServiceConfigVersion(result))
+      .build();
+  }
+
+  /**
+   * Returns service configuration version from the result
+   * @param result
+   * @return
+   */
+  private String getServiceConfigVersion(Result result) {
+    Map<String, Object> map = getServiceConfigMap(result);
+    return map == null ? null : 
String.valueOf(map.get("service_config_version"));
+  }
+
+  /**
+   * Returns service configurationv ersion note from the result
+   * @param result
+   * @return
+   */
+  private String getServiceConfigVersionNote(Result result) {
+    Map<String, Object> map = getServiceConfigMap(result);
+    return map == null ? null : 
String.valueOf(map.get("service_config_version_note"));
+  }
+
+  /**
+   * Returns service configuration map from the result. This map contains 
version number and version info
+   * @param result
+   * @return
+   */
+  private Map<String, Object> getServiceConfigMap(Result result) {
+    if (result.getResultTree().getChild("resources") != null &&
+      !result.getResultTree().getChild("resources").getChildren().isEmpty() &&
+      
result.getResultTree().getChild("resources").getChildren().iterator().next().getObject()
 != null) {
+      return 
result.getResultTree().getChild("resources").getChildren().iterator().next().getObject().getPropertiesMap().get("");
+    }
+    return null;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/565c2ea2/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/CredentialEventCreator.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/CredentialEventCreator.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/CredentialEventCreator.java
new file mode 100644
index 0000000..fc46db4
--- /dev/null
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/CredentialEventCreator.java
@@ -0,0 +1,112 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.audit.request.eventcreator;
+
+import java.util.Set;
+
+import org.apache.ambari.server.api.services.Request;
+import org.apache.ambari.server.api.services.Result;
+import org.apache.ambari.server.api.services.ResultStatus;
+import org.apache.ambari.server.audit.event.AuditEvent;
+import 
org.apache.ambari.server.audit.event.request.AddCredentialRequestAuditEvent;
+import org.apache.ambari.server.audit.request.RequestAuditEventCreator;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.joda.time.DateTime;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.User;
+
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * This creator handles crednetial requests
+ * For resource type {@link Resource.Type#Upgrade}
+ * and request types {@link Request.Type#POST}
+ */
+public class CredentialEventCreator implements RequestAuditEventCreator {
+
+  /**
+   * Set of {@link Request.Type}s that are handled by this plugin
+   */
+  private Set<Request.Type> requestTypes = 
ImmutableSet.<Request.Type>builder().add(Request.Type.POST).build();
+
+  /**
+   * Set of {@link Resource.Type}s that are handled by this plugin
+   */
+  private Set<Resource.Type> resourceTypes = 
ImmutableSet.<Resource.Type>builder().add(Resource.Type.Credential).build();
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public Set<Request.Type> getRequestTypes() {
+    return requestTypes;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public Set<Resource.Type> getResourceTypes() {
+    return resourceTypes;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public Set<ResultStatus.STATUS> getResultStatuses() {
+    return null;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public AuditEvent createAuditEvent(Request request, Result result) {
+    String username = ((User) 
SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUsername();
+
+    return AddCredentialRequestAuditEvent.builder()
+      .withTimestamp(DateTime.now())
+      .withRequestType(request.getRequestType())
+      .withResultStatus(result.getStatus())
+      .withUrl(request.getURI())
+      .withRemoteIp(request.getRemoteAddress())
+      .withUserName(username)
+      .withClusterName(getProperty(request, "cluster_name"))
+      .withType(getProperty(request, "type"))
+      .withAlias(getProperty(request, "alias"))
+      .withPrincipal(getProperty(request, "principal"))
+      .build();
+
+  }
+
+  /**
+   * Returns a property from the resquest
+   * @param request
+   * @param propertyName
+   * @return
+   */
+  private String getProperty(Request request, String propertyName) {
+    if (!request.getBody().getPropertySets().isEmpty()) {
+      return 
String.valueOf(request.getBody().getPropertySets().iterator().next().get(PropertyHelper.getPropertyId("Credential",
 propertyName)));
+    }
+    return null;
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/565c2ea2/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/DefaultEventCreator.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/DefaultEventCreator.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/DefaultEventCreator.java
new file mode 100644
index 0000000..da67cd7
--- /dev/null
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/DefaultEventCreator.java
@@ -0,0 +1,99 @@
+/**
+ * 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
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * 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.ambari.server.audit.request.eventcreator;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.ambari.server.api.services.Request;
+import org.apache.ambari.server.api.services.Result;
+import org.apache.ambari.server.api.services.ResultStatus;
+import org.apache.ambari.server.audit.event.AuditEvent;
+import org.apache.ambari.server.audit.request.RequestAuditEvent;
+import org.apache.ambari.server.audit.request.RequestAuditEventCreator;
+import org.apache.ambari.server.audit.request.RequestAuditLogger;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.joda.time.DateTime;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.User;
+
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * Default creator for {@link RequestAuditLogger}
+ */
+public class DefaultEventCreator implements RequestAuditEventCreator {
+
+  /**
+   * Set of {@link org.apache.ambari.server.api.services.Request.Type}s that 
are handled by this plugin
+   */
+  private Set<Request.Type> requestTypes;
+
+  {
+    Set<Request.Type> allowedTypes = new HashSet<Request.Type>();
+    allowedTypes.addAll(Arrays.asList(Request.Type.values()));
+    allowedTypes.remove(Request.Type.GET); // get is not handled by default
+
+    ImmutableSet.Builder<Request.Type> builder = ImmutableSet.builder();
+    requestTypes = builder.addAll(allowedTypes).build();
+
+  }
+
+  /** {@inheritDoc} */
+  @Override
+  public Set<Request.Type> getRequestTypes() {
+    return requestTypes;
+  }
+
+  /** {@inheritDoc} */
+  @Override
+  public Set<Resource.Type> getResourceTypes() {
+    // null makes this default
+    return null;
+  }
+
+  /** {@inheritDoc} */
+  @Override
+  public Set<ResultStatus.STATUS> getResultStatuses() {
+    // null makes this default
+    return null;
+  }
+
+  /**
+   * Creates a simple {@link AuditEvent} with the details of request and 
response
+   * @param request HTTP request object
+   * @param result HTTP result object
+   * @return
+   */
+  @Override
+  public AuditEvent createAuditEvent(final Request request, final Result 
result) {
+    String username = ((User) 
SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUsername();
+
+    return RequestAuditEvent.builder()
+      .withTimestamp(DateTime.now())
+      .withUserName(username)
+      .withRemoteIp(request.getRemoteAddress())
+      .withRequestType(request.getRequestType())
+      .withUrl(request.getURI())
+      .withResultStatus(result.getStatus())
+      .build();
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/565c2ea2/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/GroupEventCreator.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/GroupEventCreator.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/GroupEventCreator.java
new file mode 100644
index 0000000..85ea82e
--- /dev/null
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/GroupEventCreator.java
@@ -0,0 +1,125 @@
+/*
+ * 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.ambari.server.audit.request.eventcreator;
+
+import java.util.Set;
+
+import org.apache.ambari.server.api.services.Request;
+import org.apache.ambari.server.api.services.Result;
+import org.apache.ambari.server.api.services.ResultStatus;
+import org.apache.ambari.server.audit.event.AuditEvent;
+import 
org.apache.ambari.server.audit.event.request.CreateGroupRequestAuditEvent;
+import 
org.apache.ambari.server.audit.event.request.DeleteGroupRequestAuditEvent;
+import org.apache.ambari.server.audit.request.RequestAuditEventCreator;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.joda.time.DateTime;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.User;
+
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * This creator handles group requests
+ * For resource type {@link Resource.Type#Group}
+ * and request types {@link Request.Type#POST} and {@link Request.Type#DELETE}
+ */
+public class GroupEventCreator implements RequestAuditEventCreator {
+
+  /**
+   * Set of {@link Request.Type}s that are handled by this plugin
+   */
+  private Set<Request.Type> requestTypes = 
ImmutableSet.<Request.Type>builder().add(Request.Type.POST, 
Request.Type.DELETE).build();
+
+  /**
+   * Set of {@link Resource.Type}s that are handled by this plugin
+   */
+  private Set<Resource.Type> resourceTypes = 
ImmutableSet.<Resource.Type>builder().add(Resource.Type.Group).build();
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public Set<Request.Type> getRequestTypes() {
+    return requestTypes;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public Set<Resource.Type> getResourceTypes() {
+    return resourceTypes;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public Set<ResultStatus.STATUS> getResultStatuses() {
+    return null;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public AuditEvent createAuditEvent(Request request, Result result) {
+    String username = ((User) 
SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUsername();
+
+    switch (request.getRequestType()) {
+      case POST:
+        return CreateGroupRequestAuditEvent.builder()
+          .withTimestamp(DateTime.now())
+          .withRequestType(request.getRequestType())
+          .withResultStatus(result.getStatus())
+          .withUrl(request.getURI())
+          .withRemoteIp(request.getRemoteAddress())
+          .withUserName(username)
+          .withGroupName(getGroupName(request))
+          .build();
+      case DELETE:
+        return DeleteGroupRequestAuditEvent.builder()
+          .withTimestamp(DateTime.now())
+          .withRequestType(request.getRequestType())
+          .withResultStatus(result.getStatus())
+          .withUrl(request.getURI())
+          .withRemoteIp(request.getRemoteAddress())
+          .withUserName(username)
+          
.withGroupName(request.getResource().getKeyValueMap().get(Resource.Type.Group))
+          .build();
+      default:
+        break;
+    }
+    return null;
+  }
+
+  /**
+   * Returns group name from request
+   * @param request
+   * @return
+   */
+  private String getGroupName(Request request) {
+    if (!request.getBody().getPropertySets().isEmpty()) {
+      return 
String.valueOf(request.getBody().getPropertySets().iterator().next().get(PropertyHelper.getPropertyId("Groups",
 "group_name")));
+    }
+    return null;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/565c2ea2/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/HostEventCreator.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/HostEventCreator.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/HostEventCreator.java
new file mode 100644
index 0000000..6d26a4c
--- /dev/null
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/HostEventCreator.java
@@ -0,0 +1,168 @@
+/*
+ * 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.ambari.server.audit.request.eventcreator;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.ambari.server.api.services.Request;
+import org.apache.ambari.server.api.services.Result;
+import org.apache.ambari.server.api.services.ResultStatus;
+import org.apache.ambari.server.audit.event.AuditEvent;
+import 
org.apache.ambari.server.audit.event.request.AddComponentToHostRequestAuditEvent;
+import org.apache.ambari.server.audit.event.request.AddHostRequestAuditEvent;
+import 
org.apache.ambari.server.audit.event.request.DeleteHostRequestAuditEvent;
+import org.apache.ambari.server.audit.request.RequestAuditEventCreator;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.joda.time.DateTime;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.User;
+
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * This creator handles host requests (add, delete, add component)
+ * For resource type {@link Resource.Type#HostComponent}
+ * and request types {@link Request.Type#POST}, {@link Request.Type#DELETE} 
and {@link Request.Type#QUERY_POST}
+ */
+public class HostEventCreator implements RequestAuditEventCreator {
+
+  /**
+   * Set of {@link Request.Type}s that are handled by this plugin
+   */
+  private Set<Request.Type> requestTypes = 
ImmutableSet.<Request.Type>builder().add(Request.Type.QUERY_POST, 
Request.Type.POST, Request.Type.DELETE).build();
+
+  /**
+   * Set of {@link Resource.Type}s that are handled by this plugin
+   */
+  private Set<Resource.Type> resourceTypes = 
ImmutableSet.<Resource.Type>builder().add(Resource.Type.Host).build();
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public Set<Request.Type> getRequestTypes() {
+    return requestTypes;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public Set<Resource.Type> getResourceTypes() {
+    return resourceTypes;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public Set<ResultStatus.STATUS> getResultStatuses() {
+    // null makes this default
+    return null;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public AuditEvent createAuditEvent(Request request, Result result) {
+    String username = ((User) 
SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUsername();
+
+    switch (request.getRequestType()) {
+      case DELETE:
+        return DeleteHostRequestAuditEvent.builder()
+          .withTimestamp(DateTime.now())
+          .withRequestType(request.getRequestType())
+          .withResultStatus(result.getStatus())
+          .withUrl(request.getURI())
+          .withRemoteIp(request.getRemoteAddress())
+          .withUserName(username)
+          
.withHostName(request.getResource().getKeyValueMap().get(Resource.Type.Host))
+          .build();
+      case POST:
+        return AddHostRequestAuditEvent.builder()
+          .withTimestamp(DateTime.now())
+          .withRequestType(request.getRequestType())
+          .withResultStatus(result.getStatus())
+          .withUrl(request.getURI())
+          .withRemoteIp(request.getRemoteAddress())
+          .withUserName(username)
+          .withHostName(getHostName(request))
+          .build();
+      case QUERY_POST:
+        return AddComponentToHostRequestAuditEvent.builder()
+          .withTimestamp(DateTime.now())
+          .withRequestType(request.getRequestType())
+          .withResultStatus(result.getStatus())
+          .withUrl(request.getURI())
+          .withRemoteIp(request.getRemoteAddress())
+          .withUserName(username)
+          .withHostName(getHostNameFromQuery(request))
+          .withComponent(getHostComponent(request))
+          .build();
+      default:
+        return null;
+    }
+  }
+
+  /**
+   * Returns hostname from the request
+   * @param request
+   * @return
+   */
+  private String getHostName(Request request) {
+    if (!request.getBody().getNamedPropertySets().isEmpty()) {
+      return 
String.valueOf(request.getBody().getNamedPropertySets().iterator().next().getProperties().get(PropertyHelper.getPropertyId("Hosts",
 "host_name")));
+    }
+    return null;
+  }
+
+  /**
+   * Returns component name from the request
+   * @param request
+   * @return
+   */
+  private String getHostComponent(Request request) {
+    if (!request.getBody().getNamedPropertySets().isEmpty()) {
+      Set<Map<String, String>> set = (Set<Map<String, String>>) 
request.getBody().getNamedPropertySets().iterator().next().getProperties().get("host_components");
+      if (set != null && !set.isEmpty()) {
+        return 
set.iterator().next().get(PropertyHelper.getPropertyId("HostRoles", 
"component_name"));
+      }
+    }
+    return null;
+  }
+
+  /**
+   * Returns hostname from the query string of the request
+   * @param request
+   * @return
+   */
+  private String getHostNameFromQuery(Request request) {
+    final String key = PropertyHelper.getPropertyId("Hosts", "host_name");
+    if (request.getBody().getQueryString().contains(key)) {
+      String q = request.getBody().getQueryString();
+      int startIndex = q.indexOf(key) + key.length() + 1;
+      int endIndex = q.indexOf("&", startIndex) == -1 ? q.length() : 
q.indexOf("&", startIndex);
+      return q.substring(startIndex, endIndex);
+    }
+    return null;
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/565c2ea2/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/MemberEventCreator.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/MemberEventCreator.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/MemberEventCreator.java
new file mode 100644
index 0000000..771ac33
--- /dev/null
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/MemberEventCreator.java
@@ -0,0 +1,176 @@
+/*
+ * 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.ambari.server.audit.request.eventcreator;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.ambari.server.api.services.Request;
+import org.apache.ambari.server.api.services.Result;
+import org.apache.ambari.server.api.services.ResultStatus;
+import org.apache.ambari.server.audit.event.AuditEvent;
+import 
org.apache.ambari.server.audit.event.request.AddUserToGroupRequestAuditEvent;
+import 
org.apache.ambari.server.audit.event.request.MembershipChangeRequestAuditEvent;
+import 
org.apache.ambari.server.audit.event.request.RemoveUserFromGroupRequestAuditEvent;
+import org.apache.ambari.server.audit.request.RequestAuditEventCreator;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.joda.time.DateTime;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.User;
+
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * This creator handles member requests
+ * For resource type {@link Resource.Type#Member}
+ * and request types {@link Request.Type#POST}, {@link Request.Type#PUT} and 
{@link Request.Type#DELETE}
+ */
+public class MemberEventCreator implements RequestAuditEventCreator {
+
+  /**
+   * Set of {@link Request.Type}s that are handled by this plugin
+   */
+  private Set<Request.Type> requestTypes = 
ImmutableSet.<Request.Type>builder().add(Request.Type.PUT, Request.Type.POST, 
Request.Type.DELETE).build();
+
+  /**
+   * Set of {@link Resource.Type}s that are handled by this plugin
+   */
+  private Set<Resource.Type> resourceTypes = 
ImmutableSet.<Resource.Type>builder().add(Resource.Type.Member).build();
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public Set<Request.Type> getRequestTypes() {
+    return requestTypes;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public Set<Resource.Type> getResourceTypes() {
+    return resourceTypes;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public Set<ResultStatus.STATUS> getResultStatuses() {
+    return null;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public AuditEvent createAuditEvent(Request request, Result result) {
+    String username = ((User) 
SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUsername();
+
+    switch (request.getRequestType()) {
+      case POST:
+        return AddUserToGroupRequestAuditEvent.builder()
+          .withTimestamp(DateTime.now())
+          .withRequestType(request.getRequestType())
+          .withResultStatus(result.getStatus())
+          .withUrl(request.getURI())
+          .withRemoteIp(request.getRemoteAddress())
+          .withUserName(username)
+          .withAffectedUserName(getUserName(request))
+          .withGroupName(getGroupName(request))
+          .build();
+      case DELETE:
+        return RemoveUserFromGroupRequestAuditEvent.builder()
+          .withTimestamp(DateTime.now())
+          .withRequestType(request.getRequestType())
+          .withResultStatus(result.getStatus())
+          .withUrl(request.getURI())
+          .withRemoteIp(request.getRemoteAddress())
+          .withUserName(username)
+          .withAffectedUserName(getUserName(request))
+          .withGroupName(getGroupName(request))
+          .build();
+      case PUT:
+        return MembershipChangeRequestAuditEvent.builder()
+          .withTimestamp(DateTime.now())
+          .withRequestType(request.getRequestType())
+          .withResultStatus(result.getStatus())
+          .withUrl(request.getURI())
+          .withRemoteIp(request.getRemoteAddress())
+          .withUserName(username)
+          .withGroupName(getGroupNameForPut(request))
+          .withUserNameList(getUsers(request))
+          .build();
+      default:
+        return null;
+    }
+  }
+
+  /**
+   * Returns users from the request
+   * @param request
+   * @return
+   */
+  private List<String> getUsers(Request request) {
+    List<String> users = new LinkedList<String>();
+
+    for (Map<String, Object> propertyMap : 
request.getBody().getPropertySets()) {
+      String userName = 
String.valueOf(propertyMap.get(PropertyHelper.getPropertyId("MemberInfo", 
"user_name")));
+      users.add(userName);
+    }
+    return users;
+  }
+
+  /**
+   * Returns target group name from the request. This is called when PUT 
request type is used.
+   * @param request
+   * @return
+   */
+  private String getGroupNameForPut(Request request) {
+
+    for (Map<String, Object> propertyMap : 
request.getBody().getPropertySets()) {
+      return 
String.valueOf(propertyMap.get(PropertyHelper.getPropertyId("MemberInfo", 
"group_name")));
+    }
+    return null;
+  }
+
+  /**
+   * Returns username from the request
+   * @param request
+   * @return
+   */
+  private String getUserName(Request request) {
+    return request.getResource().getKeyValueMap().get(Resource.Type.Member);
+  }
+
+  /**
+   * Returns groupname from the request
+   * @param request
+   * @return
+   */
+  private String getGroupName(Request request) {
+    return request.getResource().getKeyValueMap().get(Resource.Type.Group);
+  }
+
+
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/565c2ea2/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/PrivilegeEventCreator.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/PrivilegeEventCreator.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/PrivilegeEventCreator.java
new file mode 100644
index 0000000..3c98329
--- /dev/null
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/PrivilegeEventCreator.java
@@ -0,0 +1,148 @@
+/*
+ * 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.ambari.server.audit.request.eventcreator;
+
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.ambari.server.api.services.Request;
+import org.apache.ambari.server.api.services.Result;
+import org.apache.ambari.server.api.services.ResultStatus;
+import org.apache.ambari.server.audit.event.AuditEvent;
+import 
org.apache.ambari.server.audit.event.request.ClusterPrivilegeChangeRequestAuditEvent;
+import 
org.apache.ambari.server.audit.event.request.PrivilegeChangeRequestAuditEvent;
+import org.apache.ambari.server.audit.request.RequestAuditEventCreator;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.joda.time.DateTime;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.User;
+
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * This creator handles privilege requests
+ * For resource type {@link Resource.Type#ClusterPrivilege}
+ * and request types {@link Request.Type#POST}, {@link Request.Type#PUT}
+ */
+public class PrivilegeEventCreator implements RequestAuditEventCreator {
+
+  /**
+   * Set of {@link Request.Type}s that are handled by this plugin
+   */
+  private Set<Request.Type> requestTypes = 
ImmutableSet.<Request.Type>builder().add(Request.Type.PUT, 
Request.Type.POST).build();
+
+  /**
+   * Set of {@link Resource.Type}s that are handled by this plugin
+   */
+  private Set<Resource.Type> resourceTypes = 
ImmutableSet.<Resource.Type>builder().add(Resource.Type.ClusterPrivilege).build();
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public Set<Request.Type> getRequestTypes() {
+    return requestTypes;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public Set<Resource.Type> getResourceTypes() {
+    return resourceTypes;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public Set<ResultStatus.STATUS> getResultStatuses() {
+    return null;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public AuditEvent createAuditEvent(Request request, Result result) {
+    String username = ((User) 
SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUsername();
+
+    Map<String, List<String>> users = getEntities(request, "USER");
+    Map<String, List<String>> groups = getEntities(request, "GROUP");
+
+    switch (request.getRequestType()) {
+      case PUT:
+        return ClusterPrivilegeChangeRequestAuditEvent.builder()
+          .withTimestamp(DateTime.now())
+          .withRequestType(request.getRequestType())
+          .withResultStatus(result.getStatus())
+          .withUrl(request.getURI())
+          .withRemoteIp(request.getRemoteAddress())
+          .withUserName(username)
+          .withUsers(users)
+          .withGroups(groups)
+          .build();
+      case POST:
+        String role = users.isEmpty() ? (groups.isEmpty() ? null : 
groups.keySet().iterator().next()) : users.keySet().iterator().next();
+        return PrivilegeChangeRequestAuditEvent.builder()
+          .withTimestamp(DateTime.now())
+          .withRequestType(request.getRequestType())
+          .withResultStatus(result.getStatus())
+          .withUrl(request.getURI())
+          .withRemoteIp(request.getRemoteAddress())
+          .withUserName(username)
+          .withRole(role)
+          .withGroup(groups.get(role) == null ? null : groups.get(role).get(0))
+          .withUser(users.get(role) == null ? null : users.get(role).get(0))
+          .withOperation((users.isEmpty() ? (groups.isEmpty() ? "" : "Group ") 
: "User ") + "role change")
+          .build();
+      default:
+        return null;
+    }
+  }
+
+  /**
+   * Assembles entities from the request. The result can contain users or 
groups based on the value of type parameter
+   * @param request
+   * @param type
+   * @return a map of role -> [user|group] names
+   */
+  private Map<String, List<String>> getEntities(final Request request, final 
String type) {
+    Map<String, List<String>> entities = new HashMap<String, List<String>>();
+
+    for (Map<String, Object> propertyMap : 
request.getBody().getPropertySets()) {
+      String ptype = 
String.valueOf(propertyMap.get(PropertyHelper.getPropertyId("PrivilegeInfo", 
"principal_type")));
+      if (type.equals(ptype)) {
+        String role = 
String.valueOf(propertyMap.get(PropertyHelper.getPropertyId("PrivilegeInfo", 
"permission_name")));
+        String name = 
String.valueOf(propertyMap.get(PropertyHelper.getPropertyId("PrivilegeInfo", 
"principal_name")));
+        if (!entities.containsKey(role)) {
+          entities.put(role, new LinkedList<String>());
+        }
+
+        entities.get(role).add(name);
+      }
+    }
+    return entities;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/565c2ea2/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/RecommendationIgnoreEventCreator.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/RecommendationIgnoreEventCreator.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/RecommendationIgnoreEventCreator.java
new file mode 100644
index 0000000..6b7bb2b
--- /dev/null
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/RecommendationIgnoreEventCreator.java
@@ -0,0 +1,81 @@
+/*
+ * 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.ambari.server.audit.request.eventcreator;
+
+import java.util.Set;
+
+import org.apache.ambari.server.api.services.Request;
+import org.apache.ambari.server.api.services.Result;
+import org.apache.ambari.server.api.services.ResultStatus;
+import org.apache.ambari.server.audit.event.AuditEvent;
+import org.apache.ambari.server.audit.request.RequestAuditEventCreator;
+import org.apache.ambari.server.controller.spi.Resource;
+
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * This creator ignores recommendation post requests
+ * For resource type {@link Resource.Type#Recommendation}
+ * and request types {@link Request.Type#POST}
+ */
+public class RecommendationIgnoreEventCreator implements 
RequestAuditEventCreator {
+
+  /**
+   * Set of {@link Request.Type}s that are handled by this plugin
+   */
+  private Set<Request.Type> requestTypes = 
ImmutableSet.<Request.Type>builder().add(Request.Type.POST).build();
+
+  /**
+   * Set of {@link Resource.Type}s that are handled by this plugin
+   */
+  private Set<Resource.Type> resourceTypes = 
ImmutableSet.<Resource.Type>builder().add(Resource.Type.Recommendation).build();
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public Set<Request.Type> getRequestTypes() {
+    return requestTypes;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public Set<Resource.Type> getResourceTypes() {
+    return resourceTypes;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public Set<ResultStatus.STATUS> getResultStatuses() {
+    return null;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public AuditEvent createAuditEvent(Request request, Result result) {
+    // intentionally skipping this event
+    return null;
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/565c2ea2/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/RepositoryEventCreator.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/RepositoryEventCreator.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/RepositoryEventCreator.java
new file mode 100644
index 0000000..321940d
--- /dev/null
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/audit/request/eventcreator/RepositoryEventCreator.java
@@ -0,0 +1,133 @@
+/*
+ * 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.ambari.server.audit.request.eventcreator;
+
+import java.util.Set;
+
+import org.apache.ambari.server.api.services.Request;
+import org.apache.ambari.server.api.services.Result;
+import org.apache.ambari.server.api.services.ResultStatus;
+import org.apache.ambari.server.audit.event.AuditEvent;
+import 
org.apache.ambari.server.audit.event.request.AddRepositoryRequestAuditEvent;
+import 
org.apache.ambari.server.audit.event.request.UpdateRepositoryRequestAuditEvent;
+import org.apache.ambari.server.audit.request.RequestAuditEventCreator;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.joda.time.DateTime;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.core.userdetails.User;
+
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * This creator handles privilege requests
+ * For resource type {@link Resource.Type#Repository}
+ * and request types {@link Request.Type#POST} and {@link Request.Type#PUT}
+ */
+public class RepositoryEventCreator implements RequestAuditEventCreator {
+
+  /**
+   * Set of {@link Request.Type}s that are handled by this plugin
+   */
+  private Set<Request.Type> requestTypes = 
ImmutableSet.<Request.Type>builder().add(Request.Type.PUT, 
Request.Type.POST).build();
+
+  /**
+   * Set of {@link Resource.Type}s that are handled by this plugin
+   */
+  private Set<Resource.Type> resourceTypes = 
ImmutableSet.<Resource.Type>builder().add(Resource.Type.Repository).build();
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public Set<Request.Type> getRequestTypes() {
+    return requestTypes;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public Set<Resource.Type> getResourceTypes() {
+    return resourceTypes;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public Set<ResultStatus.STATUS> getResultStatuses() {
+    return null;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public AuditEvent createAuditEvent(Request request, Result result) {
+    String username = ((User) 
SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUsername();
+
+    switch (request.getRequestType()) {
+      case POST:
+        return AddRepositoryRequestAuditEvent.builder()
+          .withTimestamp(DateTime.now())
+          .withRequestType(request.getRequestType())
+          .withResultStatus(result.getStatus())
+          .withUrl(request.getURI())
+          .withRemoteIp(request.getRemoteAddress())
+          .withUserName(username)
+          .withRepo(getProperty(request, 
PropertyHelper.getPropertyId("Repositories", "repo_id")))
+          .withStackName(getProperty(request, 
PropertyHelper.getPropertyId("Repositories", "stack_name")))
+          .withStackVersion(getProperty(request, 
PropertyHelper.getPropertyId("Repositories", "stack_version")))
+          .withOsType(getProperty(request, 
PropertyHelper.getPropertyId("Repositories", "os_type")))
+          .withBaseUrl(getProperty(request, 
PropertyHelper.getPropertyId("Repositories", "base_url")))
+          .build();
+      case PUT:
+        return UpdateRepositoryRequestAuditEvent.builder()
+          .withTimestamp(DateTime.now())
+          .withRequestType(request.getRequestType())
+          .withResultStatus(result.getStatus())
+          .withUrl(request.getURI())
+          .withRemoteIp(request.getRemoteAddress())
+          .withUserName(username)
+          .withRepo(getProperty(request, 
PropertyHelper.getPropertyId("Repositories", "repo_id")))
+          .withStackName(getProperty(request, 
PropertyHelper.getPropertyId("Repositories", "stack_name")))
+          .withStackVersion(getProperty(request, 
PropertyHelper.getPropertyId("Repositories", "stack_version")))
+          .withOsType(getProperty(request, 
PropertyHelper.getPropertyId("Repositories", "os_type")))
+          .withBaseUrl(getProperty(request, 
PropertyHelper.getPropertyId("Repositories", "base_url")))
+          .build();
+      default:
+        return null;
+    }
+  }
+
+  /**
+   * Returns a property from the request based on the propertyId parameter
+   * @param request
+   * @param properyId
+   * @return
+   */
+  private String getProperty(Request request, String properyId) {
+    if (!request.getBody().getPropertySets().isEmpty()) {
+      return 
String.valueOf(request.getBody().getPropertySets().iterator().next().get(properyId));
+    }
+    return null;
+  }
+
+}

Reply via email to