001/* 002 * Copyright 2012-2017 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.boot.autoconfigure.couchbase; 018 019import com.couchbase.client.java.Bucket; 020import com.couchbase.client.java.Cluster; 021import com.couchbase.client.java.CouchbaseBucket; 022import com.couchbase.client.java.CouchbaseCluster; 023import com.couchbase.client.java.cluster.ClusterInfo; 024import com.couchbase.client.java.env.DefaultCouchbaseEnvironment; 025 026import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 027import org.springframework.boot.autoconfigure.condition.AnyNestedCondition; 028import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; 029import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 030import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 031import org.springframework.boot.context.properties.EnableConfigurationProperties; 032import org.springframework.context.annotation.Bean; 033import org.springframework.context.annotation.Conditional; 034import org.springframework.context.annotation.Configuration; 035import org.springframework.context.annotation.DependsOn; 036import org.springframework.context.annotation.Primary; 037 038/** 039 * {@link EnableAutoConfiguration Auto-Configuration} for Couchbase. 040 * 041 * @author Eddú Meléndez 042 * @author Stephane Nicoll 043 * @since 1.4.0 044 */ 045@Configuration 046@ConditionalOnClass({ CouchbaseBucket.class, Cluster.class }) 047@Conditional(CouchbaseAutoConfiguration.CouchbaseCondition.class) 048@EnableConfigurationProperties(CouchbaseProperties.class) 049public class CouchbaseAutoConfiguration { 050 051 @Configuration 052 @ConditionalOnMissingBean(value = CouchbaseConfiguration.class, type = "org.springframework.data.couchbase.config.CouchbaseConfigurer") 053 public static class CouchbaseConfiguration { 054 055 private final CouchbaseProperties properties; 056 057 public CouchbaseConfiguration(CouchbaseProperties properties) { 058 this.properties = properties; 059 } 060 061 @Bean 062 @Primary 063 public DefaultCouchbaseEnvironment couchbaseEnvironment() throws Exception { 064 return initializeEnvironmentBuilder(this.properties).build(); 065 } 066 067 @Bean 068 @Primary 069 public Cluster couchbaseCluster() throws Exception { 070 return CouchbaseCluster.create(couchbaseEnvironment(), 071 this.properties.getBootstrapHosts()); 072 } 073 074 @Bean 075 @Primary 076 @DependsOn("couchbaseClient") 077 public ClusterInfo couchbaseClusterInfo() throws Exception { 078 return couchbaseCluster() 079 .clusterManager(this.properties.getBucket().getName(), 080 this.properties.getBucket().getPassword()) 081 .info(); 082 } 083 084 @Bean 085 @Primary 086 public Bucket couchbaseClient() throws Exception { 087 return couchbaseCluster().openBucket(this.properties.getBucket().getName(), 088 this.properties.getBucket().getPassword()); 089 } 090 091 /** 092 * Initialize an environment builder based on the specified settings. 093 * @param properties the couchbase properties to use 094 * @return the {@link DefaultCouchbaseEnvironment} builder. 095 */ 096 protected DefaultCouchbaseEnvironment.Builder initializeEnvironmentBuilder( 097 CouchbaseProperties properties) { 098 CouchbaseProperties.Endpoints endpoints = properties.getEnv().getEndpoints(); 099 CouchbaseProperties.Timeouts timeouts = properties.getEnv().getTimeouts(); 100 DefaultCouchbaseEnvironment.Builder builder = DefaultCouchbaseEnvironment 101 .builder().connectTimeout(timeouts.getConnect()) 102 .kvEndpoints(endpoints.getKeyValue()) 103 .kvTimeout(timeouts.getKeyValue()) 104 .queryEndpoints(endpoints.getQuery()) 105 .queryTimeout(timeouts.getQuery()).viewEndpoints(endpoints.getView()) 106 .socketConnectTimeout(timeouts.getSocketConnect()) 107 .viewTimeout(timeouts.getView()); 108 CouchbaseProperties.Ssl ssl = properties.getEnv().getSsl(); 109 if (ssl.getEnabled()) { 110 builder.sslEnabled(true); 111 if (ssl.getKeyStore() != null) { 112 builder.sslKeystoreFile(ssl.getKeyStore()); 113 } 114 if (ssl.getKeyStorePassword() != null) { 115 builder.sslKeystorePassword(ssl.getKeyStorePassword()); 116 } 117 } 118 return builder; 119 } 120 121 } 122 123 /** 124 * Determine if Couchbase should be configured. This happens if either the 125 * user-configuration defines a {@code CouchbaseConfigurer} or if at least the 126 * "bootstrapHosts" property is specified. 127 * <p> 128 * The reason why we check for the presence of {@code CouchbaseConfigurer} is that it 129 * might use {@link CouchbaseProperties} for its internal customization. 130 */ 131 static class CouchbaseCondition extends AnyNestedCondition { 132 133 CouchbaseCondition() { 134 super(ConfigurationPhase.REGISTER_BEAN); 135 } 136 137 @Conditional(OnBootstrapHostsCondition.class) 138 static class BootstrapHostsProperty { 139 140 } 141 142 @ConditionalOnBean(type = "org.springframework.data.couchbase.config.CouchbaseConfigurer") 143 static class CouchbaseConfigurerAvailable { 144 145 } 146 147 } 148 149}