001package org.apache.archiva.metadata.repository.cassandra; 002 003/* 004 * Licensed to the Apache Software Foundation (ASF) under one 005 * or more contributor license agreements. See the NOTICE file 006 * distributed with this work for additional information 007 * regarding copyright ownership. The ASF licenses this file 008 * to you under the Apache License, Version 2.0 (the 009 * "License"); you may not use this file except in compliance 010 * with the License. You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, 015 * software distributed under the License is distributed on an 016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 017 * KIND, either express or implied. See the License for the 018 * specific language governing permissions and limitations 019 * under the License. 020 */ 021 022import com.google.common.base.Predicate; 023import com.google.common.collect.Iterables; 024 025import me.prettyprint.cassandra.serializers.LongSerializer; 026import me.prettyprint.cassandra.serializers.StringSerializer; 027import me.prettyprint.cassandra.service.template.ColumnFamilyResult; 028import me.prettyprint.cassandra.service.template.ColumnFamilyTemplate; 029import me.prettyprint.cassandra.service.template.ColumnFamilyUpdater; 030import me.prettyprint.cassandra.service.template.ThriftColumnFamilyTemplate; 031import me.prettyprint.hector.api.Keyspace; 032import me.prettyprint.hector.api.beans.ColumnSlice; 033import me.prettyprint.hector.api.beans.OrderedRows; 034import me.prettyprint.hector.api.beans.Row; 035import me.prettyprint.hector.api.exceptions.HInvalidRequestException; 036import me.prettyprint.hector.api.factory.HFactory; 037import me.prettyprint.hector.api.mutation.MutationResult; 038import me.prettyprint.hector.api.mutation.Mutator; 039import me.prettyprint.hector.api.query.QueryResult; 040import me.prettyprint.hector.api.query.RangeSlicesQuery; 041 042import org.apache.archiva.configuration.ArchivaConfiguration; 043import org.apache.archiva.metadata.model.ArtifactMetadata; 044import org.apache.archiva.metadata.model.CiManagement; 045import org.apache.archiva.metadata.model.Dependency; 046import org.apache.archiva.metadata.model.FacetedMetadata; 047import org.apache.archiva.metadata.model.IssueManagement; 048import org.apache.archiva.metadata.model.License; 049import org.apache.archiva.metadata.model.MailingList; 050import org.apache.archiva.metadata.model.MetadataFacet; 051import org.apache.archiva.metadata.model.MetadataFacetFactory; 052import org.apache.archiva.metadata.model.Organization; 053import org.apache.archiva.metadata.model.ProjectMetadata; 054import org.apache.archiva.metadata.model.ProjectVersionMetadata; 055import org.apache.archiva.metadata.model.ProjectVersionReference; 056import org.apache.archiva.metadata.model.Scm; 057import org.apache.archiva.metadata.repository.MetadataRepository; 058import org.apache.archiva.metadata.repository.MetadataRepositoryException; 059import org.apache.archiva.metadata.repository.MetadataResolutionException; 060import org.apache.archiva.metadata.repository.cassandra.model.ArtifactMetadataModel; 061import org.apache.archiva.metadata.repository.cassandra.model.MetadataFacetModel; 062import org.apache.archiva.metadata.repository.cassandra.model.Namespace; 063import org.apache.archiva.metadata.repository.cassandra.model.Project; 064import org.apache.archiva.metadata.repository.cassandra.model.ProjectVersionMetadataModel; 065import org.apache.archiva.metadata.repository.cassandra.model.Repository; 066import org.apache.commons.lang.StringUtils; 067import org.modelmapper.ModelMapper; 068import org.slf4j.Logger; 069import org.slf4j.LoggerFactory; 070 071import javax.persistence.PersistenceException; 072 073import java.util.ArrayList; 074import java.util.Collection; 075import java.util.Collections; 076import java.util.Date; 077import java.util.HashMap; 078import java.util.HashSet; 079import java.util.Iterator; 080import java.util.LinkedList; 081import java.util.List; 082import java.util.Map; 083import java.util.Set; 084import java.util.UUID; 085 086import static org.apache.archiva.metadata.repository.cassandra.CassandraUtils.*; 087import static org.apache.archiva.metadata.repository.cassandra.model.ColumnNames.*; 088 089/** 090 * @author Olivier Lamy 091 * @since 2.0.0 092 */ 093public class CassandraMetadataRepository 094 implements MetadataRepository 095{ 096 097 private Logger logger = LoggerFactory.getLogger( getClass() ); 098 099 private ArchivaConfiguration configuration; 100 101 private final Map<String, MetadataFacetFactory> metadataFacetFactories; 102 103 private final CassandraArchivaManager cassandraArchivaManager; 104 105 private final ColumnFamilyTemplate<String, String> projectVersionMetadataTemplate; 106 107 private final ColumnFamilyTemplate<String, String> projectTemplate; 108 109 private final ColumnFamilyTemplate<String, String> artifactMetadataTemplate; 110 111 private final ColumnFamilyTemplate<String, String> metadataFacetTemplate; 112 113 private final ColumnFamilyTemplate<String, String> mailingListTemplate; 114 115 private final ColumnFamilyTemplate<String, String> licenseTemplate; 116 117 private final ColumnFamilyTemplate<String, String> dependencyTemplate; 118 119 private final Keyspace keyspace; 120 121 private final StringSerializer ss = StringSerializer.get(); 122 123 public CassandraMetadataRepository( Map<String, MetadataFacetFactory> metadataFacetFactories, 124 ArchivaConfiguration configuration, 125 CassandraArchivaManager cassandraArchivaManager ) 126 { 127 this.metadataFacetFactories = metadataFacetFactories; 128 this.configuration = configuration; 129 this.cassandraArchivaManager = cassandraArchivaManager; 130 this.keyspace = cassandraArchivaManager.getKeyspace(); 131 132 this.projectVersionMetadataTemplate = 133 new ThriftColumnFamilyTemplate<>( cassandraArchivaManager.getKeyspace(), // 134 cassandraArchivaManager.getProjectVersionMetadataFamilyName(), // 135 StringSerializer.get(), // 136 StringSerializer.get() ); 137 138 this.projectTemplate = new ThriftColumnFamilyTemplate<>( cassandraArchivaManager.getKeyspace(), // 139 cassandraArchivaManager.getProjectFamilyName(), // 140 // 141 StringSerializer.get(), // 142 StringSerializer.get() ); 143 144 this.artifactMetadataTemplate = new ThriftColumnFamilyTemplate<>( cassandraArchivaManager.getKeyspace(), // 145 cassandraArchivaManager.getArtifactMetadataFamilyName(), 146 StringSerializer.get(), // 147 StringSerializer.get() ); 148 149 this.metadataFacetTemplate = new ThriftColumnFamilyTemplate<>( cassandraArchivaManager.getKeyspace(), // 150 cassandraArchivaManager.getMetadataFacetFamilyName(), 151 // 152 StringSerializer.get(), // 153 StringSerializer.get() ); 154 155 this.mailingListTemplate = new ThriftColumnFamilyTemplate<>( cassandraArchivaManager.getKeyspace(), // 156 cassandraArchivaManager.getMailingListFamilyName(), 157 // 158 StringSerializer.get(), // 159 StringSerializer.get() ); 160 161 this.licenseTemplate = new ThriftColumnFamilyTemplate<>( cassandraArchivaManager.getKeyspace(), // 162 cassandraArchivaManager.getLicenseFamilyName(), 163 // 164 StringSerializer.get(), // 165 StringSerializer.get() ); 166 167 this.dependencyTemplate = new ThriftColumnFamilyTemplate<>( cassandraArchivaManager.getKeyspace(), // 168 cassandraArchivaManager.getDependencyFamilyName(), 169 // 170 StringSerializer.get(), // 171 StringSerializer.get() ); 172 } 173 174 175 /** 176 * if the repository doesn't exist it will be created 177 * 178 * @param repositoryId 179 * @return 180 */ 181 public Repository getOrCreateRepository( String repositoryId ) 182 throws MetadataRepositoryException 183 { 184 String cf = cassandraArchivaManager.getRepositoryFamilyName(); 185 186 QueryResult<OrderedRows<String, String, String>> result = HFactory // 187 .createRangeSlicesQuery( keyspace, StringSerializer.get(), StringSerializer.get(), 188 StringSerializer.get() ) // 189 .setColumnFamily( cf ) // 190 .setColumnNames( REPOSITORY_NAME.toString() ) // 191 .addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) // 192 .execute(); 193 194 if ( result.get().getCount() < 1 ) 195 { 196 // we need to create the repository 197 Repository repository = new Repository( repositoryId ); 198 199 try 200 { 201 MutationResult mutationResult = HFactory.createMutator( keyspace, StringSerializer.get() ) // 202 .addInsertion( repositoryId, cf, 203 CassandraUtils.column( REPOSITORY_NAME.toString(), repository.getName() ) ) // 204 .execute(); 205 logger.debug( "time to insert repository: {}", mutationResult.getExecutionTimeMicro() ); 206 return repository; 207 } 208 catch ( HInvalidRequestException e ) 209 { 210 logger.error( e.getMessage(), e ); 211 throw new MetadataRepositoryException( e.getMessage(), e ); 212 } 213 214 } 215 216 return new Repository( 217 result.get().getList().get( 0 ).getColumnSlice().getColumnByName( REPOSITORY_NAME.toString() ).getValue() ); 218 } 219 220 221 protected Repository getRepository( String repositoryId ) 222 throws MetadataRepositoryException 223 { 224 225 QueryResult<OrderedRows<String, String, String>> result = HFactory // 226 .createRangeSlicesQuery( keyspace, StringSerializer.get(), StringSerializer.get(), 227 StringSerializer.get() ) // 228 .setColumnFamily( cassandraArchivaManager.getRepositoryFamilyName() ) // 229 .setColumnNames( REPOSITORY_NAME.toString() ) // 230 .addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) // 231 .execute(); 232 return ( result.get().getCount() > 0 ) ? new Repository( repositoryId ) : null; 233 } 234 235 @Override 236 public void updateNamespace( String repositoryId, String namespaceId ) 237 throws MetadataRepositoryException 238 { 239 updateOrAddNamespace( repositoryId, namespaceId ); 240 } 241 242 private Namespace updateOrAddNamespace( String repositoryId, String namespaceId ) 243 throws MetadataRepositoryException 244 { 245 try 246 { 247 Repository repository = getOrCreateRepository( repositoryId ); 248 249 String key = 250 new Namespace.KeyBuilder().withNamespace( namespaceId ).withRepositoryId( repositoryId ).build(); 251 252 Namespace namespace = getNamespace( repositoryId, namespaceId ); 253 if ( namespace == null ) 254 { 255 String cf = cassandraArchivaManager.getNamespaceFamilyName(); 256 namespace = new Namespace( namespaceId, repository ); 257 HFactory.createMutator( keyspace, StringSerializer.get() ) 258 // values 259 .addInsertion( key, cf, CassandraUtils.column( NAME.toString(), namespace.getName() ) ) // 260 .addInsertion( key, cf, CassandraUtils.column( REPOSITORY_NAME.toString(), repository.getName() ) ) // 261 .execute(); 262 } 263 264 return namespace; 265 } 266 catch ( HInvalidRequestException e ) 267 { 268 logger.error( e.getMessage(), e ); 269 throw new MetadataRepositoryException( e.getMessage(), e ); 270 } 271 } 272 273 protected Namespace getNamespace( String repositoryId, String namespaceId ) 274 { 275 276 QueryResult<OrderedRows<String, String, String>> result = HFactory // 277 .createRangeSlicesQuery( keyspace, ss, ss, ss ) // 278 .setColumnFamily( cassandraArchivaManager.getNamespaceFamilyName() ) // 279 .setColumnNames( REPOSITORY_NAME.toString(), NAME.toString() ) // 280 .addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) // 281 .addEqualsExpression( NAME.toString(), namespaceId ) // 282 .execute(); 283 if ( result.get().getCount() > 0 ) 284 { 285 ColumnSlice<String, String> columnSlice = result.get().getList().get( 0 ).getColumnSlice(); 286 return new Namespace( getStringValue( columnSlice, NAME.toString() ), // 287 new Repository( getStringValue( columnSlice, REPOSITORY_NAME.toString() ) ) ); 288 289 } 290 return null; 291 } 292 293 294 @Override 295 public void removeNamespace( String repositoryId, String namespaceId ) 296 throws MetadataRepositoryException 297 { 298 299 try 300 { 301 String key = new Namespace.KeyBuilder() // 302 .withNamespace( namespaceId ) // 303 .withRepositoryId( repositoryId ) // 304 .build(); 305 306 HFactory.createMutator( cassandraArchivaManager.getKeyspace(), new StringSerializer() ) // 307 .addDeletion( key, cassandraArchivaManager.getNamespaceFamilyName() ) // 308 .execute(); 309 310 QueryResult<OrderedRows<String, String, String>> result = HFactory // 311 .createRangeSlicesQuery( keyspace, ss, ss, ss ) // 312 .setColumnFamily( cassandraArchivaManager.getProjectFamilyName() ) // 313 .setColumnNames( REPOSITORY_NAME.toString() ) // 314 .addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) // 315 .addEqualsExpression( NAMESPACE_ID.toString(), namespaceId ) // 316 .execute(); 317 318 for ( Row<String, String, String> row : result.get() ) 319 { 320 this.projectTemplate.deleteRow( row.getKey() ); 321 } 322 323 result = HFactory // 324 .createRangeSlicesQuery( keyspace, ss, ss, ss ) // 325 .setColumnFamily( cassandraArchivaManager.getProjectVersionMetadataFamilyName() ) // 326 .setColumnNames( REPOSITORY_NAME.toString() ) // 327 .addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) // 328 .addEqualsExpression( NAMESPACE_ID.toString(), namespaceId ) // 329 .execute(); 330 331 for ( Row<String, String, String> row : result.get() ) 332 { 333 this.projectVersionMetadataTemplate.deleteRow( row.getKey() ); 334 removeMailingList( row.getKey() ); 335 } 336 337 result = HFactory // 338 .createRangeSlicesQuery( keyspace, ss, ss, ss ) // 339 .setColumnFamily( cassandraArchivaManager.getArtifactMetadataFamilyName() ) // 340 .setColumnNames( REPOSITORY_NAME.toString() ) // 341 .addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) // 342 .addEqualsExpression( NAMESPACE_ID.toString(), namespaceId ) // 343 .execute(); 344 345 for ( Row<String, String, String> row : result.get() ) 346 { 347 this.artifactMetadataTemplate.deleteRow( row.getKey() ); 348 } 349 350 result = HFactory // 351 .createRangeSlicesQuery( keyspace, ss, ss, ss ) // 352 .setColumnFamily( cassandraArchivaManager.getMetadataFacetFamilyName() ) // 353 .setColumnNames( REPOSITORY_NAME.toString() ) // 354 .addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) // 355 .addEqualsExpression( NAMESPACE_ID.toString(), namespaceId ) // 356 .execute(); 357 358 for ( Row<String, String, String> row : result.get() ) 359 { 360 this.metadataFacetTemplate.deleteRow( row.getKey() ); 361 } 362 363 } 364 catch ( HInvalidRequestException e ) 365 { 366 logger.error( e.getMessage(), e ); 367 throw new MetadataRepositoryException( e.getMessage(), e ); 368 } 369 } 370 371 372 @Override 373 public void removeRepository( final String repositoryId ) 374 throws MetadataRepositoryException 375 { 376 377 // TODO use cql queries to delete all 378 List<String> namespacesKey = new ArrayList<>(); 379 380 QueryResult<OrderedRows<String, String, String>> result = HFactory // 381 .createRangeSlicesQuery( keyspace, ss, ss, ss ) // 382 .setColumnFamily( cassandraArchivaManager.getNamespaceFamilyName() ) // 383 .setColumnNames( REPOSITORY_NAME.toString() ) // 384 .addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) // 385 .execute(); 386 387 for ( Row<String, String, String> row : result.get().getList() ) 388 { 389 namespacesKey.add( row.getKey() ); 390 } 391 392 HFactory.createMutator( cassandraArchivaManager.getKeyspace(), ss ) // 393 .addDeletion( namespacesKey, cassandraArchivaManager.getNamespaceFamilyName() ) // 394 .execute(); 395 396 //delete repositoryId 397 HFactory.createMutator( cassandraArchivaManager.getKeyspace(), ss ) // 398 .addDeletion( repositoryId, cassandraArchivaManager.getRepositoryFamilyName() ) // 399 .execute(); 400 401 result = HFactory // 402 .createRangeSlicesQuery( keyspace, ss, ss, ss ) // 403 .setColumnFamily( cassandraArchivaManager.getProjectFamilyName() ) // 404 .setColumnNames( REPOSITORY_NAME.toString() ) // 405 .addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) // 406 .execute(); 407 408 for ( Row<String, String, String> row : result.get() ) 409 { 410 this.projectTemplate.deleteRow( row.getKey() ); 411 } 412 413 result = HFactory // 414 .createRangeSlicesQuery( keyspace, ss, ss, ss ) // 415 .setColumnFamily( cassandraArchivaManager.getProjectVersionMetadataFamilyName() ) // 416 .setColumnNames( REPOSITORY_NAME.toString() ) // 417 .addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) // 418 .execute(); 419 420 for ( Row<String, String, String> row : result.get() ) 421 { 422 this.projectVersionMetadataTemplate.deleteRow( row.getKey() ); 423 removeMailingList( row.getKey() ); 424 } 425 426 result = HFactory // 427 .createRangeSlicesQuery( keyspace, ss, ss, ss ) // 428 .setColumnFamily( cassandraArchivaManager.getArtifactMetadataFamilyName() ) // 429 .setColumnNames( REPOSITORY_NAME.toString() ) // 430 .addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) // 431 .execute(); 432 433 for ( Row<String, String, String> row : result.get() ) 434 { 435 this.artifactMetadataTemplate.deleteRow( row.getKey() ); 436 } 437 438 result = HFactory // 439 .createRangeSlicesQuery( keyspace, ss, ss, ss ) // 440 .setColumnFamily( cassandraArchivaManager.getMetadataFacetFamilyName() ) // 441 .setColumnNames( REPOSITORY_NAME.toString() ) // 442 .addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) // 443 .execute(); 444 445 for ( Row<String, String, String> row : result.get() ) 446 { 447 this.metadataFacetTemplate.deleteRow( row.getKey() ); 448 } 449 450 451 } 452 453 @Override 454 public Collection<String> getRepositories() 455 throws MetadataRepositoryException 456 { 457 try 458 { 459 logger.debug( "getRepositories" ); 460 461 final QueryResult<OrderedRows<String, String, String>> cResult = // 462 HFactory.createRangeSlicesQuery( cassandraArchivaManager.getKeyspace(), // 463 ss, ss, ss ) // 464 .setColumnFamily( cassandraArchivaManager.getRepositoryFamilyName() ) // 465 .setColumnNames( REPOSITORY_NAME.toString() ) // 466 .setRange( null, null, false, Integer.MAX_VALUE ) // 467 .execute(); 468 469 List<String> repoIds = new ArrayList<>( cResult.get().getCount() ); 470 471 for ( Row<String, String, String> row : cResult.get() ) 472 { 473 repoIds.add( getStringValue( row.getColumnSlice(), REPOSITORY_NAME.toString() ) ); 474 } 475 476 return repoIds; 477 } 478 catch ( PersistenceException e ) 479 { 480 throw new MetadataRepositoryException( e.getMessage(), e ); 481 } 482 483 } 484 485 // FIXME this one need peformance improvement maybe a cache? 486 @Override 487 public Collection<String> getRootNamespaces( final String repoId ) 488 throws MetadataResolutionException 489 { 490 491 QueryResult<OrderedRows<String, String, String>> result = HFactory // 492 .createRangeSlicesQuery( keyspace, ss, ss, ss ) // 493 .setColumnFamily( cassandraArchivaManager.getNamespaceFamilyName() ) // 494 .setColumnNames( NAME.toString() ) // 495 .addEqualsExpression( REPOSITORY_NAME.toString(), repoId ) // 496 .execute(); 497 498 Set<String> namespaces = new HashSet<String>( result.get().getCount() ); 499 500 for ( Row<String, String, String> row : result.get() ) 501 { 502 namespaces.add( StringUtils.substringBefore( getStringValue( row.getColumnSlice(), NAME.toString() ), "." ) ); 503 } 504 505 return namespaces; 506 } 507 508 // FIXME this one need peformance improvement maybe a cache? 509 @Override 510 public Collection<String> getNamespaces( final String repoId, final String namespaceId ) 511 throws MetadataResolutionException 512 { 513 514 QueryResult<OrderedRows<String, String, String>> result = HFactory // 515 .createRangeSlicesQuery( keyspace, ss, ss, ss ) // 516 .setColumnFamily( cassandraArchivaManager.getNamespaceFamilyName() ) // 517 .setColumnNames( NAME.toString() ) // 518 .addEqualsExpression( REPOSITORY_NAME.toString(), repoId ) // 519 .execute(); 520 521 List<String> namespaces = new ArrayList<>( result.get().getCount() ); 522 523 for ( Row<String, String, String> row : result.get() ) 524 { 525 String currentNamespace = getStringValue( row.getColumnSlice(), NAME.toString() ); 526 if ( StringUtils.startsWith( currentNamespace, namespaceId ) // 527 && ( StringUtils.length( currentNamespace ) > StringUtils.length( namespaceId ) ) ) 528 { 529 // store after namespaceId '.' but before next '.' 530 // call org namespace org.apache.maven.shared -> stored apache 531 532 String calledNamespace = StringUtils.endsWith( namespaceId, "." ) ? namespaceId : namespaceId + "."; 533 String storedNamespace = StringUtils.substringAfter( currentNamespace, calledNamespace ); 534 535 storedNamespace = StringUtils.substringBefore( storedNamespace, "." ); 536 537 namespaces.add( storedNamespace ); 538 } 539 } 540 541 return namespaces; 542 543 } 544 545 // only use for testing purpose 546 protected List<String> getNamespaces( final String repoId ) 547 throws MetadataResolutionException 548 { 549 550 QueryResult<OrderedRows<String, String, String>> result = HFactory // 551 .createRangeSlicesQuery( keyspace, ss, ss, ss ) // 552 .setColumnFamily( cassandraArchivaManager.getNamespaceFamilyName() ) // 553 .setColumnNames( NAME.toString() ) // 554 .addEqualsExpression( REPOSITORY_NAME.toString(), repoId ) // 555 .execute(); 556 557 List<String> namespaces = new ArrayList<>( result.get().getCount() ); 558 559 for ( Row<String, String, String> row : result.get() ) 560 { 561 namespaces.add( getStringValue( row.getColumnSlice(), NAME.toString() ) ); 562 } 563 564 return namespaces; 565 } 566 567 568 @Override 569 public void updateProject( String repositoryId, ProjectMetadata projectMetadata ) 570 throws MetadataRepositoryException 571 { 572 573 QueryResult<OrderedRows<String, String, String>> result = HFactory // 574 .createRangeSlicesQuery( keyspace, ss, ss, ss ) // 575 .setColumnFamily( cassandraArchivaManager.getProjectFamilyName() ) // 576 .setColumnNames( PROJECT_ID.toString() ) // 577 .addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) // 578 .addEqualsExpression( NAMESPACE_ID.toString(), projectMetadata.getNamespace() ) // 579 .addEqualsExpression( PROJECT_ID.toString(), projectMetadata.getId() ) // 580 .execute(); 581 582 // project exists ? if yes return nothing to update here 583 if ( result.get().getCount() > 0 ) 584 { 585 return; 586 } 587 else 588 { 589 Namespace namespace = updateOrAddNamespace( repositoryId, projectMetadata.getNamespace() ); 590 591 String key = 592 new Project.KeyBuilder().withProjectId( projectMetadata.getId() ).withNamespace( namespace ).build(); 593 594 String cf = cassandraArchivaManager.getProjectFamilyName(); 595 projectTemplate.createMutator() 596 // values 597 .addInsertion( key, cf, CassandraUtils.column( PROJECT_ID.toString(), projectMetadata.getId() ) ) // 598 .addInsertion( key, cf, CassandraUtils.column( REPOSITORY_NAME.toString(), repositoryId ) ) // 599 .addInsertion( key, cf, CassandraUtils.column( NAMESPACE_ID.toString(), projectMetadata.getNamespace() ) )// 600 .execute(); 601 } 602 } 603 604 @Override 605 public Collection<String> getProjects( final String repoId, final String namespace ) 606 throws MetadataResolutionException 607 { 608 609 QueryResult<OrderedRows<String, String, String>> result = HFactory // 610 .createRangeSlicesQuery( keyspace, ss, ss, ss ) // 611 .setColumnFamily( cassandraArchivaManager.getProjectFamilyName() ) // 612 .setColumnNames( PROJECT_ID.toString() ) // 613 .addEqualsExpression( REPOSITORY_NAME.toString(), repoId ) // 614 .addEqualsExpression( NAMESPACE_ID.toString(), namespace ) // 615 .execute(); 616 617 final Set<String> projects = new HashSet<String>( result.get().getCount() ); 618 619 for ( Row<String, String, String> row : result.get() ) 620 { 621 projects.add( getStringValue( row.getColumnSlice(), PROJECT_ID.toString() ) ); 622 } 623 624 return projects; 625 } 626 627 @Override 628 public void removeProject( final String repositoryId, final String namespaceId, final String projectId ) 629 throws MetadataRepositoryException 630 { 631 632 String key = new Project.KeyBuilder() // 633 .withProjectId( projectId ) // 634 .withNamespace( new Namespace( namespaceId, new Repository( repositoryId ) ) ) // 635 .build(); 636 637 this.projectTemplate.deleteRow( key ); 638 639 QueryResult<OrderedRows<String, String, String>> result = HFactory // 640 .createRangeSlicesQuery( keyspace, ss, ss, ss ) // 641 .setColumnFamily( cassandraArchivaManager.getProjectVersionMetadataFamilyName() ) // 642 .setColumnNames( ID.toString() ) // 643 .addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) // 644 .addEqualsExpression( NAMESPACE_ID.toString(), namespaceId ) // 645 .addEqualsExpression( PROJECT_ID.toString(), projectId ) // 646 .execute(); 647 648 for ( Row<String, String, String> row : result.get() ) 649 { 650 this.projectVersionMetadataTemplate.deleteRow( row.getKey() ); 651 removeMailingList( row.getKey() ); 652 } 653 654 result = HFactory // 655 .createRangeSlicesQuery( keyspace, ss, ss, ss ) // 656 .setColumnFamily( cassandraArchivaManager.getArtifactMetadataFamilyName() ) // 657 .setColumnNames( PROJECT_ID.toString() ) // 658 .addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) // 659 .addEqualsExpression( NAMESPACE_ID.toString(), namespaceId ) // 660 .addEqualsExpression( PROJECT_ID.toString(), projectId ) // 661 .execute(); 662 663 for ( Row<String, String, String> row : result.get() ) 664 { 665 this.artifactMetadataTemplate.deleteRow( row.getKey() ); 666 } 667 } 668 669 @Override 670 public Collection<String> getProjectVersions( final String repoId, final String namespace, final String projectId ) 671 throws MetadataResolutionException 672 { 673 674 QueryResult<OrderedRows<String, String, String>> result = HFactory // 675 .createRangeSlicesQuery( keyspace, ss, ss, ss ) // 676 .setColumnFamily( cassandraArchivaManager.getProjectVersionMetadataFamilyName() ) // 677 .setColumnNames( PROJECT_VERSION.toString() ) // 678 .addEqualsExpression( REPOSITORY_NAME.toString(), repoId ) // 679 .addEqualsExpression( NAMESPACE_ID.toString(), namespace ) // 680 .addEqualsExpression( PROJECT_ID.toString(), projectId ) // 681 .execute(); 682 683 int count = result.get().getCount(); 684 685 if ( count < 1 ) 686 { 687 return Collections.emptyList(); 688 } 689 690 Set<String> versions = new HashSet<String>( count ); 691 692 for ( Row<String, String, String> orderedRows : result.get() ) 693 { 694 versions.add( getStringValue( orderedRows.getColumnSlice(), PROJECT_VERSION.toString() ) ); 695 } 696 697 return versions; 698 699 } 700 701 @Override 702 public ProjectMetadata getProject( final String repoId, final String namespace, final String id ) 703 throws MetadataResolutionException 704 { 705 706 QueryResult<OrderedRows<String, String, String>> result = HFactory // 707 .createRangeSlicesQuery( keyspace, ss, ss, ss ) // 708 .setColumnFamily( cassandraArchivaManager.getProjectFamilyName() ) // 709 .setColumnNames( PROJECT_ID.toString() ) // 710 .addEqualsExpression( REPOSITORY_NAME.toString(), repoId ) // 711 .addEqualsExpression( NAMESPACE_ID.toString(), namespace ) // 712 .addEqualsExpression( PROJECT_ID.toString(), id ) // 713 .execute(); 714 715 int count = result.get().getCount(); 716 717 if ( count < 1 ) 718 { 719 return null; 720 } 721 722 ProjectMetadata projectMetadata = new ProjectMetadata(); 723 projectMetadata.setId( id ); 724 projectMetadata.setNamespace( namespace ); 725 726 logger.debug( "getProject repoId: {}, namespace: {}, projectId: {} -> {}", repoId, namespace, id, 727 projectMetadata ); 728 729 return projectMetadata; 730 } 731 732 protected ProjectVersionMetadataModel mapProjectVersionMetadataModel( ColumnSlice<String, String> columnSlice ) 733 { 734 ProjectVersionMetadataModel projectVersionMetadataModel = new ProjectVersionMetadataModel(); 735 projectVersionMetadataModel.setId( getStringValue( columnSlice, ID.toString() ) ); 736 projectVersionMetadataModel.setDescription( getStringValue( columnSlice, DESCRIPTION.toString() ) ); 737 projectVersionMetadataModel.setName( getStringValue( columnSlice, NAME.toString() ) ); 738 Namespace namespace = new Namespace( getStringValue( columnSlice, NAMESPACE_ID.toString() ), // 739 new Repository( getStringValue( columnSlice, REPOSITORY_NAME.toString() ) ) ); 740 projectVersionMetadataModel.setNamespace( namespace ); 741 projectVersionMetadataModel.setIncomplete( 742 Boolean.parseBoolean( getStringValue( columnSlice, "incomplete" ) ) ); 743 projectVersionMetadataModel.setProjectId( getStringValue( columnSlice, PROJECT_ID.toString() ) ); 744 projectVersionMetadataModel.setUrl( getStringValue( columnSlice, URL.toString() ) ); 745 return projectVersionMetadataModel; 746 } 747 748 749 @Override 750 public void updateProjectVersion( String repositoryId, String namespaceId, String projectId, 751 ProjectVersionMetadata versionMetadata ) 752 throws MetadataRepositoryException 753 { 754 try 755 { 756 Namespace namespace = getNamespace( repositoryId, namespaceId ); 757 758 if ( namespace == null ) 759 { 760 updateOrAddNamespace( repositoryId, namespaceId ); 761 } 762 763 if ( getProject( repositoryId, namespaceId, projectId ) == null ) 764 { 765 ProjectMetadata projectMetadata = new ProjectMetadata(); 766 projectMetadata.setNamespace( namespaceId ); 767 projectMetadata.setId( projectId ); 768 updateProject( repositoryId, projectMetadata ); 769 } 770 771 } 772 catch ( MetadataResolutionException e ) 773 { 774 throw new MetadataRepositoryException( e.getMessage(), e ); 775 } 776 777 QueryResult<OrderedRows<String, String, String>> result = HFactory // 778 .createRangeSlicesQuery( keyspace, ss, ss, ss ) // 779 .setColumnFamily( cassandraArchivaManager.getProjectVersionMetadataFamilyName() ) // 780 .setColumnNames( PROJECT_VERSION.toString() ) // 781 .addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) // 782 .addEqualsExpression( NAMESPACE_ID.toString(), namespaceId ) // 783 .addEqualsExpression( PROJECT_ID.toString(), projectId ) // 784 .addEqualsExpression( PROJECT_VERSION.toString(), versionMetadata.getId() ) // 785 .execute(); 786 787 ProjectVersionMetadataModel projectVersionMetadataModel = null; 788 boolean creation = true; 789 if ( result.get().getCount() > 0 ) 790 { 791 projectVersionMetadataModel = 792 mapProjectVersionMetadataModel( result.get().getList().get( 0 ).getColumnSlice() ); 793 creation = false; 794 } 795 else 796 { 797 projectVersionMetadataModel = getModelMapper().map( versionMetadata, ProjectVersionMetadataModel.class ); 798 } 799 800 projectVersionMetadataModel.setProjectId( projectId ); 801 projectVersionMetadataModel.setNamespace( new Namespace( namespaceId, new Repository( repositoryId ) ) ); 802 803 projectVersionMetadataModel.setCiManagement( versionMetadata.getCiManagement() ); 804 projectVersionMetadataModel.setIssueManagement( versionMetadata.getIssueManagement() ); 805 projectVersionMetadataModel.setOrganization( versionMetadata.getOrganization() ); 806 projectVersionMetadataModel.setScm( versionMetadata.getScm() ); 807 808 projectVersionMetadataModel.setMailingLists( versionMetadata.getMailingLists() ); 809 projectVersionMetadataModel.setDependencies( versionMetadata.getDependencies() ); 810 projectVersionMetadataModel.setLicenses( versionMetadata.getLicenses() ); 811 812 // we don't test of repository and namespace really exist ! 813 String key = new ProjectVersionMetadataModel.KeyBuilder() // 814 .withRepository( repositoryId ) // 815 .withNamespace( namespaceId ) // 816 .withProjectId( projectId ) // 817 .withProjectVersion( versionMetadata.getVersion() ) // 818 .withId( versionMetadata.getId() ) // 819 .build(); 820 821 // FIXME nested objects to store!!! 822 if ( creation ) 823 { 824 String cf = cassandraArchivaManager.getProjectVersionMetadataFamilyName(); 825 Mutator<String> mutator = projectVersionMetadataTemplate.createMutator() 826 // values 827 .addInsertion( key, cf, column( PROJECT_ID.toString(), projectId ) ) // 828 .addInsertion( key, cf, column( REPOSITORY_NAME.toString(), repositoryId ) ) // 829 .addInsertion( key, cf, column( NAMESPACE_ID.toString(), namespaceId ) )// 830 .addInsertion( key, cf, column( PROJECT_VERSION.toString(), versionMetadata.getVersion() ) ); // 831 832 addInsertion( mutator, key, cf, DESCRIPTION.toString(), versionMetadata.getDescription() ); 833 834 addInsertion( mutator, key, cf, NAME.toString(), versionMetadata.getName() ); 835 836 addInsertion( mutator, key, cf, "incomplete", Boolean.toString( versionMetadata.isIncomplete() ) ); 837 838 addInsertion( mutator, key, cf, URL.toString(), versionMetadata.getUrl() ); 839 { 840 CiManagement ci = versionMetadata.getCiManagement(); 841 if ( ci != null ) 842 { 843 addInsertion( mutator, key, cf, "ciManagement.system", ci.getSystem() ); 844 addInsertion( mutator, key, cf, "ciManagement.url", ci.getUrl() ); 845 } 846 } 847 848 { 849 IssueManagement issueManagement = versionMetadata.getIssueManagement(); 850 851 if ( issueManagement != null ) 852 { 853 addInsertion( mutator, key, cf, "issueManagement.system", issueManagement.getSystem() ); 854 addInsertion( mutator, key, cf, "issueManagement.url", issueManagement.getUrl() ); 855 } 856 } 857 858 { 859 Organization organization = versionMetadata.getOrganization(); 860 if ( organization != null ) 861 { 862 addInsertion( mutator, key, cf, "organization.name", organization.getName() ); 863 addInsertion( mutator, key, cf, "organization.url", organization.getUrl() ); 864 } 865 } 866 867 { 868 Scm scm = versionMetadata.getScm(); 869 if ( scm != null ) 870 { 871 addInsertion( mutator, key, cf, "scm.url", scm.getUrl() ); 872 addInsertion( mutator, key, cf, "scm.connection", scm.getConnection() ); 873 addInsertion( mutator, key, cf, "scm.developerConnection", scm.getDeveloperConnection() ); 874 } 875 } 876 877 recordMailingList( key, versionMetadata.getMailingLists() ); 878 879 recordLicenses( key, versionMetadata.getLicenses() ); 880 881 recordDependencies( key, versionMetadata.getDependencies(), repositoryId ); 882 883 MutationResult mutationResult = mutator.execute(); 884 } 885 else 886 { 887 ColumnFamilyUpdater<String, String> updater = projectVersionMetadataTemplate.createUpdater( key ); 888 addUpdateStringValue( updater, PROJECT_ID.toString(), projectId ); 889 addUpdateStringValue( updater, REPOSITORY_NAME.toString(), repositoryId ); 890 addUpdateStringValue( updater, NAMESPACE_ID.toString(), namespaceId ); 891 addUpdateStringValue( updater, PROJECT_VERSION.toString(), versionMetadata.getVersion() ); 892 addUpdateStringValue( updater, DESCRIPTION.toString(), versionMetadata.getDescription() ); 893 894 addUpdateStringValue( updater, NAME.toString(), versionMetadata.getName() ); 895 896 updater.setString( "incomplete", Boolean.toString( versionMetadata.isIncomplete() ) ); 897 addUpdateStringValue( updater, URL.toString(), versionMetadata.getUrl() ); 898 899 { 900 CiManagement ci = versionMetadata.getCiManagement(); 901 if ( ci != null ) 902 { 903 addUpdateStringValue( updater, "ciManagement.system", ci.getSystem() ); 904 addUpdateStringValue( updater, "ciManagement.url", ci.getUrl() ); 905 } 906 } 907 { 908 IssueManagement issueManagement = versionMetadata.getIssueManagement(); 909 if ( issueManagement != null ) 910 { 911 addUpdateStringValue( updater, "issueManagement.system", issueManagement.getSystem() ); 912 addUpdateStringValue( updater, "issueManagement.url", issueManagement.getUrl() ); 913 } 914 } 915 { 916 Organization organization = versionMetadata.getOrganization(); 917 if ( organization != null ) 918 { 919 addUpdateStringValue( updater, "organization.name", organization.getName() ); 920 addUpdateStringValue( updater, "organization.url", organization.getUrl() ); 921 } 922 } 923 { 924 Scm scm = versionMetadata.getScm(); 925 if ( scm != null ) 926 { 927 addUpdateStringValue( updater, "scm.url", scm.getUrl() ); 928 addUpdateStringValue( updater, "scm.connection", scm.getConnection() ); 929 addUpdateStringValue( updater, "scm.developerConnection", scm.getDeveloperConnection() ); 930 } 931 } 932 933 // update is a delete record 934 removeMailingList( key ); 935 recordMailingList( key, versionMetadata.getMailingLists() ); 936 937 removeLicenses( key ); 938 recordLicenses( key, versionMetadata.getLicenses() ); 939 940 removeDependencies( key ); 941 recordDependencies( key, versionMetadata.getDependencies(), repositoryId ); 942 943 projectVersionMetadataTemplate.update( updater ); 944 945 } 946 947 ArtifactMetadataModel artifactMetadataModel = new ArtifactMetadataModel(); 948 artifactMetadataModel.setRepositoryId( repositoryId ); 949 artifactMetadataModel.setNamespace( namespaceId ); 950 artifactMetadataModel.setProject( projectId ); 951 artifactMetadataModel.setProjectVersion( versionMetadata.getVersion() ); 952 artifactMetadataModel.setVersion( versionMetadata.getVersion() ); 953 updateFacets( versionMetadata, artifactMetadataModel ); 954 955 } 956 957 958 @Override 959 public ProjectVersionMetadata getProjectVersion( final String repoId, final String namespace, 960 final String projectId, final String projectVersion ) 961 throws MetadataResolutionException 962 { 963 964 QueryResult<OrderedRows<String, String, String>> result = HFactory // 965 .createRangeSlicesQuery( keyspace, ss, ss, ss ) // 966 .setColumnFamily( cassandraArchivaManager.getProjectVersionMetadataFamilyName() ) // 967 .setColumnNames( PROJECT_VERSION.toString() ) // 968 .addEqualsExpression( REPOSITORY_NAME.toString(), repoId ) // 969 .addEqualsExpression( NAMESPACE_ID.toString(), namespace ) // 970 .addEqualsExpression( PROJECT_ID.toString(), projectId ) // 971 .addEqualsExpression( PROJECT_VERSION.toString(), projectVersion ) // 972 .execute(); 973 974 if ( result.get().getCount() < 1 ) 975 { 976 return null; 977 } 978 979 String key = result.get().iterator().next().getKey(); 980 981 ColumnFamilyResult<String, String> columnFamilyResult = this.projectVersionMetadataTemplate.queryColumns( key ); 982 983 if ( !columnFamilyResult.hasResults() ) 984 { 985 return null; 986 } 987 988 ProjectVersionMetadata projectVersionMetadata = new ProjectVersionMetadata(); 989 projectVersionMetadata.setId( columnFamilyResult.getString( PROJECT_VERSION.toString() ) ); 990 projectVersionMetadata.setDescription( columnFamilyResult.getString( DESCRIPTION.toString() ) ); 991 projectVersionMetadata.setName( columnFamilyResult.getString( NAME.toString() ) ); 992 993 projectVersionMetadata.setIncomplete( Boolean.parseBoolean( columnFamilyResult.getString( "incomplete" ) ) ); 994 995 projectVersionMetadata.setUrl( columnFamilyResult.getString( URL.toString() ) ); 996 { 997 String ciUrl = columnFamilyResult.getString( "ciManagement.url" ); 998 String ciSystem = columnFamilyResult.getString( "ciManagement.system" ); 999 1000 if ( StringUtils.isNotEmpty( ciSystem ) || StringUtils.isNotEmpty( ciUrl ) ) 1001 { 1002 projectVersionMetadata.setCiManagement( new CiManagement( ciSystem, ciUrl ) ); 1003 } 1004 } 1005 { 1006 String issueUrl = columnFamilyResult.getString( "issueManagement.url" ); 1007 String issueSystem = columnFamilyResult.getString( "issueManagement.system" ); 1008 if ( StringUtils.isNotEmpty( issueSystem ) || StringUtils.isNotEmpty( issueUrl ) ) 1009 { 1010 projectVersionMetadata.setIssueManagement( new IssueManagement( issueSystem, issueUrl ) ); 1011 } 1012 } 1013 { 1014 String organizationUrl = columnFamilyResult.getString( "organization.url" ); 1015 String organizationName = columnFamilyResult.getString( "organization.name" ); 1016 if ( StringUtils.isNotEmpty( organizationUrl ) || StringUtils.isNotEmpty( organizationName ) ) 1017 { 1018 projectVersionMetadata.setOrganization( new Organization( organizationName, organizationUrl ) ); 1019 } 1020 } 1021 { 1022 String devConn = columnFamilyResult.getString( "scm.developerConnection" ); 1023 String conn = columnFamilyResult.getString( "scm.connection" ); 1024 String url = columnFamilyResult.getString( "scm.url" ); 1025 if ( StringUtils.isNotEmpty( devConn ) || StringUtils.isNotEmpty( conn ) || StringUtils.isNotEmpty( url ) ) 1026 { 1027 projectVersionMetadata.setScm( new Scm( conn, devConn, url ) ); 1028 } 1029 } 1030 projectVersionMetadata.setMailingLists( getMailingLists( key ) ); 1031 projectVersionMetadata.setLicenses( getLicenses( key ) ); 1032 projectVersionMetadata.setDependencies( getDependencies( key ) ); 1033 // facets 1034 1035 result = HFactory // 1036 .createRangeSlicesQuery( keyspace, ss, ss, ss ) // 1037 .setColumnFamily( cassandraArchivaManager.getMetadataFacetFamilyName() ) // 1038 .setColumnNames( FACET_ID.toString(), KEY.toString(), VALUE.toString(), NAME.toString() ) // 1039 .addEqualsExpression( REPOSITORY_NAME.toString(), repoId ) // 1040 .addEqualsExpression( NAMESPACE_ID.toString(), namespace ) // 1041 .addEqualsExpression( PROJECT_ID.toString(), projectId ) // 1042 .addEqualsExpression( PROJECT_VERSION.toString(), projectVersion ) // 1043 .execute(); 1044 1045 Map<String, Map<String, String>> metadataFacetsPerFacetIds = new HashMap<>(); 1046 1047 for ( Row<String, String, String> row : result.get() ) 1048 { 1049 ColumnSlice<String, String> columnSlice = row.getColumnSlice(); 1050 String facetId = getStringValue( columnSlice, FACET_ID.toString() ); 1051 Map<String, String> metaValues = metadataFacetsPerFacetIds.get( facetId ); 1052 if ( metaValues == null ) 1053 { 1054 metaValues = new HashMap<>(); 1055 metadataFacetsPerFacetIds.put( facetId, metaValues ); 1056 } 1057 metaValues.put( getStringValue( columnSlice, KEY.toString() ), getStringValue( columnSlice, VALUE.toString() ) ); 1058 } 1059 1060 if ( !metadataFacetsPerFacetIds.isEmpty() ) 1061 { 1062 for ( Map.Entry<String, Map<String, String>> entry : metadataFacetsPerFacetIds.entrySet() ) 1063 { 1064 MetadataFacetFactory metadataFacetFactory = metadataFacetFactories.get( entry.getKey() ); 1065 if ( metadataFacetFactory != null ) 1066 { 1067 MetadataFacet metadataFacet = metadataFacetFactory.createMetadataFacet(); 1068 metadataFacet.fromProperties( entry.getValue() ); 1069 projectVersionMetadata.addFacet( metadataFacet ); 1070 } 1071 } 1072 } 1073 1074 return projectVersionMetadata; 1075 } 1076 1077 protected void recordMailingList( String projectVersionMetadataKey, List<MailingList> mailingLists ) 1078 { 1079 if ( mailingLists == null || mailingLists.isEmpty() ) 1080 { 1081 return; 1082 } 1083 Mutator<String> mailingMutator = this.mailingListTemplate.createMutator(); 1084 for ( MailingList mailingList : mailingLists ) 1085 { 1086 // we don't care about the key as the real used one with the projectVersionMetadata 1087 String keyMailingList = UUID.randomUUID().toString(); 1088 String cfMailingList = cassandraArchivaManager.getMailingListFamilyName(); 1089 1090 addInsertion( mailingMutator, keyMailingList, cfMailingList, "projectVersionMetadataModel.key", 1091 projectVersionMetadataKey ); 1092 addInsertion( mailingMutator, keyMailingList, cfMailingList, NAME.toString(), mailingList.getName() ); 1093 addInsertion( mailingMutator, keyMailingList, cfMailingList, "mainArchiveUrl", 1094 mailingList.getMainArchiveUrl() ); 1095 addInsertion( mailingMutator, keyMailingList, cfMailingList, "postAddress", mailingList.getPostAddress() ); 1096 addInsertion( mailingMutator, keyMailingList, cfMailingList, "subscribeAddress", 1097 mailingList.getSubscribeAddress() ); 1098 addInsertion( mailingMutator, keyMailingList, cfMailingList, "unsubscribeAddress", 1099 mailingList.getUnsubscribeAddress() ); 1100 int idx = 0; 1101 for ( String otherArchive : mailingList.getOtherArchives() ) 1102 { 1103 addInsertion( mailingMutator, keyMailingList, cfMailingList, "otherArchive." + idx, otherArchive ); 1104 idx++; 1105 } 1106 1107 } 1108 mailingMutator.execute(); 1109 } 1110 1111 protected void removeMailingList( String projectVersionMetadataKey ) 1112 { 1113 1114 QueryResult<OrderedRows<String, String, String>> result = 1115 HFactory.createRangeSlicesQuery( cassandraArchivaManager.getKeyspace(), ss, ss, ss ) // 1116 .setColumnFamily( cassandraArchivaManager.getMailingListFamilyName() ) // 1117 .setColumnNames( NAME.toString() ) // 1118 .setRowCount( Integer.MAX_VALUE ) // 1119 .addEqualsExpression( "projectVersionMetadataModel.key", projectVersionMetadataKey ) // 1120 .execute(); 1121 1122 if ( result.get().getCount() < 1 ) 1123 { 1124 return; 1125 } 1126 1127 for ( Row<String, String, String> row : result.get() ) 1128 { 1129 this.mailingListTemplate.deleteRow( row.getKey() ); 1130 } 1131 1132 } 1133 1134 protected List<MailingList> getMailingLists( String projectVersionMetadataKey ) 1135 { 1136 List<MailingList> mailingLists = new ArrayList<>(); 1137 1138 QueryResult<OrderedRows<String, String, String>> result = 1139 HFactory.createRangeSlicesQuery( cassandraArchivaManager.getKeyspace(), ss, ss, ss ) // 1140 .setColumnFamily( cassandraArchivaManager.getMailingListFamilyName() ) // 1141 .setColumnNames( NAME.toString() ) // 1142 .setRowCount( Integer.MAX_VALUE ) // 1143 .addEqualsExpression( "projectVersionMetadataModel.key", projectVersionMetadataKey ) // 1144 .execute(); 1145 for ( Row<String, String, String> row : result.get() ) 1146 { 1147 ColumnFamilyResult<String, String> columnFamilyResult = 1148 this.mailingListTemplate.queryColumns( row.getKey() ); 1149 1150 MailingList mailingList = new MailingList(); 1151 mailingList.setName( columnFamilyResult.getString( NAME.toString() ) ); 1152 mailingList.setMainArchiveUrl( columnFamilyResult.getString( "mainArchiveUrl" ) ); 1153 mailingList.setPostAddress( columnFamilyResult.getString( "postAddress" ) ); 1154 mailingList.setSubscribeAddress( columnFamilyResult.getString( "subscribeAddress" ) ); 1155 mailingList.setUnsubscribeAddress( columnFamilyResult.getString( "unsubscribeAddress" ) ); 1156 1157 List<String> otherArchives = new ArrayList<>(); 1158 1159 for ( String columnName : columnFamilyResult.getColumnNames() ) 1160 { 1161 if ( StringUtils.startsWith( columnName, "otherArchive." ) ) 1162 { 1163 otherArchives.add( columnFamilyResult.getString( columnName ) ); 1164 } 1165 } 1166 1167 mailingList.setOtherArchives( otherArchives ); 1168 mailingLists.add( mailingList ); 1169 } 1170 1171 return mailingLists; 1172 } 1173 1174 protected void recordLicenses( String projectVersionMetadataKey, List<License> licenses ) 1175 { 1176 1177 if ( licenses == null || licenses.isEmpty() ) 1178 { 1179 return; 1180 } 1181 Mutator<String> licenseMutator = this.licenseTemplate.createMutator(); 1182 1183 for ( License license : licenses ) 1184 { 1185 // we don't care about the key as the real used one with the projectVersionMetadata 1186 String keyLicense = UUID.randomUUID().toString(); 1187 String cfLicense = cassandraArchivaManager.getLicenseFamilyName(); 1188 1189 addInsertion( licenseMutator, keyLicense, cfLicense, "projectVersionMetadataModel.key", 1190 projectVersionMetadataKey ); 1191 1192 addInsertion( licenseMutator, keyLicense, cfLicense, NAME.toString(), license.getName() ); 1193 1194 addInsertion( licenseMutator, keyLicense, cfLicense, URL.toString(), license.getUrl() ); 1195 1196 } 1197 licenseMutator.execute(); 1198 } 1199 1200 protected void removeLicenses( String projectVersionMetadataKey ) 1201 { 1202 1203 QueryResult<OrderedRows<String, String, String>> result = 1204 HFactory.createRangeSlicesQuery( cassandraArchivaManager.getKeyspace(), ss, ss, ss ) // 1205 .setColumnFamily( cassandraArchivaManager.getLicenseFamilyName() ) // 1206 .setColumnNames( NAME.toString() ) // 1207 .setRowCount( Integer.MAX_VALUE ) // 1208 .addEqualsExpression( "projectVersionMetadataModel.key", projectVersionMetadataKey ) // 1209 .execute(); 1210 for ( Row<String, String, String> row : result.get() ) 1211 { 1212 this.licenseTemplate.deleteRow( row.getKey() ); 1213 } 1214 } 1215 1216 protected List<License> getLicenses( String projectVersionMetadataKey ) 1217 { 1218 List<License> licenses = new ArrayList<>(); 1219 1220 QueryResult<OrderedRows<String, String, String>> result = 1221 HFactory.createRangeSlicesQuery( cassandraArchivaManager.getKeyspace(), ss, ss, ss ) // 1222 .setColumnFamily( cassandraArchivaManager.getLicenseFamilyName() ) // 1223 .setColumnNames( "projectVersionMetadataModel.key" ) // 1224 .setRowCount( Integer.MAX_VALUE ) // 1225 .addEqualsExpression( "projectVersionMetadataModel.key", projectVersionMetadataKey ) // 1226 .execute(); 1227 1228 for ( Row<String, String, String> row : result.get() ) 1229 { 1230 ColumnFamilyResult<String, String> columnFamilyResult = this.licenseTemplate.queryColumns( row.getKey() ); 1231 1232 licenses.add( 1233 new License( columnFamilyResult.getString( NAME.toString() ), columnFamilyResult.getString( URL.toString() ) ) ); 1234 } 1235 1236 return licenses; 1237 } 1238 1239 1240 protected void recordDependencies( String projectVersionMetadataKey, List<Dependency> dependencies, 1241 String repositoryId ) 1242 { 1243 1244 if ( dependencies == null || dependencies.isEmpty() ) 1245 { 1246 return; 1247 } 1248 Mutator<String> dependencyMutator = this.dependencyTemplate.createMutator(); 1249 1250 for ( Dependency dependency : dependencies ) 1251 { 1252 // we don't care about the key as the real used one with the projectVersionMetadata 1253 String keyDependency = UUID.randomUUID().toString(); 1254 String cfDependency = cassandraArchivaManager.getDependencyFamilyName(); 1255 1256 addInsertion( dependencyMutator, keyDependency, cfDependency, "projectVersionMetadataModel.key", 1257 projectVersionMetadataKey ); 1258 1259 addInsertion( dependencyMutator, keyDependency, cfDependency, REPOSITORY_NAME.toString(), repositoryId ); 1260 1261 addInsertion( dependencyMutator, keyDependency, cfDependency, "classifier", dependency.getClassifier() ); 1262 1263 addInsertion( dependencyMutator, keyDependency, cfDependency, "optional", 1264 Boolean.toString( dependency.isOptional() ) ); 1265 1266 addInsertion( dependencyMutator, keyDependency, cfDependency, "scope", dependency.getScope() ); 1267 1268 addInsertion( dependencyMutator, keyDependency, cfDependency, "systemPath", dependency.getSystemPath() ); 1269 1270 addInsertion( dependencyMutator, keyDependency, cfDependency, "type", dependency.getType() ); 1271 1272 addInsertion( dependencyMutator, keyDependency, cfDependency, ARTIFACT_ID.toString(), dependency.getArtifactId() ); 1273 1274 addInsertion( dependencyMutator, keyDependency, cfDependency, GROUP_ID.toString(), dependency.getGroupId() ); 1275 1276 addInsertion( dependencyMutator, keyDependency, cfDependency, VERSION.toString(), dependency.getVersion() ); 1277 1278 } 1279 dependencyMutator.execute(); 1280 } 1281 1282 protected void removeDependencies( String projectVersionMetadataKey ) 1283 { 1284 1285 QueryResult<OrderedRows<String, String, String>> result = 1286 HFactory.createRangeSlicesQuery( cassandraArchivaManager.getKeyspace(), ss, ss, ss ) // 1287 .setColumnFamily( cassandraArchivaManager.getDependencyFamilyName() ) // 1288 .setColumnNames( GROUP_ID.toString() ) // 1289 .setRowCount( Integer.MAX_VALUE ) // 1290 .addEqualsExpression( "projectVersionMetadataModel.key", projectVersionMetadataKey ) // 1291 .execute(); 1292 for ( Row<String, String, String> row : result.get() ) 1293 { 1294 this.dependencyTemplate.deleteRow( row.getKey() ); 1295 } 1296 } 1297 1298 protected List<Dependency> getDependencies( String projectVersionMetadataKey ) 1299 { 1300 List<Dependency> dependencies = new ArrayList<>(); 1301 1302 QueryResult<OrderedRows<String, String, String>> result = 1303 HFactory.createRangeSlicesQuery( cassandraArchivaManager.getKeyspace(), ss, ss, ss ) // 1304 .setColumnFamily( cassandraArchivaManager.getDependencyFamilyName() ) // 1305 .setColumnNames( "projectVersionMetadataModel.key" ) // 1306 .setRowCount( Integer.MAX_VALUE ) // 1307 .addEqualsExpression( "projectVersionMetadataModel.key", projectVersionMetadataKey ) // 1308 .execute(); 1309 1310 for ( Row<String, String, String> row : result.get() ) 1311 { 1312 ColumnFamilyResult<String, String> columnFamilyResult = 1313 this.dependencyTemplate.queryColumns( row.getKey() ); 1314 1315 Dependency dependency = new Dependency(); 1316 dependency.setClassifier( columnFamilyResult.getString( "classifier" ) ); 1317 1318 dependency.setOptional( Boolean.parseBoolean( columnFamilyResult.getString( "optional" ) ) ); 1319 1320 dependency.setScope( columnFamilyResult.getString( "scope" ) ); 1321 1322 dependency.setSystemPath( columnFamilyResult.getString( "systemPath" ) ); 1323 1324 dependency.setType( columnFamilyResult.getString( "type" ) ); 1325 1326 dependency.setArtifactId( columnFamilyResult.getString( ARTIFACT_ID.toString() ) ); 1327 1328 dependency.setGroupId( columnFamilyResult.getString( GROUP_ID.toString() ) ); 1329 1330 dependency.setVersion( columnFamilyResult.getString( VERSION.toString() ) ); 1331 1332 dependencies.add( dependency ); 1333 } 1334 1335 return dependencies; 1336 } 1337 1338 @Override 1339 public void updateArtifact( String repositoryId, String namespaceId, String projectId, String projectVersion, 1340 ArtifactMetadata artifactMeta ) 1341 throws MetadataRepositoryException 1342 { 1343 1344 Namespace namespace = getNamespace( repositoryId, namespaceId ); 1345 if ( namespace == null ) 1346 { 1347 namespace = updateOrAddNamespace( repositoryId, namespaceId ); 1348 } 1349 1350 ProjectMetadata projectMetadata = new ProjectMetadata(); 1351 projectMetadata.setId( projectId ); 1352 projectMetadata.setNamespace( namespaceId ); 1353 updateProject( repositoryId, projectMetadata ); 1354 1355 String key = new ArtifactMetadataModel.KeyBuilder().withNamespace( namespace ).withProject( projectId ).withId( 1356 artifactMeta.getId() ).withProjectVersion( projectVersion ).build(); 1357 1358 // exists? 1359 1360 boolean exists = this.artifactMetadataTemplate.isColumnsExist( key ); 1361 1362 if ( exists ) 1363 { 1364 // updater 1365 ColumnFamilyUpdater<String, String> updater = this.artifactMetadataTemplate.createUpdater( key ); 1366 updater.setLong( FILE_LAST_MODIFIED.toString(), artifactMeta.getFileLastModified().getTime() ); 1367 updater.setLong( WHEN_GATHERED.toString(), artifactMeta.getWhenGathered().getTime() ); 1368 updater.setLong( SIZE.toString(), artifactMeta.getSize() ); 1369 addUpdateStringValue( updater, MD5.toString(), artifactMeta.getMd5() ); 1370 addUpdateStringValue( updater, SHA1.toString(), artifactMeta.getSha1() ); 1371 addUpdateStringValue( updater, VERSION.toString(), artifactMeta.getVersion() ); 1372 this.artifactMetadataTemplate.update( updater ); 1373 } 1374 else 1375 { 1376 String cf = this.cassandraArchivaManager.getArtifactMetadataFamilyName(); 1377 // create 1378 this.artifactMetadataTemplate.createMutator() // 1379 .addInsertion( key, cf, column( ID.toString(), artifactMeta.getId() ) )// 1380 .addInsertion( key, cf, column( REPOSITORY_NAME.toString(), repositoryId ) ) // 1381 .addInsertion( key, cf, column( NAMESPACE_ID.toString(), namespaceId ) ) // 1382 .addInsertion( key, cf, column( PROJECT.toString(), artifactMeta.getProject() ) ) // 1383 .addInsertion( key, cf, column( PROJECT_VERSION.toString(), projectVersion ) ) // 1384 .addInsertion( key, cf, column( VERSION.toString(), artifactMeta.getVersion() ) ) // 1385 .addInsertion( key, cf, column( FILE_LAST_MODIFIED.toString(), artifactMeta.getFileLastModified().getTime() ) ) // 1386 .addInsertion( key, cf, column( SIZE.toString(), artifactMeta.getSize() ) ) // 1387 .addInsertion( key, cf, column( MD5.toString(), artifactMeta.getMd5() ) ) // 1388 .addInsertion( key, cf, column( SHA1.toString(), artifactMeta.getSha1() ) ) // 1389 .addInsertion( key, cf, column( WHEN_GATHERED.toString(), artifactMeta.getWhenGathered().getTime() ) )// 1390 .execute(); 1391 } 1392 1393 key = new ProjectVersionMetadataModel.KeyBuilder() // 1394 .withRepository( repositoryId ) // 1395 .withNamespace( namespace ) // 1396 .withProjectId( projectId ) // 1397 .withProjectVersion( projectVersion ) // 1398 .withId( artifactMeta.getId() ) // 1399 .build(); 1400 1401 QueryResult<OrderedRows<String, String, String>> result = HFactory // 1402 .createRangeSlicesQuery( keyspace, ss, ss, ss ) // 1403 .setColumnFamily( cassandraArchivaManager.getProjectVersionMetadataFamilyName() ) // 1404 .setColumnNames( VERSION.toString() ) // 1405 .addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) // 1406 .addEqualsExpression( NAMESPACE_ID.toString(), namespaceId ) // 1407 .addEqualsExpression( PROJECT_ID.toString(), projectId ) // 1408 .addEqualsExpression( PROJECT_VERSION.toString(), projectVersion ) // 1409 .addEqualsExpression( VERSION.toString(), artifactMeta.getVersion() ) // 1410 .execute(); 1411 1412 exists = result.get().getCount() > 0; 1413 1414 if ( !exists ) 1415 { 1416 String cf = this.cassandraArchivaManager.getProjectVersionMetadataFamilyName(); 1417 1418 projectVersionMetadataTemplate.createMutator() // 1419 .addInsertion( key, cf, column( NAMESPACE_ID.toString(), namespace.getName() ) ) // 1420 .addInsertion( key, cf, column( REPOSITORY_NAME.toString(), repositoryId ) ) // 1421 .addInsertion( key, cf, column( PROJECT_VERSION.toString(), projectVersion ) ) // 1422 .addInsertion( key, cf, column( PROJECT_ID.toString(), projectId ) ) // 1423 .addInsertion( key, cf, column( VERSION.toString(), artifactMeta.getVersion() ) ) // 1424 .execute(); 1425 1426 } 1427 1428 ArtifactMetadataModel artifactMetadataModel = new ArtifactMetadataModel(); 1429 1430 artifactMetadataModel.setRepositoryId( repositoryId ); 1431 artifactMetadataModel.setNamespace( namespaceId ); 1432 artifactMetadataModel.setProject( projectId ); 1433 artifactMetadataModel.setProjectVersion( projectVersion ); 1434 artifactMetadataModel.setVersion( artifactMeta.getVersion() ); 1435 artifactMetadataModel.setFileLastModified( artifactMeta.getFileLastModified() == null 1436 ? new Date().getTime() 1437 : artifactMeta.getFileLastModified().getTime() ); 1438 1439 // now facets 1440 updateFacets( artifactMeta, artifactMetadataModel ); 1441 1442 } 1443 1444 @Override 1445 public Collection<String> getArtifactVersions( final String repoId, final String namespace, final String projectId, 1446 final String projectVersion ) 1447 throws MetadataResolutionException 1448 { 1449 1450 QueryResult<OrderedRows<String, String, String>> result = HFactory // 1451 .createRangeSlicesQuery( keyspace, ss, ss, ss ) // 1452 .setColumnFamily( cassandraArchivaManager.getProjectVersionMetadataFamilyName() ) // 1453 .setColumnNames( VERSION.toString() ) // 1454 .addEqualsExpression( REPOSITORY_NAME.toString(), repoId ) // 1455 .addEqualsExpression( NAMESPACE_ID.toString(), namespace ) // 1456 .addEqualsExpression( PROJECT_ID.toString(), projectId ) // 1457 .addEqualsExpression( PROJECT_VERSION.toString(), projectVersion ) // 1458 .execute(); 1459 1460 final Set<String> versions = new HashSet<String>(); 1461 1462 for ( Row<String, String, String> row : result.get() ) 1463 { 1464 versions.add( getStringValue( row.getColumnSlice(), VERSION.toString() ) ); 1465 } 1466 1467 return versions; 1468 1469 } 1470 1471 /** 1472 * iterate over available facets to remove/add from the artifactMetadata 1473 * 1474 * @param facetedMetadata 1475 * @param artifactMetadataModel only use for the key 1476 */ 1477 private void updateFacets( final FacetedMetadata facetedMetadata, 1478 final ArtifactMetadataModel artifactMetadataModel ) 1479 { 1480 1481 String cf = cassandraArchivaManager.getMetadataFacetFamilyName(); 1482 1483 for ( final String facetId : metadataFacetFactories.keySet() ) 1484 { 1485 MetadataFacet metadataFacet = facetedMetadata.getFacet( facetId ); 1486 if ( metadataFacet == null ) 1487 { 1488 continue; 1489 } 1490 // clean first 1491 1492 QueryResult<OrderedRows<String, String, String>> result = 1493 HFactory.createRangeSlicesQuery( keyspace, ss, ss, ss ) // 1494 .setColumnFamily( cf ) // 1495 .setColumnNames( REPOSITORY_NAME.toString() ) // 1496 .addEqualsExpression( REPOSITORY_NAME.toString(), artifactMetadataModel.getRepositoryId() ) // 1497 .addEqualsExpression( NAMESPACE_ID.toString(), artifactMetadataModel.getNamespace() ) // 1498 .addEqualsExpression( PROJECT_ID.toString(), artifactMetadataModel.getProject() ) // 1499 .addEqualsExpression( PROJECT_VERSION.toString(), artifactMetadataModel.getProjectVersion() ) // 1500 .addEqualsExpression( FACET_ID.toString(), facetId ) // 1501 .execute(); 1502 1503 for ( Row<String, String, String> row : result.get().getList() ) 1504 { 1505 this.metadataFacetTemplate.deleteRow( row.getKey() ); 1506 } 1507 1508 Map<String, String> properties = metadataFacet.toProperties(); 1509 1510 for ( Map.Entry<String, String> entry : properties.entrySet() ) 1511 { 1512 String key = new MetadataFacetModel.KeyBuilder().withKey( entry.getKey() ).withArtifactMetadataModel( 1513 artifactMetadataModel ).withFacetId( facetId ).withName( metadataFacet.getName() ).build(); 1514 Mutator<String> mutator = metadataFacetTemplate.createMutator() // 1515 .addInsertion( key, cf, column( REPOSITORY_NAME.toString(), artifactMetadataModel.getRepositoryId() ) ) // 1516 .addInsertion( key, cf, column( NAMESPACE_ID.toString(), artifactMetadataModel.getNamespace() ) ) // 1517 .addInsertion( key, cf, column( PROJECT_ID.toString(), artifactMetadataModel.getProject() ) ) // 1518 .addInsertion( key, cf, column( PROJECT_VERSION.toString(), artifactMetadataModel.getProjectVersion() ) ) // 1519 .addInsertion( key, cf, column( FACET_ID.toString(), facetId ) ) // 1520 .addInsertion( key, cf, column( KEY.toString(), entry.getKey() ) ) // 1521 .addInsertion( key, cf, column( VALUE.toString(), entry.getValue() ) ); 1522 1523 if ( metadataFacet.getName() != null ) 1524 { 1525 mutator.addInsertion( key, cf, column( NAME.toString(), metadataFacet.getName() ) ); 1526 } 1527 1528 mutator.execute(); 1529 } 1530 } 1531 } 1532 1533 1534 @Override 1535 public List<String> getMetadataFacets( final String repositoryId, final String facetId ) 1536 throws MetadataRepositoryException 1537 { 1538 1539 QueryResult<OrderedRows<String, String, String>> result = HFactory // 1540 .createRangeSlicesQuery( keyspace, ss, ss, ss ) // 1541 .setColumnFamily( cassandraArchivaManager.getMetadataFacetFamilyName() ) // 1542 .setColumnNames( NAME.toString() ) // 1543 .addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) // 1544 .addEqualsExpression( FACET_ID.toString(), facetId ) // 1545 .execute(); 1546 1547 final List<String> facets = new ArrayList<>(); 1548 1549 for ( Row<String, String, String> row : result.get() ) 1550 { 1551 facets.add( getStringValue( row.getColumnSlice(), NAME.toString() ) ); 1552 } 1553 return facets; 1554 } 1555 1556 @Override 1557 public boolean hasMetadataFacet( String repositoryId, String facetId ) 1558 throws MetadataRepositoryException 1559 { 1560 return !getMetadataFacets( repositoryId, facetId ).isEmpty(); 1561 } 1562 1563 @Override 1564 public MetadataFacet getMetadataFacet( final String repositoryId, final String facetId, final String name ) 1565 throws MetadataRepositoryException 1566 { 1567 1568 MetadataFacetFactory metadataFacetFactory = metadataFacetFactories.get( facetId ); 1569 if ( metadataFacetFactory == null ) 1570 { 1571 return null; 1572 } 1573 1574 QueryResult<OrderedRows<String, String, String>> result = HFactory // 1575 .createRangeSlicesQuery( keyspace, ss, ss, ss ) // 1576 .setColumnFamily( cassandraArchivaManager.getMetadataFacetFamilyName() ) // 1577 .setColumnNames( KEY.toString(), VALUE.toString() ) // 1578 .addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) // 1579 .addEqualsExpression( FACET_ID.toString(), facetId ) // 1580 .addEqualsExpression( NAME.toString(), name ) // 1581 .execute(); 1582 1583 MetadataFacet metadataFacet = metadataFacetFactory.createMetadataFacet( repositoryId, name ); 1584 int size = result.get().getCount(); 1585 if ( size < 1 ) 1586 { 1587 return null; 1588 } 1589 Map<String, String> map = new HashMap<>( size ); 1590 for ( Row<String, String, String> row : result.get() ) 1591 { 1592 ColumnSlice<String, String> columnSlice = row.getColumnSlice(); 1593 map.put( getStringValue( columnSlice, KEY.toString() ), getStringValue( columnSlice, VALUE.toString() ) ); 1594 } 1595 metadataFacet.fromProperties( map ); 1596 return metadataFacet; 1597 } 1598 1599 @Override 1600 public void addMetadataFacet( String repositoryId, MetadataFacet metadataFacet ) 1601 throws MetadataRepositoryException 1602 { 1603 1604 if ( metadataFacet == null ) 1605 { 1606 return; 1607 } 1608 1609 if ( metadataFacet.toProperties().isEmpty() ) 1610 { 1611 String key = new MetadataFacetModel.KeyBuilder().withRepositoryId( repositoryId ).withFacetId( 1612 metadataFacet.getFacetId() ).withName( metadataFacet.getName() ).build(); 1613 1614 boolean exists = this.metadataFacetTemplate.isColumnsExist( key ); 1615 1616 if ( exists ) 1617 { 1618 ColumnFamilyUpdater<String, String> updater = this.metadataFacetTemplate.createUpdater( key ); 1619 addUpdateStringValue( updater, FACET_ID.toString(), metadataFacet.getFacetId() ); 1620 addUpdateStringValue( updater, NAME.toString(), metadataFacet.getName() ); 1621 this.metadataFacetTemplate.update( updater ); 1622 } 1623 else 1624 { 1625 String cf = this.cassandraArchivaManager.getMetadataFacetFamilyName(); 1626 this.metadataFacetTemplate.createMutator() // 1627 .addInsertion( key, cf, column( REPOSITORY_NAME.toString(), repositoryId ) ) // 1628 .addInsertion( key, cf, column( FACET_ID.toString(), metadataFacet.getFacetId() ) ) // 1629 .addInsertion( key, cf, column( NAME.toString(), metadataFacet.getName() ) ) // 1630 .execute(); 1631 } 1632 1633 } 1634 else 1635 { 1636 for ( Map.Entry<String, String> entry : metadataFacet.toProperties().entrySet() ) 1637 { 1638 String key = new MetadataFacetModel.KeyBuilder().withRepositoryId( repositoryId ).withFacetId( 1639 metadataFacet.getFacetId() ).withName( metadataFacet.getName() ).withKey( entry.getKey() ).build(); 1640 1641 boolean exists = this.metadataFacetTemplate.isColumnsExist( key ); 1642 if ( !exists ) 1643 { 1644 String cf = this.cassandraArchivaManager.getMetadataFacetFamilyName(); 1645 this.metadataFacetTemplate.createMutator() // 1646 .addInsertion( key, cf, column( REPOSITORY_NAME.toString(), repositoryId ) ) // 1647 .addInsertion( key, cf, column( FACET_ID.toString(), metadataFacet.getFacetId() ) ) // 1648 .addInsertion( key, cf, column( NAME.toString(), metadataFacet.getName() ) ) // 1649 .addInsertion( key, cf, column( KEY.toString(), entry.getKey() ) ) // 1650 .addInsertion( key, cf, column( VALUE.toString(), entry.getValue() ) ) // 1651 .execute(); 1652 } 1653 else 1654 { 1655 ColumnFamilyUpdater<String, String> updater = this.metadataFacetTemplate.createUpdater( key ); 1656 addUpdateStringValue( updater, VALUE.toString(), entry.getValue() ); 1657 this.metadataFacetTemplate.update( updater ); 1658 } 1659 } 1660 } 1661 } 1662 1663 @Override 1664 public void removeMetadataFacets( final String repositoryId, final String facetId ) 1665 throws MetadataRepositoryException 1666 { 1667 1668 QueryResult<OrderedRows<String, String, String>> result = HFactory // 1669 .createRangeSlicesQuery( keyspace, ss, ss, ss ) // 1670 .setColumnFamily( cassandraArchivaManager.getMetadataFacetFamilyName() ) // 1671 .setColumnNames( KEY.toString(), VALUE.toString() ) // 1672 .addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) // 1673 .addEqualsExpression( FACET_ID.toString(), facetId ) // 1674 .execute(); 1675 1676 for ( Row<String, String, String> row : result.get() ) 1677 { 1678 this.metadataFacetTemplate.deleteRow( row.getKey() ); 1679 } 1680 1681 } 1682 1683 @Override 1684 public void removeMetadataFacet( final String repositoryId, final String facetId, final String name ) 1685 throws MetadataRepositoryException 1686 { 1687 1688 QueryResult<OrderedRows<String, String, String>> result = HFactory // 1689 .createRangeSlicesQuery( keyspace, ss, ss, ss ) // 1690 .setColumnFamily( cassandraArchivaManager.getMetadataFacetFamilyName() ) // 1691 .setColumnNames( KEY.toString(), VALUE.toString() ) // 1692 .addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) // 1693 .addEqualsExpression( FACET_ID.toString(), facetId ) // 1694 .addEqualsExpression( NAME.toString(), name ) // 1695 .execute(); 1696 1697 for ( Row<String, String, String> row : result.get() ) 1698 { 1699 this.metadataFacetTemplate.deleteRow( row.getKey() ); 1700 } 1701 } 1702 1703 @Override 1704 public List<ArtifactMetadata> getArtifactsByDateRange( final String repositoryId, final Date startTime, 1705 final Date endTime ) 1706 throws MetadataRepositoryException 1707 { 1708 1709 LongSerializer ls = LongSerializer.get(); 1710 RangeSlicesQuery<String, String, Long> query = HFactory // 1711 .createRangeSlicesQuery( keyspace, ss, ss, ls ) // 1712 .setColumnFamily( cassandraArchivaManager.getArtifactMetadataFamilyName() ) // 1713 .setColumnNames( ArtifactMetadataModel.COLUMNS ); // 1714 1715 if ( startTime != null ) 1716 { 1717 query = query.addGteExpression( WHEN_GATHERED.toString(), startTime.getTime() ); 1718 } 1719 if ( endTime != null ) 1720 { 1721 query = query.addLteExpression( WHEN_GATHERED.toString(), endTime.getTime() ); 1722 } 1723 QueryResult<OrderedRows<String, String, Long>> result = query.execute(); 1724 1725 List<ArtifactMetadata> artifactMetadatas = new ArrayList<>( result.get().getCount() ); 1726 1727 for ( Row<String, String, Long> row : result.get() ) 1728 { 1729 ColumnSlice<String, Long> columnSlice = row.getColumnSlice(); 1730 String repositoryName = getAsStringValue( columnSlice, REPOSITORY_NAME.toString() ); 1731 if ( StringUtils.equals( repositoryName, repositoryId ) ) 1732 { 1733 1734 artifactMetadatas.add( mapArtifactMetadataLongColumnSlice( columnSlice ) ); 1735 } 1736 } 1737 1738 return artifactMetadatas; 1739 } 1740 1741 1742 protected ArtifactMetadata mapArtifactMetadataLongColumnSlice( ColumnSlice<String, Long> columnSlice ) 1743 { 1744 ArtifactMetadata artifactMetadata = new ArtifactMetadata(); 1745 artifactMetadata.setNamespace( getAsStringValue( columnSlice, NAMESPACE_ID.toString() ) ); 1746 artifactMetadata.setSize( getLongValue( columnSlice, SIZE.toString() ) ); 1747 artifactMetadata.setId( getAsStringValue( columnSlice, ID.toString() ) ); 1748 artifactMetadata.setFileLastModified( getLongValue( columnSlice, FILE_LAST_MODIFIED.toString() ) ); 1749 artifactMetadata.setMd5( getAsStringValue( columnSlice, MD5.toString() ) ); 1750 artifactMetadata.setProject( getAsStringValue( columnSlice, PROJECT.toString() ) ); 1751 artifactMetadata.setProjectVersion( getAsStringValue( columnSlice, PROJECT_VERSION.toString() ) ); 1752 artifactMetadata.setRepositoryId( getAsStringValue( columnSlice, REPOSITORY_NAME.toString() ) ); 1753 artifactMetadata.setSha1( getAsStringValue( columnSlice, SHA1.toString() ) ); 1754 artifactMetadata.setVersion( getAsStringValue( columnSlice, VERSION.toString() ) ); 1755 Long whenGathered = getLongValue( columnSlice, WHEN_GATHERED.toString() ); 1756 if ( whenGathered != null ) 1757 { 1758 artifactMetadata.setWhenGathered( new Date( whenGathered ) ); 1759 } 1760 return artifactMetadata; 1761 } 1762 1763 protected ArtifactMetadata mapArtifactMetadataStringColumnSlice( ColumnSlice<String, String> columnSlice ) 1764 { 1765 ArtifactMetadata artifactMetadata = new ArtifactMetadata(); 1766 artifactMetadata.setNamespace( getStringValue( columnSlice, NAMESPACE_ID.toString() ) ); 1767 artifactMetadata.setSize( getAsLongValue( columnSlice, SIZE.toString() ) ); 1768 artifactMetadata.setId( getStringValue( columnSlice, ID.toString() ) ); 1769 artifactMetadata.setFileLastModified( getAsLongValue( columnSlice, FILE_LAST_MODIFIED.toString() ) ); 1770 artifactMetadata.setMd5( getStringValue( columnSlice, MD5.toString() ) ); 1771 artifactMetadata.setProject( getStringValue( columnSlice, PROJECT.toString() ) ); 1772 artifactMetadata.setProjectVersion( getStringValue( columnSlice, PROJECT_VERSION.toString() ) ); 1773 artifactMetadata.setRepositoryId( getStringValue( columnSlice, REPOSITORY_NAME.toString() ) ); 1774 artifactMetadata.setSha1( getStringValue( columnSlice, SHA1.toString() ) ); 1775 artifactMetadata.setVersion( getStringValue( columnSlice, VERSION.toString() ) ); 1776 Long whenGathered = getAsLongValue( columnSlice, WHEN_GATHERED.toString() ); 1777 if ( whenGathered != null ) 1778 { 1779 artifactMetadata.setWhenGathered( new Date( whenGathered ) ); 1780 } 1781 return artifactMetadata; 1782 } 1783 1784 @Override 1785 public Collection<ArtifactMetadata> getArtifactsByChecksum( final String repositoryId, final String checksum ) 1786 throws MetadataRepositoryException 1787 { 1788 1789 // cql cannot run or in queries so running twice the query 1790 Map<String, ArtifactMetadata> artifactMetadataMap = new HashMap<>(); 1791 1792 RangeSlicesQuery<String, String, String> query = HFactory // 1793 .createRangeSlicesQuery( keyspace, ss, ss, ss ) // 1794 .setColumnFamily( cassandraArchivaManager.getArtifactMetadataFamilyName() ) // 1795 .setColumnNames( ArtifactMetadataModel.COLUMNS ); // 1796 1797 query = query.addEqualsExpression( SHA1.toString(), checksum ).addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ); 1798 1799 QueryResult<OrderedRows<String, String, String>> result = query.execute(); 1800 1801 for ( Row<String, String, String> row : result.get() ) 1802 { 1803 ColumnSlice<String, String> columnSlice = row.getColumnSlice(); 1804 1805 artifactMetadataMap.put( row.getKey(), mapArtifactMetadataStringColumnSlice( columnSlice ) ); 1806 1807 } 1808 1809 query = HFactory // 1810 .createRangeSlicesQuery( keyspace, ss, ss, ss ) // 1811 .setColumnFamily( cassandraArchivaManager.getArtifactMetadataFamilyName() ) // 1812 .setColumnNames( NAMESPACE_ID.toString(), SIZE.toString(), ID.toString(), FILE_LAST_MODIFIED.toString(), MD5.toString(), PROJECT.toString(), PROJECT_VERSION.toString(), 1813 REPOSITORY_NAME.toString(), VERSION.toString(), WHEN_GATHERED.toString(), SHA1.toString() ); // 1814 1815 query = query.addEqualsExpression( MD5.toString(), checksum ).addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ); 1816 1817 result = query.execute(); 1818 1819 for ( Row<String, String, String> row : result.get() ) 1820 { 1821 ColumnSlice<String, String> columnSlice = row.getColumnSlice(); 1822 1823 artifactMetadataMap.put( row.getKey(), mapArtifactMetadataStringColumnSlice( columnSlice ) ); 1824 1825 } 1826 1827 return artifactMetadataMap.values(); 1828 } 1829 1830 /** 1831 * Project version and artifact level metadata are stored in the same place, no distinctions in Cassandra 1832 * implementation, just calls {@link #getArtifactsByMetadata(String, String, String)} 1833 */ 1834 @Override 1835 public List<ArtifactMetadata> getArtifactsByProjectVersionMetadata( String key, String value, String repositoryId ) 1836 throws MetadataRepositoryException 1837 { 1838 return getArtifactsByMetadata( key, value, repositoryId ); 1839 } 1840 1841 @Override 1842 public List<ArtifactMetadata> getArtifactsByMetadata( String key, String value, String repositoryId ) 1843 throws MetadataRepositoryException 1844 { 1845 RangeSlicesQuery<String, String, String> query = 1846 HFactory.createRangeSlicesQuery( keyspace, ss, ss, ss ) // 1847 .setColumnFamily( cassandraArchivaManager.getMetadataFacetFamilyName() ) // 1848 .setColumnNames( MetadataFacetModel.COLUMNS ) // 1849 .addEqualsExpression( VALUE.toString(), value ); 1850 1851 if ( key != null ) 1852 { 1853 query.addEqualsExpression( KEY.toString(), key ); // 1854 } 1855 if ( repositoryId != null ) 1856 { 1857 query.addEqualsExpression( "repositoryName", repositoryId ); 1858 } 1859 1860 QueryResult<OrderedRows<String, String, String>> metadataFacetResult = query.execute(); 1861 if ( metadataFacetResult.get() == null || metadataFacetResult.get().getCount() < 1 ) 1862 { 1863 return Collections.emptyList(); 1864 } 1865 1866 List<ArtifactMetadata> artifactMetadatas = new LinkedList<ArtifactMetadata>(); 1867 1868 // TODO doing multiple queries, there should be a way to get all the artifactMetadatas for any number of 1869 // projects 1870 for ( Row<String, String, String> row : metadataFacetResult.get() ) 1871 { 1872 QueryResult<OrderedRows<String, String, String>> artifactMetadataResult = 1873 HFactory.createRangeSlicesQuery( keyspace, ss, ss, ss ) // 1874 .setColumnFamily( cassandraArchivaManager.getArtifactMetadataFamilyName() ) // 1875 .setColumnNames( ArtifactMetadataModel.COLUMNS ) // 1876 .setRowCount( Integer.MAX_VALUE ) // 1877 .addEqualsExpression( REPOSITORY_NAME.toString(), 1878 getStringValue( row.getColumnSlice(), REPOSITORY_NAME ) ) // 1879 .addEqualsExpression( NAMESPACE_ID.toString(), getStringValue( row.getColumnSlice(), NAMESPACE_ID ) ) // 1880 .addEqualsExpression( PROJECT.toString(), getStringValue( row.getColumnSlice(), PROJECT_ID ) ) // 1881 .addEqualsExpression( PROJECT_VERSION.toString(), 1882 getStringValue( row.getColumnSlice(), PROJECT_VERSION ) ) // 1883 .execute(); 1884 1885 if ( artifactMetadataResult.get() == null || artifactMetadataResult.get().getCount() < 1 ) 1886 { 1887 return Collections.emptyList(); 1888 } 1889 1890 for ( Row<String, String, String> artifactMetadataRow : artifactMetadataResult.get() ) 1891 { 1892 artifactMetadatas.add( mapArtifactMetadataStringColumnSlice( artifactMetadataRow.getColumnSlice() ) ); 1893 } 1894 } 1895 1896 return mapArtifactMetadataToArtifact( metadataFacetResult, artifactMetadatas ); 1897 } 1898 1899 @Override 1900 public List<ArtifactMetadata> getArtifactsByProperty( String key, String value, String repositoryId ) 1901 throws MetadataRepositoryException 1902 { 1903 QueryResult<OrderedRows<String, String, String>> result = 1904 HFactory.createRangeSlicesQuery( keyspace, ss, ss, ss ) // 1905 .setColumnFamily( cassandraArchivaManager.getProjectVersionMetadataFamilyName() ) // 1906 .setColumnNames( PROJECT_ID.toString(), REPOSITORY_NAME.toString(), NAMESPACE_ID.toString(), 1907 PROJECT_VERSION.toString() ) // 1908 .addEqualsExpression( key, value ) // 1909 .execute(); 1910 1911 int count = result.get().getCount(); 1912 1913 if ( count < 1 ) 1914 { 1915 return Collections.emptyList(); 1916 } 1917 1918 List<ArtifactMetadata> artifacts = new LinkedList<ArtifactMetadata>(); 1919 1920 for ( Row<String, String, String> row : result.get() ) 1921 { 1922 // TODO doing multiple queries, there should be a way to get all the artifactMetadatas for any number of 1923 // projects 1924 try 1925 { 1926 artifacts.addAll( getArtifacts( getStringValue( row.getColumnSlice(), REPOSITORY_NAME ), 1927 getStringValue( row.getColumnSlice(), NAMESPACE_ID ), 1928 getStringValue( row.getColumnSlice(), PROJECT_ID ), 1929 getStringValue( row.getColumnSlice(), PROJECT_VERSION ) ) ); 1930 } 1931 catch ( MetadataResolutionException e ) 1932 { 1933 // never raised 1934 throw new IllegalStateException( e ); 1935 } 1936 } 1937 return artifacts; 1938 } 1939 1940 @Override 1941 public void removeArtifact( final String repositoryId, final String namespace, final String project, 1942 final String version, final String id ) 1943 throws MetadataRepositoryException 1944 { 1945 logger.debug( "removeArtifact repositoryId: '{}', namespace: '{}', project: '{}', version: '{}', id: '{}'", 1946 repositoryId, namespace, project, version, id ); 1947 String key = 1948 new ArtifactMetadataModel.KeyBuilder().withRepositoryId( repositoryId ).withNamespace( namespace ).withId( 1949 id ).withProjectVersion( version ).withProject( project ).build(); 1950 1951 this.artifactMetadataTemplate.deleteRow( key ); 1952 1953 key = new ProjectVersionMetadataModel.KeyBuilder() // 1954 .withRepository( repositoryId ) // 1955 .withNamespace( namespace ) // 1956 .withProjectId( project ) // 1957 .withProjectVersion( version ) // 1958 .withId( id ) // 1959 .build(); 1960 1961 this.projectVersionMetadataTemplate.deleteRow( key ); 1962 } 1963 1964 @Override 1965 public void removeArtifact( ArtifactMetadata artifactMetadata, String baseVersion ) 1966 throws MetadataRepositoryException 1967 { 1968 logger.debug( "removeArtifact repositoryId: '{}', namespace: '{}', project: '{}', version: '{}', id: '{}'", 1969 artifactMetadata.getRepositoryId(), artifactMetadata.getNamespace(), 1970 artifactMetadata.getProject(), baseVersion, artifactMetadata.getId() ); 1971 String key = 1972 new ArtifactMetadataModel.KeyBuilder().withRepositoryId( artifactMetadata.getRepositoryId() ).withNamespace( 1973 artifactMetadata.getNamespace() ).withId( artifactMetadata.getId() ).withProjectVersion( 1974 baseVersion ).withProject( artifactMetadata.getProject() ).build(); 1975 1976 this.artifactMetadataTemplate.deleteRow( key ); 1977 1978 } 1979 1980 @Override 1981 public void removeArtifact( final String repositoryId, final String namespace, final String project, 1982 final String version, final MetadataFacet metadataFacet ) 1983 throws MetadataRepositoryException 1984 { 1985 1986 RangeSlicesQuery<String, String, String> query = HFactory // 1987 .createRangeSlicesQuery( keyspace, ss, ss, ss ) // 1988 .setColumnFamily( cassandraArchivaManager.getArtifactMetadataFamilyName() ) // 1989 .setColumnNames( NAMESPACE_ID.toString() ); // 1990 1991 query = query.addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) // 1992 .addEqualsExpression( NAMESPACE_ID.toString(), namespace ) // 1993 .addEqualsExpression( PROJECT.toString(), project ) // 1994 .addEqualsExpression( VERSION.toString(), version ); 1995 1996 QueryResult<OrderedRows<String, String, String>> result = query.execute(); 1997 1998 for ( Row<String, String, String> row : result.get() ) 1999 { 2000 this.artifactMetadataTemplate.deleteRow( row.getKey() ); 2001 } 2002 } 2003 2004 2005 @Override 2006 public List<ArtifactMetadata> getArtifacts( final String repositoryId ) 2007 throws MetadataRepositoryException 2008 { 2009 2010 RangeSlicesQuery<String, String, String> query = HFactory // 2011 .createRangeSlicesQuery( keyspace, ss, ss, ss ) // 2012 .setColumnFamily( cassandraArchivaManager.getArtifactMetadataFamilyName() ) // 2013 .setColumnNames( ArtifactMetadataModel.COLUMNS ); // 2014 2015 query = query.addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ); 2016 2017 QueryResult<OrderedRows<String, String, String>> result = query.execute(); 2018 2019 List<ArtifactMetadata> artifactMetadatas = new ArrayList<>( result.get().getCount() ); 2020 2021 for ( Row<String, String, String> row : result.get() ) 2022 { 2023 ColumnSlice<String, String> columnSlice = row.getColumnSlice(); 2024 2025 artifactMetadatas.add( mapArtifactMetadataStringColumnSlice( columnSlice ) ); 2026 2027 } 2028 2029 return artifactMetadatas; 2030 } 2031 2032 2033 @Override 2034 public Collection<ProjectVersionReference> getProjectReferences( String repoId, String namespace, String projectId, 2035 String projectVersion ) 2036 throws MetadataResolutionException 2037 { 2038 QueryResult<OrderedRows<String, String, String>> result = HFactory // 2039 .createRangeSlicesQuery( keyspace, ss, ss, ss ) // 2040 .setColumnFamily( cassandraArchivaManager.getDependencyFamilyName() ) // 2041 .setColumnNames( "projectVersionMetadataModel.key" ) // 2042 .addEqualsExpression( REPOSITORY_NAME.toString(), repoId ) // 2043 .addEqualsExpression( GROUP_ID.toString(), namespace ) // 2044 .addEqualsExpression( ARTIFACT_ID.toString(), projectId ) // 2045 .addEqualsExpression( VERSION.toString(), projectVersion ) // 2046 .execute(); 2047 2048 List<String> dependenciesIds = new ArrayList<>( result.get().getCount() ); 2049 2050 for ( Row<String, String, String> row : result.get().getList() ) 2051 { 2052 dependenciesIds.add( getStringValue( row.getColumnSlice(), "projectVersionMetadataModel.key" ) ); 2053 } 2054 2055 List<ProjectVersionReference> references = new ArrayList<>( result.get().getCount() ); 2056 2057 for ( String key : dependenciesIds ) 2058 { 2059 ColumnFamilyResult<String, String> columnFamilyResult = 2060 this.projectVersionMetadataTemplate.queryColumns( key ); 2061 references.add( new ProjectVersionReference( ProjectVersionReference.ReferenceType.DEPENDENCY, // 2062 columnFamilyResult.getString( PROJECT_ID.toString() ), // 2063 columnFamilyResult.getString( NAMESPACE_ID.toString() ), // 2064 columnFamilyResult.getString( PROJECT_VERSION.toString() ) ) ); 2065 } 2066 2067 return references; 2068 } 2069 2070 @Override 2071 public void removeProjectVersion( final String repoId, final String namespace, final String projectId, 2072 final String projectVersion ) 2073 throws MetadataRepositoryException 2074 { 2075 2076 QueryResult<OrderedRows<String, String, String>> result = HFactory // 2077 .createRangeSlicesQuery( keyspace, ss, ss, ss ) // 2078 .setColumnFamily( cassandraArchivaManager.getProjectVersionMetadataFamilyName() ) // 2079 .setColumnNames( VERSION.toString() ) // 2080 .addEqualsExpression( REPOSITORY_NAME.toString(), repoId ) // 2081 .addEqualsExpression( NAMESPACE_ID.toString(), namespace ) // 2082 .addEqualsExpression( PROJECT_ID.toString(), projectId ) // 2083 .addEqualsExpression( PROJECT_VERSION.toString(), projectVersion ) // 2084 .execute(); 2085 2086 for ( Row<String, String, String> row : result.get().getList() ) 2087 { 2088 this.projectVersionMetadataTemplate.deleteRow( row.getKey() ); 2089 removeMailingList( row.getKey() ); 2090 removeLicenses( row.getKey() ); 2091 removeDependencies( row.getKey() ); 2092 } 2093 2094 RangeSlicesQuery<String, String, String> query = HFactory // 2095 .createRangeSlicesQuery( keyspace, ss, ss, ss ) // 2096 .setColumnFamily( cassandraArchivaManager.getArtifactMetadataFamilyName() ) // 2097 .setColumnNames( NAMESPACE_ID.toString() ); // 2098 2099 query = query.addEqualsExpression( REPOSITORY_NAME.toString(), repoId ) // 2100 .addEqualsExpression( NAMESPACE_ID.toString(), namespace ) // 2101 .addEqualsExpression( PROJECT.toString(), projectId ) // 2102 .addEqualsExpression( PROJECT_VERSION.toString(), projectVersion ); 2103 2104 result = query.execute(); 2105 2106 for ( Row<String, String, String> row : result.get() ) 2107 { 2108 this.artifactMetadataTemplate.deleteRow( row.getKey() ); 2109 2110 } 2111 } 2112 2113 @Override 2114 public Collection<ArtifactMetadata> getArtifacts( final String repoId, final String namespace, 2115 final String projectId, final String projectVersion ) 2116 throws MetadataResolutionException 2117 { 2118 2119 QueryResult<OrderedRows<String, String, String>> result = 2120 HFactory.createRangeSlicesQuery( keyspace, ss, ss, ss ) // 2121 .setColumnFamily( cassandraArchivaManager.getArtifactMetadataFamilyName() ) // 2122 .setColumnNames( ArtifactMetadataModel.COLUMNS )// 2123 .setRowCount( Integer.MAX_VALUE ) // 2124 .addEqualsExpression( REPOSITORY_NAME.toString(), repoId ) // 2125 .addEqualsExpression( NAMESPACE_ID.toString(), namespace ) // 2126 .addEqualsExpression( PROJECT.toString(), projectId ) // 2127 .addEqualsExpression( PROJECT_VERSION.toString(), projectVersion ) // 2128 .execute(); 2129 2130 if ( result.get() == null || result.get().getCount() < 1 ) 2131 { 2132 return Collections.emptyList(); 2133 } 2134 2135 List<ArtifactMetadata> artifactMetadatas = new ArrayList<>( result.get().getCount() ); 2136 2137 for ( Row<String, String, String> row : result.get() ) 2138 { 2139 artifactMetadatas.add( mapArtifactMetadataStringColumnSlice( row.getColumnSlice() ) ); 2140 } 2141 2142 result = HFactory.createRangeSlicesQuery( keyspace, ss, ss, ss ) // 2143 .setColumnFamily( cassandraArchivaManager.getMetadataFacetFamilyName() ) // 2144 .setColumnNames( MetadataFacetModel.COLUMNS ) // 2145 .setRowCount( Integer.MAX_VALUE ) // 2146 .addEqualsExpression( REPOSITORY_NAME.toString(), repoId ) // 2147 .addEqualsExpression( NAMESPACE_ID.toString(), namespace ) // 2148 .addEqualsExpression( PROJECT_ID.toString(), projectId ) // 2149 .addEqualsExpression( PROJECT_VERSION.toString(), projectVersion ) // 2150 .execute(); 2151 2152 return mapArtifactMetadataToArtifact(result, artifactMetadatas); 2153 } 2154 2155 /** 2156 * Attach metadata to each of the ArtifactMetadata objects 2157 */ 2158 private List<ArtifactMetadata> mapArtifactMetadataToArtifact(QueryResult<OrderedRows<String, String, String>> result, List<ArtifactMetadata> artifactMetadatas) { 2159 if ( result.get() == null || result.get().getCount() < 1 ) 2160 { 2161 return artifactMetadatas; 2162 } 2163 2164 final List<MetadataFacetModel> metadataFacetModels = new ArrayList<>( result.get().getCount() ); 2165 2166 for ( Row<String, String, String> row : result.get() ) 2167 { 2168 ColumnSlice<String, String> columnSlice = row.getColumnSlice(); 2169 MetadataFacetModel metadataFacetModel = new MetadataFacetModel(); 2170 metadataFacetModel.setFacetId( getStringValue( columnSlice, FACET_ID.toString() ) ); 2171 metadataFacetModel.setName( getStringValue( columnSlice, NAME.toString() ) ); 2172 metadataFacetModel.setValue( getStringValue( columnSlice, VALUE.toString() ) ); 2173 metadataFacetModel.setKey( getStringValue( columnSlice, KEY.toString() ) ); 2174 metadataFacetModel.setProjectVersion( getStringValue( columnSlice, PROJECT_VERSION.toString() ) ); 2175 metadataFacetModels.add( metadataFacetModel ); 2176 } 2177 2178 // rebuild MetadataFacet for artifacts 2179 2180 for ( final ArtifactMetadata artifactMetadata : artifactMetadatas ) 2181 { 2182 Iterable<MetadataFacetModel> metadataFacetModelIterable = 2183 Iterables.filter( metadataFacetModels, new Predicate<MetadataFacetModel>() 2184 { 2185 @Override 2186 public boolean apply( MetadataFacetModel metadataFacetModel ) 2187 { 2188 if ( metadataFacetModel != null ) 2189 { 2190 return StringUtils.equals( artifactMetadata.getVersion(), 2191 metadataFacetModel.getProjectVersion() ); 2192 } 2193 return false; 2194 } 2195 } ); 2196 Iterator<MetadataFacetModel> iterator = metadataFacetModelIterable.iterator(); 2197 Map<String, List<MetadataFacetModel>> metadataFacetValuesPerFacetId = new HashMap<>(); 2198 while ( iterator.hasNext() ) 2199 { 2200 MetadataFacetModel metadataFacetModel = iterator.next(); 2201 List<MetadataFacetModel> values = metadataFacetValuesPerFacetId.get( metadataFacetModel.getName() ); 2202 if ( values == null ) 2203 { 2204 values = new ArrayList<>(); 2205 metadataFacetValuesPerFacetId.put( metadataFacetModel.getFacetId(), values ); 2206 } 2207 values.add( metadataFacetModel ); 2208 2209 } 2210 2211 for ( Map.Entry<String, List<MetadataFacetModel>> entry : metadataFacetValuesPerFacetId.entrySet() ) 2212 { 2213 MetadataFacetFactory metadataFacetFactory = metadataFacetFactories.get( entry.getKey() ); 2214 if ( metadataFacetFactory != null ) 2215 { 2216 List<MetadataFacetModel> facetModels = entry.getValue(); 2217 if ( !facetModels.isEmpty() ) 2218 { 2219 MetadataFacet metadataFacet = metadataFacetFactory.createMetadataFacet(); 2220 Map<String, String> props = new HashMap<>( facetModels.size() ); 2221 for ( MetadataFacetModel metadataFacetModel : facetModels ) 2222 { 2223 props.put( metadataFacetModel.getKey(), metadataFacetModel.getValue() ); 2224 } 2225 metadataFacet.fromProperties( props ); 2226 artifactMetadata.addFacet( metadataFacet ); 2227 } 2228 } 2229 } 2230 } 2231 2232 return artifactMetadatas; 2233 } 2234 2235 @Override 2236 public void save() 2237 { 2238 logger.trace( "save" ); 2239 } 2240 2241 @Override 2242 public void close() 2243 throws MetadataRepositoryException 2244 { 2245 logger.trace( "close" ); 2246 } 2247 2248 @Override 2249 public void revert() 2250 { 2251 logger.warn( "CassandraMetadataRepository cannot revert" ); 2252 } 2253 2254 @Override 2255 public boolean canObtainAccess( Class<?> aClass ) 2256 { 2257 return false; 2258 } 2259 2260 @Override 2261 public <T> T obtainAccess( Class<T> aClass ) 2262 throws MetadataRepositoryException 2263 { 2264 throw new IllegalArgumentException( 2265 "Access using " + aClass + " is not supported on the cassandra metadata storage" ); 2266 } 2267 2268 2269 private static class ModelMapperHolder 2270 { 2271 private static ModelMapper MODEL_MAPPER = new ModelMapper(); 2272 } 2273 2274 protected ModelMapper getModelMapper() 2275 { 2276 return ModelMapperHolder.MODEL_MAPPER; 2277 } 2278 2279 /** 2280 * This implementation just calls getArtifactsByMetadata( null, text, repositoryId ). We can't search artifacts by 2281 * any property. 2282 */ 2283 @Override 2284 public List<ArtifactMetadata> searchArtifacts( String text, String repositoryId, boolean exact ) 2285 throws MetadataRepositoryException 2286 { 2287 return getArtifactsByMetadata( null, text, repositoryId ); 2288 } 2289 2290 /** 2291 * The exact parameter is ignored as we can't do non exact searches in Cassandra 2292 */ 2293 @Override 2294 public List<ArtifactMetadata> searchArtifacts( String key, String text, String repositoryId, boolean exact ) 2295 throws MetadataRepositoryException 2296 { 2297 // TODO optimize 2298 List<ArtifactMetadata> artifacts = new LinkedList<ArtifactMetadata>(); 2299 artifacts.addAll( getArtifactsByMetadata( key, text, repositoryId ) ); 2300 artifacts.addAll( getArtifactsByProperty( key, text, repositoryId ) ); 2301 return artifacts; 2302 } 2303}