You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ac...@apache.org on 2016/12/17 11:53:47 UTC

[08/17] camel git commit: CAMEL-9748: camel-openstack keystone

CAMEL-9748: camel-openstack keystone


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/9f3d212a
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/9f3d212a
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/9f3d212a

Branch: refs/heads/master
Commit: 9f3d212a8c773f9e7c08199283fe3b3fe76fa8da
Parents: 2847e09
Author: Jan Bouska <jb...@redhat.com>
Authored: Sat Dec 3 20:25:07 2016 +0100
Committer: Andrea Cosentino <an...@gmail.com>
Committed: Sat Dec 17 12:25:14 2016 +0100

----------------------------------------------------------------------
 .../openstack/keystone/KeystoneComponent.java   |  33 ++++
 .../openstack/keystone/KeystoneConstants.java   |  43 +++++
 .../openstack/keystone/KeystoneEndpoint.java    | 164 +++++++++++++++++
 .../producer/AbstractKeystoneProducer.java      |  33 ++++
 .../keystone/producer/DomainProducer.java       | 115 ++++++++++++
 .../keystone/producer/GroupProducer.java        | 157 ++++++++++++++++
 .../keystone/producer/ProjectProducer.java      | 121 +++++++++++++
 .../keystone/producer/RegionProducer.java       | 110 ++++++++++++
 .../keystone/producer/UserProducer.java         | 125 +++++++++++++
 .../apache/camel/component/openstack-keystone   |   1 +
 .../openstack/AbstractProducerTestSupport.java  |   2 +-
 .../openstack/keystone/DomainProducerTest.java  | 169 +++++++++++++++++
 .../openstack/keystone/GroupProducerTest.java   | 171 ++++++++++++++++++
 .../keystone/KeystoneProducerTestSupport.java   |  65 +++++++
 .../openstack/keystone/ProjectProducerTest.java | 173 ++++++++++++++++++
 .../openstack/keystone/RegionProducerTest.java  | 163 +++++++++++++++++
 .../openstack/keystone/UserProducerTest.java    | 179 +++++++++++++++++++
 17 files changed, 1823 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/9f3d212a/components/camel-openstack/src/main/java/org/apache/camel/component/openstack/keystone/KeystoneComponent.java
