]> source.dussan.org Git - archiva.git/blob
8ebfc2d293f529d4f3706c84290c826e51e665b8
[archiva.git] /
1 package org.apache.archiva.metadata.repository.cassandra;
2
3 /*
4  * Licensed to the Apache Software Foundation (ASF) under one
5  * or more contributor license agreements.  See the NOTICE file
6  * distributed with this work for additional information
7  * regarding copyright ownership.  The ASF licenses this file
8  * to you under the Apache License, Version 2.0 (the
9  * "License"); you may not use this file except in compliance
10  * with the License.  You may obtain a copy of the License at
11  *
12  *  http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing,
15  * software distributed under the License is distributed on an
16  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17  * KIND, either express or implied.  See the License for the
18  * specific language governing permissions and limitations
19  * under the License.
20  */
21
22 import com.google.common.collect.ImmutableMap;
23 import com.netflix.astyanax.AstyanaxContext;
24 import com.netflix.astyanax.Keyspace;
25 import com.netflix.astyanax.connectionpool.NodeDiscoveryType;
26 import com.netflix.astyanax.connectionpool.exceptions.ConnectionException;
27 import com.netflix.astyanax.connectionpool.exceptions.NotFoundException;
28 import com.netflix.astyanax.connectionpool.impl.ConnectionPoolConfigurationImpl;
29 import com.netflix.astyanax.connectionpool.impl.ConnectionPoolType;
30 import com.netflix.astyanax.connectionpool.impl.Slf4jConnectionPoolMonitorImpl;
31 import com.netflix.astyanax.ddl.KeyspaceDefinition;
32 import com.netflix.astyanax.entitystore.DefaultEntityManager;
33 import com.netflix.astyanax.entitystore.EntityManager;
34 import com.netflix.astyanax.impl.AstyanaxConfigurationImpl;
35 import com.netflix.astyanax.thrift.ThriftFamilyFactory;
36 import org.apache.archiva.metadata.repository.cassandra.model.ArtifactMetadataModel;
37 import org.apache.archiva.metadata.repository.cassandra.model.MetadataFacetModel;
38 import org.apache.archiva.metadata.repository.cassandra.model.Namespace;
39 import org.apache.archiva.metadata.repository.cassandra.model.Project;
40 import org.apache.archiva.metadata.repository.cassandra.model.ProjectVersionMetadataModel;
41 import org.apache.archiva.metadata.repository.cassandra.model.Repository;
42 import org.slf4j.Logger;
43 import org.slf4j.LoggerFactory;
44 import org.springframework.context.ApplicationContext;
45 import org.springframework.stereotype.Service;
46
47 import javax.annotation.PostConstruct;
48 import javax.annotation.PreDestroy;
49 import javax.inject.Inject;
50 import javax.persistence.PersistenceException;
51 import java.util.Properties;
52
53 /**
54  * FIXME make all configuration not hardcoded :-)
55  *
56  * @author Olivier Lamy
57  * @since 2.0.0
58  */
59 @Service( "archivaEntityManagerFactory#cassandra" )
60 public class DefaultCassandraEntityManagerFactory
61     implements CassandraEntityManagerFactory
62 {
63
64     private Logger logger = LoggerFactory.getLogger( getClass() );
65
66     @Inject
67     private ApplicationContext applicationContext;
68
69     private static final String CLUSTER_NAME = "archiva";
70
71     private static final String KEYSPACE_NAME = "ArchivaKeySpace";
72
73     private AstyanaxContext<Keyspace> keyspaceContext;
74
75     private Keyspace keyspace;
76
77     private boolean started = false;
78
79     private EntityManager<Repository, String> repositoryEntityManager;
80
81     private EntityManager<Namespace, String> namespaceEntityManager;
82
83     private EntityManager<Project, String> projectEntityManager;
84
85     private EntityManager<ArtifactMetadataModel, String> artifactMetadataModelEntityManager;
86
87     private EntityManager<MetadataFacetModel, String> metadataFacetModelEntityManager;
88
89     private EntityManager<ProjectVersionMetadataModel, String> projectVersionMetadataModelEntityManager;
90
91
92     @PostConstruct
93     public void initialize()
94         throws ConnectionException
95     {
96         String cassandraHost = System.getProperty( "cassandraHost", "localhost" );
97         String cassandraPort = System.getProperty( "cassandraPort" );
98         keyspaceContext = new AstyanaxContext.Builder().forCluster( CLUSTER_NAME ).forKeyspace(
99             KEYSPACE_NAME ).withAstyanaxConfiguration(
100             new AstyanaxConfigurationImpl().setDiscoveryType( NodeDiscoveryType.RING_DESCRIBE ).setConnectionPoolType(
101                 ConnectionPoolType.TOKEN_AWARE ) ).withConnectionPoolConfiguration(
102             new ConnectionPoolConfigurationImpl( CLUSTER_NAME + "_" + KEYSPACE_NAME ).setSocketTimeout(
103                 30000 ).setMaxTimeoutWhenExhausted( 2000 ).setMaxConnsPerHost( 20 ).setInitConnsPerHost( 10 ).setSeeds(
104                 cassandraHost + ":" + cassandraPort ) ).withConnectionPoolMonitor(
105             new Slf4jConnectionPoolMonitorImpl() ).buildKeyspace( ThriftFamilyFactory.getInstance() );
106
107         this.start();
108
109         keyspace = keyspaceContext.getClient();
110         //Partitioner partitioner = keyspace.getPartitioner();
111
112         ImmutableMap<String, Object> options = ImmutableMap.<String, Object>builder().put( "strategy_options",
113                                                                                            ImmutableMap.<String, Object>builder().put(
114                                                                                                "replication_factor",
115                                                                                                "1" ).build() ).put(
116             "strategy_class", "SimpleStrategy" ).build();
117
118         // test if the namespace already exists if exception or null create it
119         boolean keyspaceExists = false;
120         try
121         {
122             KeyspaceDefinition keyspaceDefinition = keyspace.describeKeyspace();
123             if ( keyspaceDefinition != null )
124             {
125                 keyspaceExists = true;
126             }
127
128         }
129         catch ( ConnectionException e )
130         {
131         }
132
133         if ( !keyspaceExists )
134         {
135             keyspace.createKeyspace( options );
136         }
137
138         try
139         {
140             Properties properties = keyspace.getKeyspaceProperties();
141             logger.info( "keyspace properties: {}", properties );
142         }
143         catch ( ConnectionException e )
144         {
145             // FIXME better logging !
146             logger.warn( e.getMessage(), e );
147         }
148
149         try
150         {
151             repositoryEntityManager =
152                 new DefaultEntityManager.Builder<Repository, String>().withEntityType( Repository.class ).withKeyspace(
153                     keyspace ).withAutoCommit( true ).build();
154             boolean exists = columnFamilyExists( "repository" );
155             // TODO very basic test we must test model change too
156             if ( !exists )
157             {
158                 repositoryEntityManager.createStorage( null );
159             }
160
161             namespaceEntityManager =
162                 new DefaultEntityManager.Builder<Namespace, String>().withEntityType( Namespace.class ).withKeyspace(
163                     keyspace ).withAutoCommit( true ).build();
164
165             exists = columnFamilyExists( "namespace" );
166             if ( !exists )
167             {
168                 namespaceEntityManager.createStorage( null );
169             }
170
171             projectEntityManager =
172                 new DefaultEntityManager.Builder<Project, String>().withEntityType( Project.class ).withKeyspace(
173                     keyspace ).withAutoCommit( true ).build();
174
175             exists = columnFamilyExists( "project" );
176             if ( !exists )
177             {
178                 projectEntityManager.createStorage( null );
179             }
180
181             artifactMetadataModelEntityManager =
182                 new DefaultEntityManager.Builder<ArtifactMetadataModel, String>().withEntityType(
183                     ArtifactMetadataModel.class ).withAutoCommit( true ).withKeyspace( keyspace ).build();
184
185             exists = columnFamilyExists( "artifactmetadatamodel" );
186             if ( !exists )
187             {
188                 artifactMetadataModelEntityManager.createStorage( null );
189             }
190
191             metadataFacetModelEntityManager =
192                 new DefaultEntityManager.Builder<MetadataFacetModel, String>().withEntityType(
193                     MetadataFacetModel.class ).withAutoCommit( true ).withKeyspace( keyspace ).build();
194
195             exists = columnFamilyExists( "metadatafacetmodel" );
196             if ( !exists )
197             {
198                 metadataFacetModelEntityManager.createStorage( null );
199             }
200
201             projectVersionMetadataModelEntityManager =
202                 new DefaultEntityManager.Builder<ProjectVersionMetadataModel, String>().withEntityType(
203                     ProjectVersionMetadataModel.class ).withAutoCommit( true ).withKeyspace( keyspace ).build();
204
205             exists = columnFamilyExists( "projectversionmetadatamodel" );
206             if ( !exists )
207             {
208                 projectVersionMetadataModelEntityManager.createStorage( null );
209             }
210
211         }
212         catch ( PersistenceException e )
213         {
214             // FIXME report exception
215             logger.error( e.getMessage(), e );
216         }
217         catch ( ConnectionException e )
218         {
219             // FIXME report exception
220             logger.error( e.getMessage(), e );
221         }
222     }
223
224     public void start()
225     {
226         keyspaceContext.start();
227         started = true;
228     }
229
230     @PreDestroy
231     public void shutdown()
232     {
233         if ( keyspaceContext != null )
234         {
235             keyspaceContext.shutdown();
236             started = false;
237         }
238     }
239
240
241     @Override
242     public boolean started()
243     {
244         return started;
245     }
246
247     private boolean columnFamilyExists( String columnFamilyName )
248         throws ConnectionException
249     {
250         try
251         {
252             Properties properties = keyspace.getColumnFamilyProperties( columnFamilyName );
253             logger.debug( "getColumnFamilyProperties for {}: {}", columnFamilyName, properties );
254             return true;
255         }
256         catch ( NotFoundException e )
257         {
258             return false;
259         }
260     }
261
262
263     @Override
264     public Keyspace getKeyspace()
265     {
266         return keyspace;
267     }
268
269     public EntityManager<Repository, String> getRepositoryEntityManager()
270     {
271         return repositoryEntityManager;
272     }
273
274     public void setRepositoryEntityManager( EntityManager<Repository, String> repositoryEntityManager )
275     {
276         this.repositoryEntityManager = repositoryEntityManager;
277     }
278
279     public EntityManager<Namespace, String> getNamespaceEntityManager()
280     {
281         return namespaceEntityManager;
282     }
283
284     public void setNamespaceEntityManager( EntityManager<Namespace, String> namespaceEntityManager )
285     {
286         this.namespaceEntityManager = namespaceEntityManager;
287     }
288
289     public EntityManager<Project, String> getProjectEntityManager()
290     {
291         return projectEntityManager;
292     }
293
294     public void setProjectEntityManager( EntityManager<Project, String> projectEntityManager )
295     {
296         this.projectEntityManager = projectEntityManager;
297     }
298
299     public EntityManager<ArtifactMetadataModel, String> getArtifactMetadataModelEntityManager()
300     {
301         return artifactMetadataModelEntityManager;
302     }
303
304     public void setArtifactMetadataModelEntityManager(
305         EntityManager<ArtifactMetadataModel, String> artifactMetadataModelEntityManager )
306     {
307         this.artifactMetadataModelEntityManager = artifactMetadataModelEntityManager;
308     }
309
310     public EntityManager<MetadataFacetModel, String> getMetadataFacetModelEntityManager()
311     {
312         return metadataFacetModelEntityManager;
313     }
314
315     public void setMetadataFacetModelEntityManager(
316         EntityManager<MetadataFacetModel, String> metadataFacetModelEntityManager )
317     {
318         this.metadataFacetModelEntityManager = metadataFacetModelEntityManager;
319     }
320
321     public EntityManager<ProjectVersionMetadataModel, String> getProjectVersionMetadataModelEntityManager()
322     {
323         return projectVersionMetadataModelEntityManager;
324     }
325
326     public void setProjectVersionMetadataModelEntityManager(
327         EntityManager<ProjectVersionMetadataModel, String> projectVersionMetadataModelEntityManager )
328     {
329         this.projectVersionMetadataModelEntityManager = projectVersionMetadataModelEntityManager;
330     }
331 }