diff --git a/src/main/java/org/springframework/data/couchbase/config/BeanNames.java b/src/main/java/org/springframework/data/couchbase/config/BeanNames.java
new file mode 100644
index 00000000..942d8e50
--- /dev/null
+++ b/src/main/java/org/springframework/data/couchbase/config/BeanNames.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2012-2015 the original author or authors
+ *
+ * Licensed 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.springframework.data.couchbase.config;
+
+/**
+ * Contains default bean names that will be used when no "id" is supplied to the beans.
+ *
+ * @author Michael Nitschinger
+ * @author Simon Baslé
+ */
+public class BeanNames {
+
+ /**
+ * Refers to the "" bean.
+ */
+ static final String COUCHBASE_CLUSTER = "cluster";
+
+ /**
+ * Refers to the "" bean.
+ */
+ static final String COUCHBASE_BUCKET = "bucket";
+
+ /**
+ * Refers to the "" bean.
+ */
+ static final String COUCHBASE_TEMPLATE = "couchbaseTemplate";
+
+ /**
+ * Refers to the "" bean
+ */
+ static final String TRANSLATION_SERVICE = "translationService";
+
+}
diff --git a/src/main/java/org/springframework/data/couchbase/config/CouchbaseJmxParser.java b/src/main/java/org/springframework/data/couchbase/config/CouchbaseJmxParser.java
new file mode 100644
index 00000000..22c2969d
--- /dev/null
+++ b/src/main/java/org/springframework/data/couchbase/config/CouchbaseJmxParser.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2012-2015 the original author or authors
+ *
+ * Licensed 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.springframework.data.couchbase.config;
+
+import com.couchbase.client.java.Bucket;
+import org.w3c.dom.Element;
+
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.parsing.BeanComponentDefinition;
+import org.springframework.beans.factory.parsing.CompositeComponentDefinition;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.xml.BeanDefinitionParser;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.springframework.data.couchbase.monitor.ClientInfo;
+import org.springframework.data.couchbase.monitor.ClusterInfo;
+import org.springframework.util.StringUtils;
+
+/**
+ * Enables Parsing of the "" configuration bean.
+ *
+ * In order to enable JMX, different JmxComponents need to be registered. The dependency to the original
+ * {@link Bucket} object is solved through the "bucket-ref" attribute.
+ *
+ * @author Michael Nitschinger
+ * @author Simon Baslé
+ */
+public class CouchbaseJmxParser implements BeanDefinitionParser {
+
+ /**
+ * Parse the element and dispatch the registration of the JMX components.
+ *
+ * @param element the XML element which contains the attributes.
+ * @param parserContext encapsulates the parsing state and configuration.
+ * @return null, because no bean instance needs to be returned.
+ */
+ public BeanDefinition parse(final Element element, final ParserContext parserContext) {
+ String bucketName = element.getAttribute("bucket-ref");
+ if (!StringUtils.hasText(bucketName)) {
+ bucketName = BeanNames.COUCHBASE_BUCKET;
+ }
+ registerJmxComponents(bucketName, element, parserContext);
+ return null;
+ }
+
+ /**
+ * Register the JMX components in the context.
+ *
+ * @param element the XML element which contains the attributes.
+ * @param parserContext encapsulates the parsing state and configuration.
+ * @parma refBucketName the reference name to the couchbase bucket.
+ */
+ protected void registerJmxComponents(final String refBucketName,
+ final Element element, final ParserContext parserContext) {
+ Object eleSource = parserContext.extractSource(element);
+ CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), eleSource);
+
+ createBeanDefEntry(ClientInfo.class, compositeDef, refBucketName, eleSource, parserContext);
+ createBeanDefEntry(ClusterInfo.class, compositeDef, refBucketName, eleSource, parserContext);
+
+ parserContext.registerComponent(compositeDef);
+ }
+
+ /**
+ * Creates Bean Definitions for JMX components and adds them as a nested component.
+ *
+ * @param clazz the class type to register.
+ * @param compositeDef component that can hold nested components.
+ * @param refName the reference name to the couchbase client.
+ * @param eleSource source element to reference.
+ * @param parserContext encapsulates the parsing state and configuration.
+ */
+ protected void createBeanDefEntry(final Class> clazz, final CompositeComponentDefinition compositeDef,
+ final String refName, final Object eleSource, final ParserContext parserContext) {
+ BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(clazz);
+ builder.getRawBeanDefinition().setSource(eleSource);
+ builder.addConstructorArgReference(refName);
+ BeanDefinition assertDef = builder.getBeanDefinition();
+ String assertName = parserContext.getReaderContext().registerWithGeneratedName(assertDef);
+ compositeDef.addNestedComponent(new BeanComponentDefinition(assertDef, assertName));
+ }
+
+}
diff --git a/src/main/java/org/springframework/data/couchbase/config/CouchbaseNamespaceHandler.java b/src/main/java/org/springframework/data/couchbase/config/CouchbaseNamespaceHandler.java
new file mode 100644
index 00000000..6e4d50d6
--- /dev/null
+++ b/src/main/java/org/springframework/data/couchbase/config/CouchbaseNamespaceHandler.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2012-2015 the original author or authors
+ *
+ * Licensed 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.springframework.data.couchbase.config;
+
+import org.springframework.beans.factory.xml.NamespaceHandler;
+import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
+
+/**
+ * {@link NamespaceHandler} for Couchbase configuration.
+ *
+ * This handler acts as a container for one or more bean parsers and registers them. During parsing, the elements
+ * get analyzed and the appropriate registered parser is called.
+ *
+ * @author Michael Nitschinger
+ */
+public class CouchbaseNamespaceHandler extends NamespaceHandlerSupport {
+
+ /**
+ * Register bean definition parsers in the namespace handler.
+ */
+ public final void init() {
+ //TODO repositories (CouchbaseRepositoryConfigurationExtension and RepositoryBeanDefinitionParser)
+ //TODO bucket
+ //TODO cluster
+ registerBeanDefinitionParser("jmx", new CouchbaseJmxParser());
+ registerBeanDefinitionParser("template", new CouchbaseTemplateParser());
+ //TODO translation service
+ }
+
+}
diff --git a/src/main/java/org/springframework/data/couchbase/config/CouchbaseTemplateParser.java b/src/main/java/org/springframework/data/couchbase/config/CouchbaseTemplateParser.java
new file mode 100644
index 00000000..c4b0de93
--- /dev/null
+++ b/src/main/java/org/springframework/data/couchbase/config/CouchbaseTemplateParser.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2012-2015 the original author or authors
+ *
+ * Licensed 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.springframework.data.couchbase.config;
+
+import org.w3c.dom.Element;
+
+import org.springframework.beans.factory.support.AbstractBeanDefinition;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.springframework.data.couchbase.core.CouchbaseTemplate;
+import org.springframework.util.StringUtils;
+
+/**
+ * Parser for "" bean definitions.
+ *
+ * The outcome of this bean definition parser will be a constructed {@link CouchbaseTemplate}.
+ *
+ * @author Michael Nitschinger
+ */
+public class CouchbaseTemplateParser extends AbstractSingleBeanDefinitionParser {
+
+ /**
+ * Resolve the bean ID and assign a default if not set.
+ *
+ * @param element the XML element which contains the attributes.
+ * @param definition the bean definition to work with.
+ * @param parserContext encapsulates the parsing state and configuration.
+ * @return the ID to work with.
+ */
+ @Override
+ protected String resolveId(final Element element, final AbstractBeanDefinition definition, final ParserContext parserContext) {
+ String id = super.resolveId(element, definition, parserContext);
+ return StringUtils.hasText(id) ? id : BeanNames.COUCHBASE_TEMPLATE;
+ }
+
+ /**
+ * Defines the bean class that will be constructed.
+ *
+ * @param element the XML element which contains the attributes.
+ * @return the class type to instantiate.
+ */
+ @Override
+ protected Class getBeanClass(final Element element) {
+ return CouchbaseTemplate.class;
+ }
+
+ /**
+ * Parse the bean definition and build up the bean.
+ *
+ * @param element the XML element which contains the attributes.
+ * @param bean the builder which builds the bean.
+ */
+ @Override
+ protected void doParse(final Element element, final BeanDefinitionBuilder bean) {
+ String bucketRef = element.getAttribute("bucket-ref");
+ String converterRef = element.getAttribute("converter-ref");
+ String translationServiceRef = element.getAttribute("translation-service-ref");
+
+ bean.addConstructorArgReference(StringUtils.hasText(bucketRef) ? bucketRef : BeanNames.COUCHBASE_BUCKET);
+
+ if (StringUtils.hasText(converterRef)) {
+ bean.addConstructorArgReference(converterRef);
+ }
+
+ if (StringUtils.hasText(translationServiceRef)) {
+ bean.addConstructorArgReference(translationServiceRef);
+ }
+ }
+
+}
diff --git a/src/main/java/org/springframework/data/couchbase/monitor/ClientInfo.java b/src/main/java/org/springframework/data/couchbase/monitor/ClientInfo.java
new file mode 100644
index 00000000..a5bc7eb0
--- /dev/null
+++ b/src/main/java/org/springframework/data/couchbase/monitor/ClientInfo.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2012-2015 the original author or authors
+ *
+ * Licensed 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.springframework.data.couchbase.monitor;
+
+import java.net.InetAddress;
+
+import com.couchbase.client.java.Bucket;
+import com.couchbase.client.java.bucket.BucketInfo;
+
+import org.springframework.jmx.export.annotation.ManagedAttribute;
+import org.springframework.jmx.export.annotation.ManagedResource;
+
+/**
+ * Exposes basic client information.
+ *
+ * @author Michael Nitschinger
+ * @author Simon Baslé
+ */
+@ManagedResource(description = "Client Information")
+public class ClientInfo {
+
+ private final Bucket bucket;
+ private final BucketInfo info;
+
+ public ClientInfo(final Bucket bucket) {
+ this.bucket = bucket;
+ this.info = bucket.bucketManager().info();
+ }
+
+ @ManagedAttribute(description = "Hostnames of connected nodes")
+ public String getHostNames() {
+ StringBuilder result = new StringBuilder();
+ for (InetAddress node : info.nodeList()) {
+ result.append(node.toString()).append(",");
+ }
+ return result.toString();
+ }
+
+ @ManagedAttribute(description = "Number of connected nodes")
+ public int getNumberOfNodes() {
+ return info.nodeCount();
+ }
+
+ //TODO obtain count of available nodes vs unavailable ones and expose it
+
+}
diff --git a/src/main/java/org/springframework/data/couchbase/monitor/ClusterInfo.java b/src/main/java/org/springframework/data/couchbase/monitor/ClusterInfo.java
new file mode 100644
index 00000000..094c26e5
--- /dev/null
+++ b/src/main/java/org/springframework/data/couchbase/monitor/ClusterInfo.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2012-2015 the original author or authors
+ *
+ * Licensed 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.springframework.data.couchbase.monitor;
+
+import java.net.InetAddress;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+
+import com.couchbase.client.java.Bucket;
+import com.couchbase.client.java.bucket.BucketInfo;
+
+import org.springframework.jmx.export.annotation.ManagedAttribute;
+import org.springframework.jmx.export.annotation.ManagedMetric;
+import org.springframework.jmx.export.annotation.ManagedResource;
+import org.springframework.web.client.RestTemplate;
+
+/**
+ * Exposes basic cluster information.
+ *
+ * @author Michael Nitschinger
+ * @author Simon Baslé
+ */
+@ManagedResource(description = "Cluster Information")
+public class ClusterInfo {
+
+ private final RestTemplate template;
+ private final Bucket bucket;
+ private final BucketInfo info;
+
+ public ClusterInfo(final Bucket bucket) {
+ this.template = new RestTemplate();
+ this.bucket = bucket;
+ this.info = bucket.bucketManager().info();
+ }
+
+ @ManagedMetric(description = "Total RAM assigned")
+ public long getTotalRAMAssigned() {
+ return convertPotentialLong(parseStorageTotals().get("ram").get("total"));
+ }
+
+ @ManagedMetric(description = "Total RAM used")
+ public long getTotalRAMUsed() {
+ return convertPotentialLong(parseStorageTotals().get("ram").get("used"));
+ }
+
+ @ManagedMetric(description = "Total Disk Space assigned")
+ public long getTotalDiskAssigned() {
+ return convertPotentialLong(parseStorageTotals().get("hdd").get("total"));
+ }
+
+ @ManagedMetric(description = "Total Disk Space used")
+ public long getTotalDiskUsed() {
+ return convertPotentialLong(parseStorageTotals().get("hdd").get("used"));
+ }
+
+ @ManagedMetric(description = "Total Disk Space free")
+ public long getTotalDiskFree() {
+ return convertPotentialLong(parseStorageTotals().get("hdd").get("free"));
+ }
+
+ @ManagedAttribute(description = "Cluster is Balanced")
+ public boolean getIsBalanced() {
+ return (Boolean) fetchPoolInfo().get("balanced");
+ }
+
+ @ManagedAttribute(description = "Rebalance Status")
+ public String getRebalanceStatus() {
+ return (String) fetchPoolInfo().get("rebalanceStatus");
+ }
+
+ @ManagedAttribute(description = "Maximum Available Buckets")
+ public int getMaxBuckets() {
+ return (Integer) fetchPoolInfo().get("maxBucketCount");
+ }
+
+ /**
+ * Depending on the value size, either int or long can be passed in and get
+ * converted to long.
+ *
+ * @param value the value to convert.
+ * @return the converted value.
+ */
+ private long convertPotentialLong(Object value) {
+ if (value instanceof Integer) {
+ return new Long((Integer) value);
+ }
+ else if (value instanceof Long) {
+ return (Long) value;
+ }
+ else {
+ throw new IllegalStateException("Cannot convert value to long: " + value);
+ }
+ }
+
+ protected String randomAvailableHostname() {
+ List available = info.nodeList();
+ Collections.shuffle(available);
+ return available.get(0).getHostName();
+ }
+
+ private HashMap fetchPoolInfo() {
+ return template.getForObject("http://"
+ + randomAvailableHostname() + ":8091/pools/default", HashMap.class);
+ }
+
+ private HashMap parseStorageTotals() {
+ HashMap stats = fetchPoolInfo();
+ return (HashMap) stats.get("storageTotals");
+ }
+
+}