----------------------------------------------------------------------
diff --git a/components/camel-openstack/src/main/java/org/apache/camel/component/openstack/keystone/KeystoneComponent.java b/components/camel-openstack/src/main/java/org/apache/camel/component/openstack/keystone/KeystoneComponent.java
new file mode 100644
index 0000000..34e92f9
--- /dev/null
+++ b/components/camel-openstack/src/main/java/org/apache/camel/component/openstack/keystone/KeystoneComponent.java
@@ -0,0 +1,33 @@
+/**
+ * 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.camel.component.openstack.keystone;
+
+import org.apache.camel.Endpoint;
+import org.apache.camel.impl.DefaultComponent;
+
+import java.util.Map;
+
+public class KeystoneComponent extends DefaultComponent {
+
+	@Override protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception {
+		KeystoneEndpoint endpoint = new KeystoneEndpoint(uri, this);
+		setProperties(endpoint, parameters);
+		endpoint.setHost(remaining);
+		return endpoint;
+	}
+}
+

http://git-wip-us.apache.org/repos/asf/camel/blob/9f3d212a/components/camel-openstack/src/main/java/org/apache/camel/component/openstack/keystone/KeystoneConstants.java
----------------------------------------------------------------------
diff --git a/components/camel-openstack/src/main/java/org/apache/camel/component/openstack/keystone/KeystoneConstants.java b/components/camel-openstack/src/main/java/org/apache/camel/component/openstack/keystone/KeystoneConstants.java
new file mode 100644
index 0000000..e6273b0
--- /dev/null
+++ b/components/camel-openstack/src/main/java/org/apache/camel/component/openstack/keystone/KeystoneConstants.java
@@ -0,0 +1,43 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.openstack.keystone;
+
+import org.apache.camel.component.openstack.common.OpenstackConstants;
+
+public final class KeystoneConstants extends OpenstackConstants{
+
+	public static final String REGIONS = "regions";
+	public static final String DOMAINS = "domains";
+	public static final String PROJECTS = "projects";
+	public static final String USERS = "users";
+	public static final String GROUPS = "groups";
+
+	public static final String DESCRIPTION = "description";
+	public static final String DOMAIN_ID = "domainId";
+	public static final String PARENT_ID = "parentId";
+
+	public static final String PASSWORD = "password";
+	public static final String EMAIL = "email";
+
+	public static final String USER_ID = "userId";
+	public static final String GROUP_ID = "groupId";
+
+	public static final String ADD_USER_TO_GROUP = "addUserToGroup";
+	public static final String CHECK_GROUP_USER = "checkUserGroup";
+	public static final String REMOVE_USER_FROM_GROUP = "removeUserFromGroup";
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/9f3d212a/components/camel-openstack/src/main/java/org/apache/camel/component/openstack/keystone/KeystoneEndpoint.java
----------------------------------------------------------------------
diff --git a/components/camel-openstack/src/main/java/org/apache/camel/component/openstack/keystone/KeystoneEndpoint.java b/components/camel-openstack/src/main/java/org/apache/camel/component/openstack/keystone/KeystoneEndpoint.java
new file mode 100644
index 0000000..bb57f72
--- /dev/null
+++ b/components/camel-openstack/src/main/java/org/apache/camel/component/openstack/keystone/KeystoneEndpoint.java
@@ -0,0 +1,164 @@
+/**
+ * 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.camel.component.openstack.keystone;
+
+import org.apache.camel.Producer;
+import org.apache.camel.component.openstack.common.AbstractOpenstackEndpoint;
+import org.apache.camel.component.openstack.keystone.producer.DomainProducer;
+import org.apache.camel.component.openstack.keystone.producer.GroupProducer;
+import org.apache.camel.component.openstack.keystone.producer.ProjectProducer;
+import org.apache.camel.component.openstack.keystone.producer.RegionProducer;
+import org.apache.camel.component.openstack.keystone.producer.UserProducer;
+import org.apache.camel.spi.Metadata;
+import org.apache.camel.spi.UriEndpoint;
+import org.apache.camel.spi.UriParam;
+import org.apache.camel.spi.UriPath;
+
+@UriEndpoint(scheme = "openstack-keystone", title = "OpenStack-Keystone", syntax = "openstack-keystone:host", label = "cloud, virtualization")
+public class KeystoneEndpoint extends AbstractOpenstackEndpoint {
+
+	@UriPath
+	@Metadata(required = "true")
+	private String host;
+
+	@UriParam(enums = "regions, domains, projects, users, groups")
+	@Metadata(required = "true")
+	String subsystem;
+
+	@UriParam(defaultValue = "default")
+	private String domain = "default";
+
+	@UriParam
+	@Metadata(required = "true")
+	private String project;
+
+	@UriParam
+	private String operation;
+
+	@UriParam
+	@Metadata(required = "true")
+	private String username;
+
+	@UriParam
+	@Metadata(required = "true")
+	private String password;
+
+	public KeystoneEndpoint(String uri, KeystoneComponent component) {
+		super(uri, component);
+	}
+
+	@Override
+	public Producer createProducer() throws Exception {
+		switch (getSubsystem()) {
+			case KeystoneConstants.REGIONS:
+				return new RegionProducer(this, createClient());
+			case KeystoneConstants.DOMAINS:
+				return new DomainProducer(this, createClient());
+			case KeystoneConstants.PROJECTS:
+				return new ProjectProducer(this, createClient());
+			case KeystoneConstants.USERS:
+				return new UserProducer(this, createClient());
+			case KeystoneConstants.GROUPS:
+				return new GroupProducer(this, createClient());
+			default:
+				throw new IllegalArgumentException("Can't create producer with subsystem " + subsystem);
+		}
+	}
+
+	public String getSubsystem() {
+		return subsystem;
+	}
+
+	/**
+	 * OpenStack Nova subsystem
+	 */
+	public void setSubsystem(String subsystem) {
+		this.subsystem = subsystem;
+	}
+
+	@Override
+	public String getDomain() {
+		return domain;
+	}
+
+	/**
+	 * Authentication domain
+	 */
+	public void setDomain(String domain) {
+		this.domain = domain;
+	}
+
+	@Override
+	public String getProject() {
+		return project;
+	}
+
+	/**
+	 * The project ID
+	 */
+	public void setProject(String project) {
+		this.project = project;
+	}
+
+	@Override
+	public String getOperation() {
+		return operation;
+	}
+
+	/**
+	 * The operation to do
+	 */
+	public void setOperation(String operation) {
+		this.operation = operation;
+	}
+
+	@Override
+	public String getUsername() {
+		return username;
+	}
+
+	/**
+	 * OpenStack username
+	 */
+	public void setUsername(String username) {
+		this.username = username;
+	}
+
+	@Override
+	public String getPassword() {
+		return password;
+	}
+
+	/**
+	 * OpenStack password
+	 */
+	public void setPassword(String password) {
+		this.password = password;
+	}
+
+	@Override
+	public String getHost() {
+		return host;
+	}
+
+	/**
+	 * OpenStack host url
+	 */
+	public void setHost(String host) {
+		this.host = host;
+	}
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/9f3d212a/components/camel-openstack/src/main/java/org/apache/camel/component/openstack/keystone/producer/AbstractKeystoneProducer.java
----------------------------------------------------------------------
diff --git a/components/camel-openstack/src/main/java/org/apache/camel/component/openstack/keystone/producer/AbstractKeystoneProducer.java b/components/camel-openstack/src/main/java/org/apache/camel/component/openstack/keystone/producer/AbstractKeystoneProducer.java
new file mode 100644
index 0000000..f4d9690
--- /dev/null
+++ b/components/camel-openstack/src/main/java/org/apache/camel/component/openstack/keystone/producer/AbstractKeystoneProducer.java
@@ -0,0 +1,33 @@
+/**
+ * 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.camel.component.openstack.keystone.producer;
+
+import org.apache.camel.component.openstack.common.AbstractOpenstackEndpoint;
+import org.apache.camel.component.openstack.common.AbstractOpenstackProducer;
+
+import org.openstack4j.api.OSClient;
+
+
+public abstract class AbstractKeystoneProducer extends AbstractOpenstackProducer {
+
+	OSClient.OSClientV3 osV3Client;
+
+	public AbstractKeystoneProducer(AbstractOpenstackEndpoint endpoint, OSClient.OSClientV3 client) {
+		super(endpoint, client);
+		osV3Client = client;
+	}
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/9f3d212a/components/camel-openstack/src/main/java/org/apache/camel/component/openstack/keystone/producer/DomainProducer.java
----------------------------------------------------------------------
diff --git a/components/camel-openstack/src/main/java/org/apache/camel/component/openstack/keystone/producer/DomainProducer.java b/components/camel-openstack/src/main/java/org/apache/camel/component/openstack/keystone/producer/DomainProducer.java
new file mode 100644
index 0000000..c90ae50
--- /dev/null
+++ b/components/camel-openstack/src/main/java/org/apache/camel/component/openstack/keystone/producer/DomainProducer.java
@@ -0,0 +1,115 @@
+/**
+ * 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.camel.component.openstack.keystone.producer;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.component.openstack.keystone.KeystoneConstants;
+import org.apache.camel.component.openstack.keystone.KeystoneEndpoint;
+import org.apache.camel.util.ObjectHelper;
+
+import org.openstack4j.api.Builders;
+import org.openstack4j.api.OSClient;
+import org.openstack4j.model.common.ActionResponse;
+import org.openstack4j.model.identity.v3.Domain;
+import org.openstack4j.model.identity.v3.builder.DomainBuilder;
+
+import java.util.List;
+import java.util.Map;
+
+public class DomainProducer extends AbstractKeystoneProducer {
+
+	public DomainProducer(KeystoneEndpoint endpoint, OSClient.OSClientV3 client) {
+		super(endpoint, client);
+	}
+
+	@Override public void process(Exchange exchange) throws Exception {
+		final String operation = getOperation(exchange);
+		switch (operation) {
+			case KeystoneConstants.CREATE:
+				doCreate(exchange);
+				break;
+			case KeystoneConstants.GET:
+				doGet(exchange);
+				break;
+			case KeystoneConstants.GET_ALL:
+				doGetAll(exchange);
+				break;
+			case KeystoneConstants.UPDATE:
+				doUpdate(exchange);
+				break;
+			case KeystoneConstants.DELETE:
+				doDelete(exchange);
+				break;
+			default:
+				throw new IllegalArgumentException("Unsupported operation " + operation);
+		}
+	}
+
+	private void doCreate(Exchange exchange) {
+		final Domain in = messageToDomain(exchange.getIn());
+		final Domain out = osV3Client.identity().domains().create(in);
+		exchange.getIn().setBody(out);
+	}
+
+	private void doGet(Exchange exchange) {
+		final Message msg = exchange.getIn();
+		final String id = msg.getHeader(KeystoneConstants.ID, msg.getHeader(KeystoneConstants.DOMAIN_ID, String.class), String.class);
+		ObjectHelper.notEmpty(id, "Domain ID");
+		final Domain out = osV3Client.identity().domains().get(id);
+		exchange.getIn().setBody(out);
+	}
+
+	private void doGetAll(Exchange exchange) {
+		final List<? extends Domain> out = osV3Client.identity().domains().list();
+		exchange.getIn().setBody(out);
+	}
+
+	private void doUpdate(Exchange exchange) {
+		final Message msg = exchange.getIn();
+		final Domain in = messageToDomain(msg);
+		final Domain out = osV3Client.identity().domains().update(in);
+		msg.setBody(out);
+	}
+
+	private void doDelete(Exchange exchange) {
+		final Message msg = exchange.getIn();
+		final String id = msg.getHeader(KeystoneConstants.ID, msg.getHeader(KeystoneConstants.DOMAIN_ID, String.class), String.class);
+		ObjectHelper.notEmpty(id, "Domain ID");
+		final ActionResponse response = osV3Client.identity().domains().delete(id);
+		checkFailure(response, msg, "Delete domain" + id);
+	}
+
+	//TODO:
+	private Domain messageToDomain(Message message) {
+		Domain domain = message.getBody(Domain.class);
+		if(domain == null) {
+			Map headers = message.getHeaders();
+			DomainBuilder builder = Builders.domain();
+
+			ObjectHelper.notEmpty(message.getHeader(KeystoneConstants.NAME, String.class), "Name");
+			builder.name(message.getHeader(KeystoneConstants.NAME, String.class));
+
+			if (headers.containsKey(KeystoneConstants.DESCRIPTION))
+				builder.description(message.getHeader(KeystoneConstants.DESCRIPTION, String.class));
+
+			domain = builder.build();
+		}
+
+		return domain;
+	}
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/9f3d212a/components/camel-openstack/src/main/java/org/apache/camel/component/openstack/keystone/producer/GroupProducer.java
----------------------------------------------------------------------
diff --git a/components/camel-openstack/src/main/java/org/apache/camel/component/openstack/keystone/producer/GroupProducer.java b/components/camel-openstack/src/main/java/org/apache/camel/component/openstack/keystone/producer/GroupProducer.java
new file mode 100644
index 0000000..aab828f
--- /dev/null
+++ b/components/camel-openstack/src/main/java/org/apache/camel/component/openstack/keystone/producer/GroupProducer.java
@@ -0,0 +1,157 @@
+/**
+ * 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.camel.component.openstack.keystone.producer;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.component.openstack.keystone.KeystoneConstants;
+import org.apache.camel.component.openstack.keystone.KeystoneEndpoint;
+import org.apache.camel.util.ObjectHelper;
+
+import org.openstack4j.api.Builders;
+import org.openstack4j.api.OSClient;
+import org.openstack4j.model.common.ActionResponse;
+import org.openstack4j.model.identity.v3.Group;
+import org.openstack4j.model.identity.v3.builder.GroupBuilder;
+
+import java.util.List;
+import java.util.Map;
+
+public class GroupProducer extends AbstractKeystoneProducer {
+
+	public GroupProducer(KeystoneEndpoint endpoint, OSClient.OSClientV3 client) {
+		super(endpoint, client);
+	}
+
+	@Override
+	public void process(Exchange exchange) throws Exception {
+		final String operation = getOperation(exchange);
+		switch (operation) {
+			case KeystoneConstants.CREATE:
+				doCreate(exchange);
+				break;
+			case KeystoneConstants.GET:
+				doGet(exchange);
+				break;
+			case KeystoneConstants.GET_ALL:
+				doGetAll(exchange);
+				break;
+			case KeystoneConstants.UPDATE:
+				doUpdate(exchange);
+				break;
+			case KeystoneConstants.DELETE:
+				doDelete(exchange);
+				break;
+			case KeystoneConstants.ADD_USER_TO_GROUP:
+				doAddUser(exchange);
+				break;
+			case KeystoneConstants.CHECK_GROUP_USER:
+				doCheckUserGroup(exchange);
+				break;
+			case KeystoneConstants.REMOVE_USER_FROM_GROUP:
+				doRemoveUserFromGroup(exchange);
+				break;
+			default:
+				throw new IllegalArgumentException("Unsupgrouped operation " + operation);
+		}
+	}
+
+	private void doCreate(Exchange exchange) {
+		final Group in = messageToGroup(exchange.getIn());
+		final Group out = osV3Client.identity().groups().create(in);
+		exchange.getIn().setBody(out);
+	}
+
+	private void doGet(Exchange exchange) {
+		final Message msg = exchange.getIn();
+		final String id = msg.getHeader(KeystoneConstants.ID, msg.getHeader(KeystoneConstants.GROUP_ID, String.class), String.class);
+		ObjectHelper.notEmpty(id, "Group ID");
+		final Group result = osV3Client.identity().groups().get(id);
+		msg.setBody(result);
+	}
+
+	private void doGetAll(Exchange exchange) {
+		final List<? extends Group> out = osV3Client.identity().groups().list();
+		exchange.getIn().setBody(out);
+	}
+
+	private void doUpdate(Exchange exchange) {
+		final Message msg = exchange.getIn();
+		final Group group = messageToGroup(msg);
+		final Group updatedGroup = osV3Client.identity().groups().update(group);
+		msg.setBody(updatedGroup);
+	}
+
+	private void doDelete(Exchange exchange) {
+		final Message msg = exchange.getIn();
+		final String id = msg.getHeader(KeystoneConstants.ID, msg.getHeader(KeystoneConstants.GROUP_ID, String.class), String.class);
+		ObjectHelper.notEmpty(id, "Group ID");
+		final ActionResponse response = osV3Client.identity().groups().delete(id);
+		checkFailure(response, msg, "Delete group with ID " + id);
+	}
+
+	private void doAddUser(Exchange exchange) {
+		final Message msg = exchange.getIn();
+		final String userId = msg.getHeader(KeystoneConstants.USER_ID, String.class);
+		final String groupId = msg.getHeader(KeystoneConstants.GROUP_ID, String.class);
+		ObjectHelper.notEmpty(userId, "User ID");
+		ObjectHelper.notEmpty(groupId, "Group ID");
+		final ActionResponse response = osV3Client.identity().groups().addUserToGroup(groupId, userId);
+		checkFailure(response, msg, String.format("Add user %s to group %s", userId, groupId));
+	}
+
+	private void doCheckUserGroup(Exchange exchange) {
+		final Message msg = exchange.getIn();
+		final String userId = msg.getHeader(KeystoneConstants.USER_ID, String.class);
+		final String groupId = msg.getHeader(KeystoneConstants.GROUP_ID, String.class);
+		ObjectHelper.notEmpty(userId, "User ID");
+		ObjectHelper.notEmpty(groupId, "Group ID");
+		final ActionResponse response = osV3Client.identity().groups().checkGroupUser(groupId, userId);
+		msg.setBody(response.isSuccess());
+	}
+
+	private void doRemoveUserFromGroup(Exchange exchange) {
+		final Message msg = exchange.getIn();
+		final String userId = msg.getHeader(KeystoneConstants.USER_ID, String.class);
+		final String groupId = msg.getHeader(KeystoneConstants.GROUP_ID, String.class);
+		ObjectHelper.notEmpty(userId, "User ID");
+		ObjectHelper.notEmpty(groupId, "Group ID");
+		final ActionResponse response = osV3Client.identity().groups().removeUserFromGroup(groupId, userId);
+		checkFailure(response, msg, String.format("Delete user %s from group %s", userId, groupId));
+	}
+
+	private Group messageToGroup(Message message) {
+		Group group = message.getBody(Group.class);
+
+		if (group == null) {
+			Map headers = message.getHeaders();
+			GroupBuilder builder = Builders.group();
+
+			ObjectHelper.notEmpty(message.getHeader(KeystoneConstants.NAME, String.class), "Name");
+			builder.name(message.getHeader(KeystoneConstants.NAME, String.class));
+
+			if (headers.containsKey(KeystoneConstants.DOMAIN_ID))
+				builder.domainId(message.getHeader(KeystoneConstants.DOMAIN_ID, String.class));
+
+			if (headers.containsKey(KeystoneConstants.DESCRIPTION))
+				builder.description(message.getHeader(KeystoneConstants.DESCRIPTION, String.class));
+
+			group = builder.build();
+		}
+		return group;
+	}
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/9f3d212a/components/camel-openstack/src/main/java/org/apache/camel/component/openstack/keystone/producer/ProjectProducer.java
----------------------------------------------------------------------
diff --git a/components/camel-openstack/src/main/java/org/apache/camel/component/openstack/keystone/producer/ProjectProducer.java b/components/camel-openstack/src/main/java/org/apache/camel/component/openstack/keystone/producer/ProjectProducer.java
new file mode 100644
index 0000000..f8aa248
--- /dev/null
+++ b/components/camel-openstack/src/main/java/org/apache/camel/component/openstack/keystone/producer/ProjectProducer.java
@@ -0,0 +1,121 @@
+/**
+ * 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.camel.component.openstack.keystone.producer;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.component.openstack.keystone.KeystoneConstants;
+import org.apache.camel.component.openstack.keystone.KeystoneEndpoint;
+import org.apache.camel.util.ObjectHelper;
+
+import org.openstack4j.api.Builders;
+import org.openstack4j.api.OSClient;
+import org.openstack4j.model.common.ActionResponse;
+import org.openstack4j.model.identity.v3.Project;
+import org.openstack4j.model.identity.v3.builder.ProjectBuilder;
+
+import java.util.List;
+import java.util.Map;
+
+public class ProjectProducer extends AbstractKeystoneProducer {
+
+	public ProjectProducer(KeystoneEndpoint endpoint, OSClient.OSClientV3 client) {
+		super(endpoint, client);
+	}
+
+	@Override
+	public void process(Exchange exchange) throws Exception {
+		final String operation = getOperation(exchange);
+		switch (operation) {
+			case KeystoneConstants.CREATE:
+				doCreate(exchange);
+				break;
+			case KeystoneConstants.GET:
+				doGet(exchange);
+				break;
+			case KeystoneConstants.GET_ALL:
+				doGetAll(exchange);
+				break;
+			case KeystoneConstants.UPDATE:
+				doUpdate(exchange);
+				break;
+			case KeystoneConstants.DELETE:
+				doDelete(exchange);
+				break;
+			default:
+				throw new IllegalArgumentException("Unsuproutered operation " + operation);
+		}
+	}
+
+	private void doCreate(Exchange exchange) {
+		final Project in = messageToProject(exchange.getIn());
+		final Project out = osV3Client.identity().projects().create(in);
+		exchange.getIn().setBody(out);
+	}
+
+	private void doGet(Exchange exchange) {
+		final Message msg = exchange.getIn();
+		final String id = msg.getHeader(KeystoneConstants.ID, String.class);
+		ObjectHelper.notEmpty(id, "Project ID");
+		final Project result = osV3Client.identity().projects().get(id);
+		msg.setBody(result);
+	}
+
+	private void doGetAll(Exchange exchange) {
+		final List<? extends Project> out = osV3Client.identity().projects().list();
+		exchange.getIn().setBody(out);
+	}
+
+	private void doUpdate(Exchange exchange) {
+		final Message msg = exchange.getIn();
+		final Project in = messageToProject(msg);
+		final Project out = osV3Client.identity().projects().update(in);
+		msg.setBody(out);
+	}
+
+	private void doDelete(Exchange exchange) {
+		final Message msg = exchange.getIn();
+		final String id = msg.getHeader(KeystoneConstants.ID, String.class);
+		ObjectHelper.notEmpty(id, "Project ID");
+		final ActionResponse response = osV3Client.identity().projects().delete(id);
+		checkFailure(response, msg, "Delete project with ID " + id);
+	}
+
+	private Project messageToProject(Message message) {
+		Project project = message.getBody(Project.class);
+
+		if (project == null) {
+			Map headers = message.getHeaders();
+			ProjectBuilder builder = Builders.project();
+
+			ObjectHelper.notEmpty(message.getHeader(KeystoneConstants.NAME, String.class), "Name");
+			builder.name(message.getHeader(KeystoneConstants.NAME, String.class));
+
+			if (headers.containsKey(KeystoneConstants.DOMAIN_ID))
+				builder.domainId(message.getHeader(KeystoneConstants.DOMAIN_ID, String.class));
+
+			if(headers.containsKey(KeystoneConstants.DESCRIPTION))
+				builder.description(message.getHeader(KeystoneConstants.DESCRIPTION, String.class));
+
+			if(headers.containsKey(KeystoneConstants.PARENT_ID))
+				builder.parentId(message.getHeader(KeystoneConstants.PARENT_ID, String.class));
+
+			project = builder.build();
+		}
+		return project;
+	}
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/9f3d212a/components/camel-openstack/src/main/java/org/apache/camel/component/openstack/keystone/producer/RegionProducer.java
----------------------------------------------------------------------
diff --git a/components/camel-openstack/src/main/java/org/apache/camel/component/openstack/keystone/producer/RegionProducer.java b/components/camel-openstack/src/main/java/org/apache/camel/component/openstack/keystone/producer/RegionProducer.java
new file mode 100644
index 0000000..0c9c80e
--- /dev/null
+++ b/components/camel-openstack/src/main/java/org/apache/camel/component/openstack/keystone/producer/RegionProducer.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.camel.component.openstack.keystone.producer;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.component.openstack.keystone.KeystoneConstants;
+import org.apache.camel.component.openstack.keystone.KeystoneEndpoint;
+import org.apache.camel.util.ObjectHelper;
+
+import org.openstack4j.api.Builders;
+import org.openstack4j.api.OSClient;
+import org.openstack4j.model.common.ActionResponse;
+import org.openstack4j.model.identity.v3.Region;
+import org.openstack4j.model.identity.v3.builder.RegionBuilder;
+
+import java.util.List;
+import java.util.Map;
+
+public class RegionProducer extends AbstractKeystoneProducer {
+
+	public RegionProducer(KeystoneEndpoint endpoint, OSClient.OSClientV3 client) {
+		super(endpoint, client);
+	}
+
+	@Override public void process(Exchange exchange) throws Exception {
+		final String operation = getOperation(exchange);
+		switch (operation) {
+			case KeystoneConstants.CREATE:
+				doCreate(exchange);
+				break;
+			case KeystoneConstants.GET:
+				doGet(exchange);
+				break;
+			case KeystoneConstants.GET_ALL:
+				doGetAll(exchange);
+				break;
+			case KeystoneConstants.UPDATE:
+				doUpdate(exchange);
+				break;
+			case KeystoneConstants.DELETE:
+				doDelete(exchange);
+				break;
+			default:
+				throw new IllegalArgumentException("Unsupported operation " + operation);
+		}
+	}
+
+	private void doCreate(Exchange exchange) {
+		final Region in = messageToRegion(exchange.getIn());
+		final Region out = osV3Client.identity().regions().create(in);
+		exchange.getIn().setBody(out);
+	}
+
+	private void doGet(Exchange exchange) {
+		final String id = exchange.getIn().getHeader(KeystoneConstants.ID, String.class);
+		ObjectHelper.notEmpty(id, "Region ID");
+		final Region out = osV3Client.identity().regions().get(id);
+		exchange.getIn().setBody(out);
+	}
+
+	private void doGetAll(Exchange exchange) {
+		final List<? extends Region> out = osV3Client.identity().regions().list();
+		exchange.getIn().setBody(out);
+	}
+
+	private void doUpdate(Exchange exchange) {
+		final Message msg = exchange.getIn();
+		final Region in = messageToRegion(msg);
+		final Region out = osV3Client.identity().regions().update(in);
+		msg.setBody(out);
+	}
+
+	private void doDelete(Exchange exchange) {
+		final Message msg = exchange.getIn();
+		final String id = msg.getHeader(KeystoneConstants.ID, String.class);
+		ObjectHelper.notEmpty(id, "Region ID");
+		final ActionResponse response = osV3Client.identity().regions().delete(id);
+		checkFailure(response, msg, "Delete network" + id);
+	}
+
+	private Region messageToRegion(Message message) {
+		Region region = message.getBody(Region.class);
+		if(region == null) {
+			Map headers = message.getHeaders();
+			RegionBuilder builder = Builders.region();
+
+			if(headers.containsKey(KeystoneConstants.DESCRIPTION))
+			builder.description(message.getHeader(KeystoneConstants.DESCRIPTION, String.class));
+
+			region = builder.build();
+		}
+
+		return region;
+	}
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/9f3d212a/components/camel-openstack/src/main/java/org/apache/camel/component/openstack/keystone/producer/UserProducer.java
----------------------------------------------------------------------
diff --git a/components/camel-openstack/src/main/java/org/apache/camel/component/openstack/keystone/producer/UserProducer.java b/components/camel-openstack/src/main/java/org/apache/camel/component/openstack/keystone/producer/UserProducer.java
new file mode 100644
index 0000000..4beacd1
--- /dev/null
+++ b/components/camel-openstack/src/main/java/org/apache/camel/component/openstack/keystone/producer/UserProducer.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.camel.component.openstack.keystone.producer;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Message;
+import org.apache.camel.component.openstack.keystone.KeystoneConstants;
+import org.apache.camel.component.openstack.keystone.KeystoneEndpoint;
+import org.apache.camel.util.ObjectHelper;
+
+import org.openstack4j.api.Builders;
+import org.openstack4j.api.OSClient;
+import org.openstack4j.model.common.ActionResponse;
+import org.openstack4j.model.identity.v3.User;
+import org.openstack4j.model.identity.v3.builder.UserBuilder;
+
+import java.util.List;
+import java.util.Map;
+
+public class UserProducer extends AbstractKeystoneProducer {
+
+	public UserProducer(KeystoneEndpoint endpoint, OSClient.OSClientV3 client) {
+		super(endpoint, client);
+	}
+
+	@Override
+	public void process(Exchange exchange) throws Exception {
+		final String operation = getOperation(exchange);
+		switch (operation) {
+			case KeystoneConstants.CREATE:
+				doCreate(exchange);
+				break;
+			case KeystoneConstants.GET:
+				doGet(exchange);
+				break;
+			case KeystoneConstants.GET_ALL:
+				doGetAll(exchange);
+				break;
+			case KeystoneConstants.UPDATE:
+				doUpdate(exchange);
+				break;
+			case KeystoneConstants.DELETE:
+				doDelete(exchange);
+				break;
+			default:
+				throw new IllegalArgumentException("Unsuproutered operation " + operation);
+		}
+	}
+
+	private void doCreate(Exchange exchange) {
+		final User in = messageToUser(exchange.getIn());
+		final User out = osV3Client.identity().users().create(in);
+		exchange.getIn().setBody(out);
+	}
+
+	private void doGet(Exchange exchange) {
+		final Message msg = exchange.getIn();
+		final String id = msg.getHeader(KeystoneConstants.ID, msg.getHeader(KeystoneConstants.USER_ID, String.class), String.class);
+		ObjectHelper.notEmpty(id, "User ID");
+		final User result = osV3Client.identity().users().get(id);
+		msg.setBody(result);
+	}
+
+	private void doGetAll(Exchange exchange) {
+		final List<? extends User> out = osV3Client.identity().users().list();
+		exchange.getIn().setBody(out);
+	}
+
+	private void doUpdate(Exchange exchange) {
+		final Message msg = exchange.getIn();
+		final User in = messageToUser(msg);
+		final User out = osV3Client.identity().users().update(in);
+		msg.setBody(out);
+	}
+
+	private void doDelete(Exchange exchange) {
+		final Message msg = exchange.getIn();
+		final String id = msg.getHeader(KeystoneConstants.ID, msg.getHeader(KeystoneConstants.USER_ID, String.class), String.class);
+		ObjectHelper.notEmpty(id, "User ID");
+		final ActionResponse response = osV3Client.identity().users().delete(id);
+		checkFailure(response, msg, "Delete user with ID " + id);
+	}
+
+	private User messageToUser(Message message) {
+		User project = message.getBody(User.class);
+
+		if (project == null) {
+			Map headers = message.getHeaders();
+			UserBuilder builder = Builders.user();
+
+			ObjectHelper.notEmpty(message.getHeader(KeystoneConstants.NAME, String.class), "Name");
+			builder.name(message.getHeader(KeystoneConstants.NAME, String.class));
+
+			if (headers.containsKey(KeystoneConstants.DOMAIN_ID))
+				builder.domainId(message.getHeader(KeystoneConstants.DOMAIN_ID, String.class));
+
+			if(headers.containsKey(KeystoneConstants.DESCRIPTION))
+				builder.description(message.getHeader(KeystoneConstants.DESCRIPTION, String.class));
+
+			if(headers.containsKey(KeystoneConstants.PASSWORD))
+				builder.password(message.getHeader(KeystoneConstants.PASSWORD, String.class));
+
+			if(headers.containsKey(KeystoneConstants.EMAIL))
+				builder.email(message.getHeader(KeystoneConstants.EMAIL, String.class));
+
+
+			project = builder.build();
+		}
+		return project;
+	}
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/9f3d212a/components/camel-openstack/src/main/resources/META-INF/services/org/apache/camel/component/openstack-keystone
----------------------------------------------------------------------
diff --git a/components/camel-openstack/src/main/resources/META-INF/services/org/apache/camel/component/openstack-keystone b/components/camel-openstack/src/main/resources/META-INF/services/org/apache/camel/component/openstack-keystone
new file mode 100644
index 0000000..d3eae0b
--- /dev/null
+++ b/components/camel-openstack/src/main/resources/META-INF/services/org/apache/camel/component/openstack-keystone
@@ -0,0 +1 @@
+class=org.apache.camel.component.openstack.keystone.KeystoneComponent

http://git-wip-us.apache.org/repos/asf/camel/blob/9f3d212a/components/camel-openstack/src/test/java/org/apache/camel/component/openstack/AbstractProducerTestSupport.java
----------------------------------------------------------------------
diff --git a/components/camel-openstack/src/test/java/org/apache/camel/component/openstack/AbstractProducerTestSupport.java b/components/camel-openstack/src/test/java/org/apache/camel/component/openstack/AbstractProducerTestSupport.java
index 9a8a3d3..e464c74 100644
--- a/components/camel-openstack/src/test/java/org/apache/camel/component/openstack/AbstractProducerTestSupport.java
+++ b/components/camel-openstack/src/test/java/org/apache/camel/component/openstack/AbstractProducerTestSupport.java
@@ -36,7 +36,7 @@ import java.io.IOException;
 public abstract class AbstractProducerTestSupport {
 
 	@Mock
-	protected OSClient client;
+	protected OSClient.OSClientV3 client;
 
 	@Mock
 	protected Exchange exchange;

http://git-wip-us.apache.org/repos/asf/camel/blob/9f3d212a/components/camel-openstack/src/test/java/org/apache/camel/component/openstack/keystone/DomainProducerTest.java
----------------------------------------------------------------------
diff --git a/components/camel-openstack/src/test/java/org/apache/camel/component/openstack/keystone/DomainProducerTest.java b/components/camel-openstack/src/test/java/org/apache/camel/component/openstack/keystone/DomainProducerTest.java
new file mode 100644
index 0000000..40c7879
--- /dev/null
+++ b/components/camel-openstack/src/test/java/org/apache/camel/component/openstack/keystone/DomainProducerTest.java
@@ -0,0 +1,169 @@
+/**
+ * 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.camel.component.openstack.keystone;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import org.apache.camel.component.openstack.keystone.producer.DomainProducer;
+import org.apache.camel.component.openstack.neutron.NeutronConstants;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.openstack4j.api.Builders;
+import org.openstack4j.model.common.ActionResponse;
+import org.openstack4j.model.identity.v3.Domain;
+import org.openstack4j.model.network.Network;
+import org.openstack4j.model.network.Router;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class DomainProducerTest extends KeystoneProducerTestSupport {
+
+	private Domain dummyDomain;
+
+	@Mock
+	private Domain testOSdomain;
+
+	@Before
+	public void setUp() {
+		producer = new DomainProducer(endpoint, client);
+		
+		when(domainService.create(any(Domain.class))).thenReturn(testOSdomain);
+		when(domainService.get(anyString())).thenReturn(testOSdomain);
+
+		List<Domain> getAllList = new ArrayList<>();
+		getAllList.add(testOSdomain);
+		getAllList.add(testOSdomain);
+		doReturn(getAllList).when(domainService).list();
+		
+		dummyDomain = createDomain();
+
+		when(testOSdomain.getName()).thenReturn(dummyDomain.getName());
+		when(testOSdomain.getDescription()).thenReturn(dummyDomain.getDescription());
+	}
+	
+	@Test
+	public void createTest() throws Exception {
+		msg.setHeader(KeystoneConstants.OPERATION, KeystoneConstants.CREATE);
+		msg.setHeader(KeystoneConstants.NAME, dummyDomain.getName());
+		msg.setHeader(KeystoneConstants.DESCRIPTION, dummyDomain.getDescription());
+
+
+		producer.process(exchange);
+
+		ArgumentCaptor<Domain> captor = ArgumentCaptor.forClass(Domain.class);
+		verify(domainService).create(captor.capture());
+
+		assertEqualsDomain(dummyDomain, captor.getValue());
+	}
+
+	@Test
+	public void getTest() throws Exception {
+		final String id = "id";
+		msg.setHeader(NeutronConstants.OPERATION, NeutronConstants.GET);
+		msg.setHeader(NeutronConstants.ID, id);
+
+		producer.process(exchange);
+
+		ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
+		verify(domainService).get(captor.capture());
+
+		assertEquals(id, captor.getValue());
+		assertEqualsDomain(testOSdomain, msg.getBody(Domain.class));
+	}
+
+	@Test
+	public void getAllTest() throws Exception {
+		msg.setHeader(NeutronConstants.OPERATION, NeutronConstants.GET_ALL);
+
+		producer.process(exchange);
+
+		final List<Network> result = msg.getBody(List.class);
+		assertTrue(result.size() == 2);
+		assertEquals(testOSdomain, result.get(0));
+	}
+
+	@Test
+	public void updateTest() throws Exception {
+		final String id = "myID";
+		msg.setHeader(KeystoneConstants.OPERATION, KeystoneConstants.UPDATE);
+		final String newName = "newName";
+
+		when(testOSdomain.getId()).thenReturn(id);
+		when(testOSdomain.getName()).thenReturn(newName);
+		when(testOSdomain.getDescription()).thenReturn("desc");
+
+		when(domainService.update(any(Domain.class))).thenReturn(testOSdomain);
+		msg.setBody(testOSdomain);
+
+		producer.process(exchange);
+
+		ArgumentCaptor<Domain> captor = ArgumentCaptor.forClass(Domain.class);
+		verify(domainService).update(captor.capture());
+
+		assertEqualsDomain(testOSdomain, captor.getValue());
+		assertNotNull(captor.getValue().getId());
+		assertEquals(newName, msg.getBody(Domain.class).getName());
+	}
+	
+	@Test
+	public void deleteTest() throws Exception {
+		when(domainService.delete(anyString())).thenReturn(ActionResponse.actionSuccess());
+		final String networkID = "myID";
+		msg.setHeader(NeutronConstants.OPERATION, NeutronConstants.DELETE);
+		msg.setHeader(NeutronConstants.ID, networkID);
+
+		producer.process(exchange);
+
+		ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
+		verify(domainService).delete(captor.capture());
+		assertEquals(networkID, captor.getValue());
+		assertFalse(msg.isFault());
+
+		//in case of failure
+		final String failureMessage = "fail";
+		when(domainService.delete(anyString())).thenReturn(ActionResponse.actionFailed(failureMessage, 404));
+		producer.process(exchange);
+		assertTrue(msg.isFault());
+		assertTrue(msg.getBody(String.class).contains(failureMessage));
+	}
+
+	private void assertEqualsDomain(Domain old, Domain newDomain) {
+		assertEquals(old.getName(), newDomain.getName());
+		assertEquals(old.getDescription(), newDomain.getDescription());
+	}
+
+	private Domain createDomain() {
+		return Builders.domain()
+				.description("desc")
+				.name("domain Name").build();
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/9f3d212a/components/camel-openstack/src/test/java/org/apache/camel/component/openstack/keystone/GroupProducerTest.java
----------------------------------------------------------------------
diff --git a/components/camel-openstack/src/test/java/org/apache/camel/component/openstack/keystone/GroupProducerTest.java b/components/camel-openstack/src/test/java/org/apache/camel/component/openstack/keystone/GroupProducerTest.java
new file mode 100644
index 0000000..e1aec6d
--- /dev/null
+++ b/components/camel-openstack/src/test/java/org/apache/camel/component/openstack/keystone/GroupProducerTest.java
@@ -0,0 +1,171 @@
+/**
+ * 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.camel.component.openstack.keystone;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import org.apache.camel.component.openstack.keystone.producer.GroupProducer;
+import org.apache.camel.component.openstack.neutron.NeutronConstants;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.openstack4j.api.Builders;
+import org.openstack4j.model.common.ActionResponse;
+import org.openstack4j.model.identity.v3.Group;
+import org.openstack4j.model.network.Network;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class GroupProducerTest extends KeystoneProducerTestSupport {
+
+	private Group dummyGroup;
+
+	@Mock
+	private Group testOSgroup;
+
+	@Before
+	public void setUp() {
+		producer = new GroupProducer(endpoint, client);
+		
+		when(groupService.create(any(Group.class))).thenReturn(testOSgroup);
+		when(groupService.get(anyString())).thenReturn(testOSgroup);
+
+		List<Group> getAllList = new ArrayList<>();
+		getAllList.add(testOSgroup);
+		getAllList.add(testOSgroup);
+		doReturn(getAllList).when(groupService).list();
+		
+		dummyGroup = createGroup();
+
+		when(testOSgroup.getName()).thenReturn(dummyGroup.getName());
+		when(testOSgroup.getDescription()).thenReturn(dummyGroup.getDescription());
+	}
+	
+	@Test
+	public void createTest() throws Exception {
+		msg.setHeader(KeystoneConstants.OPERATION, KeystoneConstants.CREATE);
+		msg.setHeader(KeystoneConstants.NAME, dummyGroup.getName());
+		msg.setHeader(KeystoneConstants.DESCRIPTION, dummyGroup.getDescription());
+		msg.setHeader(KeystoneConstants.DOMAIN_ID, dummyGroup.getDomainId());
+
+
+		producer.process(exchange);
+
+		ArgumentCaptor<Group> captor = ArgumentCaptor.forClass(Group.class);
+		verify(groupService).create(captor.capture());
+
+		assertEqualsGroup(dummyGroup, captor.getValue());
+	}
+
+	@Test
+	public void getTest() throws Exception {
+		final String id = "id";
+		msg.setHeader(NeutronConstants.OPERATION, NeutronConstants.GET);
+		msg.setHeader(NeutronConstants.ID, id);
+
+		producer.process(exchange);
+
+		ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
+		verify(groupService).get(captor.capture());
+
+		assertEquals(id, captor.getValue());
+		assertEqualsGroup(testOSgroup, msg.getBody(Group.class));
+	}
+
+	@Test
+	public void getAllTest() throws Exception {
+		msg.setHeader(NeutronConstants.OPERATION, NeutronConstants.GET_ALL);
+
+		producer.process(exchange);
+
+		final List<Network> result = msg.getBody(List.class);
+		assertTrue(result.size() == 2);
+		assertEquals(testOSgroup, result.get(0));
+	}
+
+	@Test
+	public void updateTest() throws Exception {
+		final String id = "myID";
+		msg.setHeader(KeystoneConstants.OPERATION, KeystoneConstants.UPDATE);
+		final String newName = "newName";
+
+		when(testOSgroup.getId()).thenReturn(id);
+		when(testOSgroup.getName()).thenReturn(newName);
+		when(testOSgroup.getDescription()).thenReturn("desc");
+
+		when(groupService.update(any(Group.class))).thenReturn(testOSgroup);
+		msg.setBody(testOSgroup);
+
+		producer.process(exchange);
+
+		ArgumentCaptor<Group> captor = ArgumentCaptor.forClass(Group.class);
+		verify(groupService).update(captor.capture());
+
+		assertEqualsGroup(testOSgroup, captor.getValue());
+		assertNotNull(captor.getValue().getId());
+		assertEquals(newName, msg.getBody(Group.class).getName());
+	}
+	
+	@Test
+	public void deleteTest() throws Exception {
+		when(groupService.delete(anyString())).thenReturn(ActionResponse.actionSuccess());
+		final String networkID = "myID";
+		msg.setHeader(NeutronConstants.OPERATION, NeutronConstants.DELETE);
+		msg.setHeader(NeutronConstants.ID, networkID);
+
+		producer.process(exchange);
+
+		ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
+		verify(groupService).delete(captor.capture());
+		assertEquals(networkID, captor.getValue());
+		assertFalse(msg.isFault());
+
+		//in case of failure
+		final String failureMessage = "fail";
+		when(groupService.delete(anyString())).thenReturn(ActionResponse.actionFailed(failureMessage, 404));
+		producer.process(exchange);
+		assertTrue(msg.isFault());
+		assertTrue(msg.getBody(String.class).contains(failureMessage));
+	}
+
+	private void assertEqualsGroup(Group old, Group newGroup) {
+		assertEquals(old.getName(), newGroup.getName());
+		assertEquals(old.getDescription(), newGroup.getDescription());
+		assertEquals(old.getDomainId(), newGroup.getDomainId());
+	}
+
+	private Group createGroup() {
+		return Builders.group()
+				.domainId("domain")
+				.description("desc")
+				.name("group Name").build();
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/9f3d212a/components/camel-openstack/src/test/java/org/apache/camel/component/openstack/keystone/KeystoneProducerTestSupport.java
----------------------------------------------------------------------
diff --git a/components/camel-openstack/src/test/java/org/apache/camel/component/openstack/keystone/KeystoneProducerTestSupport.java b/components/camel-openstack/src/test/java/org/apache/camel/component/openstack/keystone/KeystoneProducerTestSupport.java
new file mode 100644
index 0000000..02ba409
--- /dev/null
+++ b/components/camel-openstack/src/test/java/org/apache/camel/component/openstack/keystone/KeystoneProducerTestSupport.java
@@ -0,0 +1,65 @@
+/**
+ * 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.camel.component.openstack.keystone;
+
+import static org.mockito.Mockito.when;
+
+import org.apache.camel.component.openstack.AbstractProducerTestSupport;
+
+import org.junit.Before;
+
+import org.mockito.Mock;
+import org.openstack4j.api.identity.v3.DomainService;
+import org.openstack4j.api.identity.v3.GroupService;
+import org.openstack4j.api.identity.v3.IdentityService;
+import org.openstack4j.api.identity.v3.ProjectService;
+import org.openstack4j.api.identity.v3.RegionService;
+import org.openstack4j.api.identity.v3.UserService;
+
+public class KeystoneProducerTestSupport extends AbstractProducerTestSupport {
+
+	@Mock
+	protected KeystoneEndpoint endpoint;
+
+	@Mock
+	protected IdentityService identityService;
+
+	@Mock
+	protected DomainService domainService;
+
+	@Mock
+	protected GroupService groupService;
+
+	@Mock
+	protected ProjectService projectService;
+
+	@Mock
+	protected RegionService regionService;
+
+	@Mock
+	protected UserService userService;
+
+	@Before
+	public void setUpComputeService(){
+		when(client.identity()).thenReturn(identityService);
+		when(identityService.domains()).thenReturn(domainService);
+		when(identityService.groups()).thenReturn(groupService);
+		when(identityService.projects()).thenReturn(projectService);
+		when(identityService.regions()).thenReturn(regionService);
+		when(identityService.users()).thenReturn(userService);
+	}
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/9f3d212a/components/camel-openstack/src/test/java/org/apache/camel/component/openstack/keystone/ProjectProducerTest.java
----------------------------------------------------------------------
diff --git a/components/camel-openstack/src/test/java/org/apache/camel/component/openstack/keystone/ProjectProducerTest.java b/components/camel-openstack/src/test/java/org/apache/camel/component/openstack/keystone/ProjectProducerTest.java
new file mode 100644
index 0000000..206ac9f
--- /dev/null
+++ b/components/camel-openstack/src/test/java/org/apache/camel/component/openstack/keystone/ProjectProducerTest.java
@@ -0,0 +1,173 @@
+/**
+ * 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.camel.component.openstack.keystone;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import org.apache.camel.component.openstack.keystone.producer.ProjectProducer;
+import org.apache.camel.component.openstack.neutron.NeutronConstants;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.openstack4j.api.Builders;
+import org.openstack4j.model.common.ActionResponse;
+import org.openstack4j.model.identity.v3.Project;
+import org.openstack4j.model.network.Network;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ProjectProducerTest extends KeystoneProducerTestSupport {
+
+	private Project dummyProject;
+
+	@Mock
+	private Project testOSproject;
+
+	@Before
+	public void setUp() {
+		producer = new ProjectProducer(endpoint, client);
+		
+		when(projectService.create(any(Project.class))).thenReturn(testOSproject);
+		when(projectService.get(anyString())).thenReturn(testOSproject);
+
+		List<Project> getAllList = new ArrayList<>();
+		getAllList.add(testOSproject);
+		getAllList.add(testOSproject);
+		doReturn(getAllList).when(projectService).list();
+		
+		dummyProject = createProject();
+
+		when(testOSproject.getName()).thenReturn(dummyProject.getName());
+		when(testOSproject.getDescription()).thenReturn(dummyProject.getDescription());
+	}
+	
+	@Test
+	public void createTest() throws Exception {
+		msg.setHeader(KeystoneConstants.OPERATION, KeystoneConstants.CREATE);
+		msg.setHeader(KeystoneConstants.NAME, dummyProject.getName());
+		msg.setHeader(KeystoneConstants.DESCRIPTION, dummyProject.getDescription());
+		msg.setHeader(KeystoneConstants.DOMAIN_ID, dummyProject.getDomainId());
+		msg.setHeader(KeystoneConstants.PARENT_ID, dummyProject.getParentId());
+
+
+		producer.process(exchange);
+
+		ArgumentCaptor<Project> captor = ArgumentCaptor.forClass(Project.class);
+		verify(projectService).create(captor.capture());
+
+		assertEqualsProject(dummyProject, captor.getValue());
+	}
+
+	@Test
+	public void getTest() throws Exception {
+		final String id = "id";
+		msg.setHeader(NeutronConstants.OPERATION, NeutronConstants.GET);
+		msg.setHeader(NeutronConstants.ID, id);
+
+		producer.process(exchange);
+
+		ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
+		verify(projectService).get(captor.capture());
+
+		assertEquals(id, captor.getValue());
+		assertEqualsProject(testOSproject, msg.getBody(Project.class));
+	}
+
+	@Test
+	public void getAllTest() throws Exception {
+		msg.setHeader(NeutronConstants.OPERATION, NeutronConstants.GET_ALL);
+
+		producer.process(exchange);
+
+		final List<Network> result = msg.getBody(List.class);
+		assertTrue(result.size() == 2);
+		assertEquals(testOSproject, result.get(0));
+	}
+
+	@Test
+	public void updateTest() throws Exception {
+		final String id = "myID";
+		msg.setHeader(KeystoneConstants.OPERATION, KeystoneConstants.UPDATE);
+		final String newName = "newName";
+
+		when(testOSproject.getId()).thenReturn(id);
+		when(testOSproject.getName()).thenReturn(newName);
+		when(testOSproject.getDescription()).thenReturn("desc");
+
+		when(projectService.update(any(Project.class))).thenReturn(testOSproject);
+		msg.setBody(testOSproject);
+
+		producer.process(exchange);
+
+		ArgumentCaptor<Project> captor = ArgumentCaptor.forClass(Project.class);
+		verify(projectService).update(captor.capture());
+
+		assertEqualsProject(testOSproject, captor.getValue());
+		assertNotNull(captor.getValue().getId());
+		assertEquals(newName, msg.getBody(Project.class).getName());
+	}
+	
+	@Test
+	public void deleteTest() throws Exception {
+		when(projectService.delete(anyString())).thenReturn(ActionResponse.actionSuccess());
+		final String networkID = "myID";
+		msg.setHeader(NeutronConstants.OPERATION, NeutronConstants.DELETE);
+		msg.setHeader(NeutronConstants.ID, networkID);
+
+		producer.process(exchange);
+
+		ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
+		verify(projectService).delete(captor.capture());
+		assertEquals(networkID, captor.getValue());
+		assertFalse(msg.isFault());
+
+		//in case of failure
+		final String failureMessage = "fail";
+		when(projectService.delete(anyString())).thenReturn(ActionResponse.actionFailed(failureMessage, 404));
+		producer.process(exchange);
+		assertTrue(msg.isFault());
+		assertTrue(msg.getBody(String.class).contains(failureMessage));
+	}
+
+	private void assertEqualsProject(Project old, Project newProject) {
+		assertEquals(old.getName(), newProject.getName());
+		assertEquals(old.getDescription(), newProject.getDescription());
+		assertEquals(old.getDomainId(), newProject.getDomainId());
+	}
+
+	private Project createProject() {
+		return Builders.project()
+				.domainId("domain")
+				.description("desc")
+				.name("project Name")
+				.parentId("parent").build();
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/9f3d212a/components/camel-openstack/src/test/java/org/apache/camel/component/openstack/keystone/RegionProducerTest.java
----------------------------------------------------------------------
diff --git a/components/camel-openstack/src/test/java/org/apache/camel/component/openstack/keystone/RegionProducerTest.java b/components/camel-openstack/src/test/java/org/apache/camel/component/openstack/keystone/RegionProducerTest.java
new file mode 100644
index 0000000..332d02f
--- /dev/null
+++ b/components/camel-openstack/src/test/java/org/apache/camel/component/openstack/keystone/RegionProducerTest.java
@@ -0,0 +1,163 @@
+/**
+ * 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.camel.component.openstack.keystone;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import org.apache.camel.component.openstack.keystone.producer.RegionProducer;
+import org.apache.camel.component.openstack.neutron.NeutronConstants;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.openstack4j.api.Builders;
+import org.openstack4j.model.common.ActionResponse;
+import org.openstack4j.model.identity.v3.Region;
+import org.openstack4j.model.network.Network;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class RegionProducerTest extends KeystoneProducerTestSupport {
+
+	private Region dummyRegion;
+
+	@Mock
+	private Region testOSregion;
+
+	@Before
+	public void setUp() {
+		producer = new RegionProducer(endpoint, client);
+		
+		when(regionService.create(any(Region.class))).thenReturn(testOSregion);
+		when(regionService.get(anyString())).thenReturn(testOSregion);
+
+		List<Region> getAllList = new ArrayList<>();
+		getAllList.add(testOSregion);
+		getAllList.add(testOSregion);
+		doReturn(getAllList).when(regionService).list();
+		
+		dummyRegion = createRegion();
+
+		when(testOSregion.getDescription()).thenReturn(dummyRegion.getDescription());
+	}
+	
+	@Test
+	public void createTest() throws Exception {
+		msg.setHeader(KeystoneConstants.OPERATION, KeystoneConstants.CREATE);
+		msg.setHeader(KeystoneConstants.DESCRIPTION, dummyRegion.getDescription());
+
+		producer.process(exchange);
+
+		ArgumentCaptor<Region> captor = ArgumentCaptor.forClass(Region.class);
+		verify(regionService).create(captor.capture());
+
+		assertEqualsRegion(dummyRegion, captor.getValue());
+	}
+
+	@Test
+	public void getTest() throws Exception {
+		final String id = "id";
+		msg.setHeader(NeutronConstants.OPERATION, NeutronConstants.GET);
+		msg.setHeader(NeutronConstants.ID, id);
+
+		producer.process(exchange);
+
+		ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
+		verify(regionService).get(captor.capture());
+
+		assertEquals(id, captor.getValue());
+		assertEqualsRegion(testOSregion, msg.getBody(Region.class));
+	}
+
+	@Test
+	public void getAllTest() throws Exception {
+		msg.setHeader(NeutronConstants.OPERATION, NeutronConstants.GET_ALL);
+
+		producer.process(exchange);
+
+		final List<Network> result = msg.getBody(List.class);
+		assertTrue(result.size() == 2);
+		assertEquals(testOSregion, result.get(0));
+	}
+
+	@Test
+	public void updateTest() throws Exception {
+		final String id = "myID";
+		msg.setHeader(KeystoneConstants.OPERATION, KeystoneConstants.UPDATE);
+
+		when(testOSregion.getId()).thenReturn(id);
+		final String newDescription = "ndesc";
+		when(testOSregion.getDescription()).thenReturn(newDescription);
+
+		when(regionService.update(any(Region.class))).thenReturn(testOSregion);
+		msg.setBody(testOSregion);
+
+		producer.process(exchange);
+
+		ArgumentCaptor<Region> captor = ArgumentCaptor.forClass(Region.class);
+		verify(regionService).update(captor.capture());
+
+		assertEqualsRegion(testOSregion, captor.getValue());
+		assertNotNull(captor.getValue().getId());
+		assertEquals(newDescription, msg.getBody(Region.class).getDescription());
+	}
+	
+	@Test
+	public void deleteTest() throws Exception {
+		when(regionService.delete(anyString())).thenReturn(ActionResponse.actionSuccess());
+		final String networkID = "myID";
+		msg.setHeader(NeutronConstants.OPERATION, NeutronConstants.DELETE);
+		msg.setHeader(NeutronConstants.ID, networkID);
+
+		producer.process(exchange);
+
+		ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
+		verify(regionService).delete(captor.capture());
+		assertEquals(networkID, captor.getValue());
+		assertFalse(msg.isFault());
+
+		//in case of failure
+		final String failureMessage = "fail";
+		when(regionService.delete(anyString())).thenReturn(ActionResponse.actionFailed(failureMessage, 404));
+		producer.process(exchange);
+		assertTrue(msg.isFault());
+		assertTrue(msg.getBody(String.class).contains(failureMessage));
+	}
+
+	private void assertEqualsRegion(Region old, Region newRegion) {
+		assertEquals(old.getDescription(), newRegion.getDescription());
+	}
+
+	private Region createRegion() {
+		return Builders.region()
+				.description("desc")
+				.build();
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/9f3d212a/components/camel-openstack/src/test/java/org/apache/camel/component/openstack/keystone/UserProducerTest.java
----------------------------------------------------------------------
diff --git a/components/camel-openstack/src/test/java/org/apache/camel/component/openstack/keystone/UserProducerTest.java b/components/camel-openstack/src/test/java/org/apache/camel/component/openstack/keystone/UserProducerTest.java
new file mode 100644
index 0000000..a9315d0
--- /dev/null
+++ b/components/camel-openstack/src/test/java/org/apache/camel/component/openstack/keystone/UserProducerTest.java
@@ -0,0 +1,179 @@
+/**
+ * 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.camel.component.openstack.keystone;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import org.apache.camel.component.openstack.keystone.producer.UserProducer;
+import org.apache.camel.component.openstack.neutron.NeutronConstants;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.openstack4j.api.Builders;
+import org.openstack4j.model.common.ActionResponse;
+import org.openstack4j.model.identity.v3.User;
+import org.openstack4j.model.network.Network;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class UserProducerTest extends KeystoneProducerTestSupport {
+
+	private User dummyUser;
+
+	@Mock
+	private User testOSuser;
+
+	@Before
+	public void setUp() {
+		producer = new UserProducer(endpoint, client);
+		
+		when(userService.create(any(User.class))).thenReturn(testOSuser);
+		when(userService.get(anyString())).thenReturn(testOSuser);
+
+		List<User> getAllList = new ArrayList<>();
+		getAllList.add(testOSuser);
+		getAllList.add(testOSuser);
+		doReturn(getAllList).when(userService).list();
+		
+		dummyUser = createUser();
+
+		when(testOSuser.getName()).thenReturn(dummyUser.getName());
+		when(testOSuser.getDescription()).thenReturn(dummyUser.getDescription());
+		when(testOSuser.getPassword()).thenReturn(dummyUser.getPassword());
+		when(testOSuser.getDomainId()).thenReturn(dummyUser.getDomainId());
+		when(testOSuser.getEmail()).thenReturn(dummyUser.getEmail());
+	}
+	
+	@Test
+	public void createTest() throws Exception {
+		msg.setHeader(KeystoneConstants.OPERATION, KeystoneConstants.CREATE);
+		msg.setHeader(KeystoneConstants.NAME, dummyUser.getName());
+		msg.setHeader(KeystoneConstants.DESCRIPTION, dummyUser.getDescription());
+		msg.setHeader(KeystoneConstants.DOMAIN_ID, dummyUser.getDomainId());
+		msg.setHeader(KeystoneConstants.PASSWORD, dummyUser.getPassword());
+		msg.setHeader(KeystoneConstants.EMAIL, dummyUser.getEmail());
+
+		producer.process(exchange);
+
+		ArgumentCaptor<User> captor = ArgumentCaptor.forClass(User.class);
+		verify(userService).create(captor.capture());
+
+		assertEqualsUser(dummyUser, captor.getValue());
+	}
+
+	@Test
+	public void getTest() throws Exception {
+		final String id = "id";
+		msg.setHeader(NeutronConstants.OPERATION, NeutronConstants.GET);
+		msg.setHeader(NeutronConstants.ID, id);
+
+		producer.process(exchange);
+
+		ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
+		verify(userService).get(captor.capture());
+
+		assertEquals(id, captor.getValue());
+		assertEqualsUser(testOSuser, msg.getBody(User.class));
+	}
+
+	@Test
+	public void getAllTest() throws Exception {
+		msg.setHeader(NeutronConstants.OPERATION, NeutronConstants.GET_ALL);
+
+		producer.process(exchange);
+
+		final List<Network> result = msg.getBody(List.class);
+		assertTrue(result.size() == 2);
+		assertEquals(testOSuser, result.get(0));
+	}
+
+	@Test
+	public void updateTest() throws Exception {
+		final String id = "myID";
+		msg.setHeader(KeystoneConstants.OPERATION, KeystoneConstants.UPDATE);
+
+		when(testOSuser.getId()).thenReturn(id);
+		final String newDescription = "ndesc";
+		when(testOSuser.getDescription()).thenReturn(newDescription);
+
+		when(userService.update(any(User.class))).thenReturn(testOSuser);
+		msg.setBody(testOSuser);
+
+		producer.process(exchange);
+
+		ArgumentCaptor<User> captor = ArgumentCaptor.forClass(User.class);
+		verify(userService).update(captor.capture());
+
+		assertEqualsUser(testOSuser, captor.getValue());
+		assertNotNull(captor.getValue().getId());
+		assertEquals(newDescription, msg.getBody(User.class).getDescription());
+	}
+	
+	@Test
+	public void deleteTest() throws Exception {
+		when(userService.delete(anyString())).thenReturn(ActionResponse.actionSuccess());
+		final String networkID = "myID";
+		msg.setHeader(NeutronConstants.OPERATION, NeutronConstants.DELETE);
+		msg.setHeader(NeutronConstants.ID, networkID);
+
+		producer.process(exchange);
+
+		ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
+		verify(userService).delete(captor.capture());
+		assertEquals(networkID, captor.getValue());
+		assertFalse(msg.isFault());
+
+		//in case of failure
+		final String failureMessage = "fail";
+		when(userService.delete(anyString())).thenReturn(ActionResponse.actionFailed(failureMessage, 404));
+		producer.process(exchange);
+		assertTrue(msg.isFault());
+		assertTrue(msg.getBody(String.class).contains(failureMessage));
+	}
+
+	private void assertEqualsUser(User old, User newUser) {
+		assertEquals(old.getName(), newUser.getName());
+		assertEquals(old.getDomainId(), newUser.getDomainId());
+		assertEquals(old.getPassword(), newUser.getPassword());
+		assertEquals(old.getDescription(), newUser.getDescription());
+		assertEquals(old.getEmail(), newUser.getEmail());
+	}
+
+	private User createUser() {
+		return Builders.user()
+				.name("User name")
+				.domainId("domainId")
+				.password("password")
+				.description("desc")
+				.email("email@mail.com")
+				.build();
+	}
+
+}