1 package org.apache.archiva.metadata.repository.cassandra;
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 * KIND, either express or implied. See the License for the
18 * specific language governing permissions and limitations
22 import me.prettyprint.cassandra.serializers.LongSerializer;
23 import me.prettyprint.cassandra.serializers.StringSerializer;
24 import me.prettyprint.cassandra.service.template.ColumnFamilyResult;
25 import me.prettyprint.cassandra.service.template.ColumnFamilyTemplate;
26 import me.prettyprint.cassandra.service.template.ColumnFamilyUpdater;
27 import me.prettyprint.cassandra.service.template.ThriftColumnFamilyTemplate;
28 import me.prettyprint.hector.api.Keyspace;
29 import me.prettyprint.hector.api.beans.ColumnSlice;
30 import me.prettyprint.hector.api.beans.OrderedRows;
31 import me.prettyprint.hector.api.beans.Row;
32 import me.prettyprint.hector.api.exceptions.HInvalidRequestException;
33 import me.prettyprint.hector.api.factory.HFactory;
34 import me.prettyprint.hector.api.mutation.MutationResult;
35 import me.prettyprint.hector.api.mutation.Mutator;
36 import me.prettyprint.hector.api.query.QueryResult;
37 import me.prettyprint.hector.api.query.RangeSlicesQuery;
38 import org.apache.archiva.checksum.ChecksumAlgorithm;
39 import org.apache.archiva.metadata.QueryParameter;
40 import org.apache.archiva.metadata.model.ArtifactMetadata;
41 import org.apache.archiva.metadata.model.CiManagement;
42 import org.apache.archiva.metadata.model.Dependency;
43 import org.apache.archiva.metadata.model.FacetedMetadata;
44 import org.apache.archiva.metadata.model.IssueManagement;
45 import org.apache.archiva.metadata.model.License;
46 import org.apache.archiva.metadata.model.MailingList;
47 import org.apache.archiva.metadata.model.MetadataFacet;
48 import org.apache.archiva.metadata.model.MetadataFacetFactory;
49 import org.apache.archiva.metadata.model.Organization;
50 import org.apache.archiva.metadata.model.ProjectMetadata;
51 import org.apache.archiva.metadata.model.ProjectVersionMetadata;
52 import org.apache.archiva.metadata.model.ProjectVersionReference;
53 import org.apache.archiva.metadata.model.Scm;
54 import org.apache.archiva.metadata.repository.AbstractMetadataRepository;
55 import org.apache.archiva.metadata.repository.MetadataRepository;
56 import org.apache.archiva.metadata.repository.MetadataRepositoryException;
57 import org.apache.archiva.metadata.repository.MetadataResolutionException;
58 import org.apache.archiva.metadata.repository.MetadataService;
59 import org.apache.archiva.metadata.repository.RepositorySession;
60 import org.apache.archiva.metadata.repository.cassandra.model.ArtifactMetadataModel;
61 import org.apache.archiva.metadata.repository.cassandra.model.MetadataFacetModel;
62 import org.apache.archiva.metadata.repository.cassandra.model.Namespace;
63 import org.apache.archiva.metadata.repository.cassandra.model.Project;
64 import org.apache.archiva.metadata.repository.cassandra.model.ProjectVersionMetadataModel;
65 import org.apache.archiva.metadata.repository.cassandra.model.Repository;
66 import org.apache.commons.lang3.StringUtils;
67 import org.modelmapper.ModelMapper;
68 import org.slf4j.Logger;
69 import org.slf4j.LoggerFactory;
71 import java.time.Instant;
72 import java.time.ZonedDateTime;
73 import java.util.ArrayList;
74 import java.util.Collections;
75 import java.util.Comparator;
76 import java.util.HashMap;
77 import java.util.HashSet;
78 import java.util.Iterator;
79 import java.util.LinkedList;
80 import java.util.List;
83 import java.util.Spliterator;
84 import java.util.UUID;
85 import java.util.function.BiFunction;
86 import java.util.function.Consumer;
87 import java.util.stream.Collectors;
88 import java.util.stream.Stream;
89 import java.util.stream.StreamSupport;
91 import static org.apache.archiva.metadata.model.ModelInfo.STORAGE_TZ;
92 import static org.apache.archiva.metadata.repository.cassandra.CassandraUtils.*;
93 import static org.apache.archiva.metadata.repository.cassandra.model.ColumnNames.*;
96 * @author Olivier Lamy
99 public class CassandraMetadataRepository
100 extends AbstractMetadataRepository implements MetadataRepository
103 private static final String ARTIFACT_METADATA_MODEL_KEY = "artifactMetadataModel.key";
104 private Logger logger = LoggerFactory.getLogger( getClass() );
106 private final CassandraArchivaManager cassandraArchivaManager;
108 private final ColumnFamilyTemplate<String, String> projectVersionMetadataTemplate;
110 private final ColumnFamilyTemplate<String, String> projectTemplate;
112 private final ColumnFamilyTemplate<String, String> artifactMetadataTemplate;
114 private final ColumnFamilyTemplate<String, String> metadataFacetTemplate;
116 private final ColumnFamilyTemplate<String, String> mailingListTemplate;
118 private final ColumnFamilyTemplate<String, String> licenseTemplate;
120 private final ColumnFamilyTemplate<String, String> dependencyTemplate;
122 private final ColumnFamilyTemplate<String, String> checksumTemplate;
124 private final Keyspace keyspace;
126 private final StringSerializer ss = StringSerializer.get();
128 public CassandraMetadataRepository( MetadataService metadataService,
129 CassandraArchivaManager cassandraArchivaManager )
131 super( metadataService );
132 this.cassandraArchivaManager = cassandraArchivaManager;
133 this.keyspace = cassandraArchivaManager.getKeyspace();
135 this.projectVersionMetadataTemplate =
136 new ThriftColumnFamilyTemplate<>( cassandraArchivaManager.getKeyspace(), //
137 cassandraArchivaManager.getProjectVersionMetadataFamilyName(), //
138 StringSerializer.get(), //
139 StringSerializer.get() );
141 this.projectTemplate = new ThriftColumnFamilyTemplate<>( cassandraArchivaManager.getKeyspace(), //
142 cassandraArchivaManager.getProjectFamilyName(), //
144 StringSerializer.get(), //
145 StringSerializer.get() );
147 this.artifactMetadataTemplate = new ThriftColumnFamilyTemplate<>( cassandraArchivaManager.getKeyspace(), //
148 cassandraArchivaManager.getArtifactMetadataFamilyName(),
149 StringSerializer.get(), //
150 StringSerializer.get() );
152 this.metadataFacetTemplate = new ThriftColumnFamilyTemplate<>( cassandraArchivaManager.getKeyspace(), //
153 cassandraArchivaManager.getMetadataFacetFamilyName(),
155 StringSerializer.get(), //
156 StringSerializer.get() );
158 this.mailingListTemplate = new ThriftColumnFamilyTemplate<>( cassandraArchivaManager.getKeyspace(), //
159 cassandraArchivaManager.getMailingListFamilyName(),
161 StringSerializer.get(), //
162 StringSerializer.get() );
164 this.licenseTemplate = new ThriftColumnFamilyTemplate<>( cassandraArchivaManager.getKeyspace(), //
165 cassandraArchivaManager.getLicenseFamilyName(),
167 StringSerializer.get(), //
168 StringSerializer.get() );
170 this.dependencyTemplate = new ThriftColumnFamilyTemplate<>( cassandraArchivaManager.getKeyspace(), //
171 cassandraArchivaManager.getDependencyFamilyName(),
173 StringSerializer.get(), //
174 StringSerializer.get() );
176 this.checksumTemplate = new ThriftColumnFamilyTemplate<>( cassandraArchivaManager.getKeyspace(), //
177 cassandraArchivaManager.getChecksumFamilyName(),
179 StringSerializer.get(), //
180 StringSerializer.get() );
185 * if the repository doesn't exist it will be created
187 * @param repositoryId
190 public Repository getOrCreateRepository( String repositoryId )
191 throws MetadataRepositoryException
193 String cf = cassandraArchivaManager.getRepositoryFamilyName();
195 QueryResult<OrderedRows<String, String, String>> result = HFactory //
196 .createRangeSlicesQuery( keyspace, StringSerializer.get(), StringSerializer.get(),
197 StringSerializer.get() ) //
198 .setColumnFamily( cf ) //
199 .setColumnNames( REPOSITORY_NAME.toString() ) //
200 .addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) //
203 if ( result.get().getCount() < 1 )
205 // we need to create the repository
206 Repository repository = new Repository( repositoryId );
210 MutationResult mutationResult = HFactory.createMutator( keyspace, StringSerializer.get() ) //
211 .addInsertion( repositoryId, cf,
212 CassandraUtils.column( REPOSITORY_NAME.toString(), repository.getName() ) ) //
214 logger.debug( "time to insert repository: {}", mutationResult.getExecutionTimeMicro() );
217 catch ( HInvalidRequestException e )
219 logger.error( e.getMessage(), e );
220 throw new MetadataRepositoryException( e.getMessage(), e );
225 return new Repository(
226 result.get().getList().get( 0 ).getColumnSlice().getColumnByName( REPOSITORY_NAME.toString() ).getValue() );
230 protected Repository getRepository( String repositoryId )
231 throws MetadataRepositoryException
234 QueryResult<OrderedRows<String, String, String>> result = HFactory //
235 .createRangeSlicesQuery( keyspace, StringSerializer.get(), StringSerializer.get(),
236 StringSerializer.get() ) //
237 .setColumnFamily( cassandraArchivaManager.getRepositoryFamilyName() ) //
238 .setColumnNames( REPOSITORY_NAME.toString() ) //
239 .addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) //
241 return ( result.get().getCount() > 0 ) ? new Repository( repositoryId ) : null;
245 public void updateNamespace( RepositorySession session, String repositoryId, String namespaceId )
246 throws MetadataRepositoryException
248 updateOrAddNamespace( repositoryId, namespaceId );
251 private Namespace updateOrAddNamespace( String repositoryId, String namespaceId )
252 throws MetadataRepositoryException
256 Repository repository = getOrCreateRepository( repositoryId );
259 new Namespace.KeyBuilder().withNamespace( namespaceId ).withRepositoryId( repositoryId ).build();
261 Namespace namespace = getNamespace( repositoryId, namespaceId );
262 if ( namespace == null )
264 String cf = cassandraArchivaManager.getNamespaceFamilyName();
265 namespace = new Namespace( namespaceId, repository );
266 HFactory.createMutator( keyspace, StringSerializer.get() )
268 .addInsertion( key, cf, CassandraUtils.column( NAME.toString(), namespace.getName() ) ) //
269 .addInsertion( key, cf, CassandraUtils.column( REPOSITORY_NAME.toString(), repository.getName() ) ) //
275 catch ( HInvalidRequestException e )
277 logger.error( e.getMessage(), e );
278 throw new MetadataRepositoryException( e.getMessage(), e );
282 protected Namespace getNamespace( String repositoryId, String namespaceId )
285 QueryResult<OrderedRows<String, String, String>> result = HFactory //
286 .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
287 .setColumnFamily( cassandraArchivaManager.getNamespaceFamilyName() ) //
288 .setColumnNames( REPOSITORY_NAME.toString(), NAME.toString() ) //
289 .addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) //
290 .addEqualsExpression( NAME.toString(), namespaceId ) //
292 if ( result.get().getCount() > 0 )
294 ColumnSlice<String, String> columnSlice = result.get().getList().get( 0 ).getColumnSlice();
295 return new Namespace( getStringValue( columnSlice, NAME.toString() ), //
296 new Repository( getStringValue( columnSlice, REPOSITORY_NAME.toString() ) ) );
304 public void removeNamespace( RepositorySession session, String repositoryId, String namespaceId )
305 throws MetadataRepositoryException
310 String key = new Namespace.KeyBuilder() //
311 .withNamespace( namespaceId ) //
312 .withRepositoryId( repositoryId ) //
315 HFactory.createMutator( cassandraArchivaManager.getKeyspace(), new StringSerializer() ) //
316 .addDeletion( key, cassandraArchivaManager.getNamespaceFamilyName() ) //
319 QueryResult<OrderedRows<String, String, String>> result = HFactory //
320 .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
321 .setColumnFamily( cassandraArchivaManager.getProjectFamilyName() ) //
322 .setColumnNames( REPOSITORY_NAME.toString() ) //
323 .addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) //
324 .addEqualsExpression( NAMESPACE_ID.toString(), namespaceId ) //
327 for ( Row<String, String, String> row : result.get() )
329 this.projectTemplate.deleteRow( row.getKey() );
333 .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
334 .setColumnFamily( cassandraArchivaManager.getProjectVersionMetadataFamilyName() ) //
335 .setColumnNames( REPOSITORY_NAME.toString() ) //
336 .addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) //
337 .addEqualsExpression( NAMESPACE_ID.toString(), namespaceId ) //
340 for ( Row<String, String, String> row : result.get() )
342 this.projectVersionMetadataTemplate.deleteRow( row.getKey() );
343 removeMailingList( row.getKey() );
347 .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
348 .setColumnFamily( cassandraArchivaManager.getArtifactMetadataFamilyName() ) //
349 .setColumnNames( REPOSITORY_NAME.toString() ) //
350 .addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) //
351 .addEqualsExpression( NAMESPACE_ID.toString(), namespaceId ) //
354 for ( Row<String, String, String> row : result.get() )
356 this.artifactMetadataTemplate.deleteRow( row.getKey() );
360 .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
361 .setColumnFamily( cassandraArchivaManager.getMetadataFacetFamilyName() ) //
362 .setColumnNames( REPOSITORY_NAME.toString() ) //
363 .addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) //
364 .addEqualsExpression( NAMESPACE_ID.toString(), namespaceId ) //
367 for ( Row<String, String, String> row : result.get() )
369 this.metadataFacetTemplate.deleteRow( row.getKey() );
373 catch ( HInvalidRequestException e )
375 logger.error( e.getMessage(), e );
376 throw new MetadataRepositoryException( e.getMessage(), e );
382 public void removeRepository( RepositorySession session, final String repositoryId )
383 throws MetadataRepositoryException
386 // TODO use cql queries to delete all
387 List<String> namespacesKey = new ArrayList<>();
389 QueryResult<OrderedRows<String, String, String>> result = HFactory //
390 .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
391 .setColumnFamily( cassandraArchivaManager.getNamespaceFamilyName() ) //
392 .setColumnNames( REPOSITORY_NAME.toString() ) //
393 .addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) //
396 for ( Row<String, String, String> row : result.get().getList() )
398 namespacesKey.add( row.getKey() );
401 HFactory.createMutator( cassandraArchivaManager.getKeyspace(), ss ) //
402 .addDeletion( namespacesKey, cassandraArchivaManager.getNamespaceFamilyName() ) //
405 //delete repositoryId
406 HFactory.createMutator( cassandraArchivaManager.getKeyspace(), ss ) //
407 .addDeletion( repositoryId, cassandraArchivaManager.getRepositoryFamilyName() ) //
411 .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
412 .setColumnFamily( cassandraArchivaManager.getProjectFamilyName() ) //
413 .setColumnNames( REPOSITORY_NAME.toString() ) //
414 .addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) //
417 for ( Row<String, String, String> row : result.get() )
419 this.projectTemplate.deleteRow( row.getKey() );
423 .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
424 .setColumnFamily( cassandraArchivaManager.getProjectVersionMetadataFamilyName() ) //
425 .setColumnNames( REPOSITORY_NAME.toString() ) //
426 .addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) //
429 for ( Row<String, String, String> row : result.get() )
431 this.projectVersionMetadataTemplate.deleteRow( row.getKey() );
432 removeMailingList( row.getKey() );
436 .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
437 .setColumnFamily( cassandraArchivaManager.getArtifactMetadataFamilyName() ) //
438 .setColumnNames( REPOSITORY_NAME.toString() ) //
439 .addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) //
442 for ( Row<String, String, String> row : result.get() )
444 this.artifactMetadataTemplate.deleteRow( row.getKey() );
448 .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
449 .setColumnFamily( cassandraArchivaManager.getMetadataFacetFamilyName() ) //
450 .setColumnNames( REPOSITORY_NAME.toString() ) //
451 .addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) //
454 for ( Row<String, String, String> row : result.get() )
456 this.metadataFacetTemplate.deleteRow( row.getKey() );
462 // FIXME this one need peformance improvement maybe a cache?
464 public List<String> getRootNamespaces( RepositorySession session, final String repoId )
465 throws MetadataResolutionException
468 QueryResult<OrderedRows<String, String, String>> result = HFactory //
469 .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
470 .setColumnFamily( cassandraArchivaManager.getNamespaceFamilyName() ) //
471 .setColumnNames( NAME.toString() ) //
472 .addEqualsExpression( REPOSITORY_NAME.toString(), repoId ) //
475 Set<String> namespaces = new HashSet<>( result.get( ).getCount( ) );
477 for ( Row<String, String, String> row : result.get() )
479 namespaces.add( StringUtils.substringBefore( getStringValue( row.getColumnSlice(), NAME.toString() ), "." ) );
482 return new ArrayList<>( namespaces );
485 // FIXME this one need peformance improvement maybe a cache?
487 public List<String> getChildNamespaces( RepositorySession session, final String repoId, final String namespaceId )
488 throws MetadataResolutionException
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 ) //
498 List<String> namespaces = new ArrayList<>( result.get().getCount() );
500 for ( Row<String, String, String> row : result.get() )
502 String currentNamespace = getStringValue( row.getColumnSlice(), NAME.toString() );
503 if ( StringUtils.startsWith( currentNamespace, namespaceId ) //
504 && ( StringUtils.length( currentNamespace ) > StringUtils.length( namespaceId ) ) )
506 // store after namespaceId '.' but before next '.'
507 // call org namespace org.apache.maven.shared -> stored apache
509 String calledNamespace = StringUtils.endsWith( namespaceId, "." ) ? namespaceId : namespaceId + ".";
510 String storedNamespace = StringUtils.substringAfter( currentNamespace, calledNamespace );
512 storedNamespace = StringUtils.substringBefore( storedNamespace, "." );
514 namespaces.add( storedNamespace );
522 // only use for testing purpose
523 protected List<String> getNamespaces( final String repoId )
524 throws MetadataResolutionException
527 QueryResult<OrderedRows<String, String, String>> result = HFactory //
528 .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
529 .setColumnFamily( cassandraArchivaManager.getNamespaceFamilyName() ) //
530 .setColumnNames( NAME.toString() ) //
531 .addEqualsExpression( REPOSITORY_NAME.toString(), repoId ) //
534 List<String> namespaces = new ArrayList<>( result.get().getCount() );
536 for ( Row<String, String, String> row : result.get() )
538 namespaces.add( getStringValue( row.getColumnSlice(), NAME.toString() ) );
546 public void updateProject( RepositorySession session, String repositoryId, ProjectMetadata projectMetadata )
547 throws MetadataRepositoryException
550 QueryResult<OrderedRows<String, String, String>> result = HFactory //
551 .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
552 .setColumnFamily( cassandraArchivaManager.getProjectFamilyName() ) //
553 .setColumnNames( PROJECT_ID.toString() ) //
554 .addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) //
555 .addEqualsExpression( NAMESPACE_ID.toString(), projectMetadata.getNamespace() ) //
556 .addEqualsExpression( PROJECT_ID.toString(), projectMetadata.getId() ) //
559 // project exists ? if yes return nothing to update here
560 if ( result.get( ).getCount( ) <= 0 )
562 Namespace namespace = updateOrAddNamespace( repositoryId, projectMetadata.getNamespace() );
565 new Project.KeyBuilder().withProjectId( projectMetadata.getId() ).withNamespace( namespace ).build();
567 String cf = cassandraArchivaManager.getProjectFamilyName();
568 projectTemplate.createMutator()
570 .addInsertion( key, cf, CassandraUtils.column( PROJECT_ID.toString(), projectMetadata.getId() ) ) //
571 .addInsertion( key, cf, CassandraUtils.column( REPOSITORY_NAME.toString(), repositoryId ) ) //
572 .addInsertion( key, cf, CassandraUtils.column( NAMESPACE_ID.toString(), projectMetadata.getNamespace() ) )//
578 public List<String> getProjects( RepositorySession session, final String repoId, final String namespace )
579 throws MetadataResolutionException
582 QueryResult<OrderedRows<String, String, String>> result = HFactory //
583 .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
584 .setColumnFamily( cassandraArchivaManager.getProjectFamilyName() ) //
585 .setColumnNames( PROJECT_ID.toString() ) //
586 .addEqualsExpression( REPOSITORY_NAME.toString(), repoId ) //
587 .addEqualsExpression( NAMESPACE_ID.toString(), namespace ) //
590 final Set<String> projects = new HashSet<>( result.get( ).getCount( ) );
592 for ( Row<String, String, String> row : result.get() )
594 projects.add( getStringValue( row.getColumnSlice(), PROJECT_ID.toString() ) );
597 return new ArrayList<>( projects );
601 public void removeProject( RepositorySession session, final String repositoryId, final String namespaceId, final String projectId )
602 throws MetadataRepositoryException
605 String key = new Project.KeyBuilder() //
606 .withProjectId( projectId ) //
607 .withNamespace( new Namespace( namespaceId, new Repository( repositoryId ) ) ) //
610 this.projectTemplate.deleteRow( key );
612 QueryResult<OrderedRows<String, String, String>> result = HFactory //
613 .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
614 .setColumnFamily( cassandraArchivaManager.getProjectVersionMetadataFamilyName() ) //
615 .setColumnNames( ID.toString() ) //
616 .addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) //
617 .addEqualsExpression( NAMESPACE_ID.toString(), namespaceId ) //
618 .addEqualsExpression( PROJECT_ID.toString(), projectId ) //
621 for ( Row<String, String, String> row : result.get() )
623 this.projectVersionMetadataTemplate.deleteRow( row.getKey() );
624 removeMailingList( row.getKey() );
628 .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
629 .setColumnFamily( cassandraArchivaManager.getArtifactMetadataFamilyName() ) //
630 .setColumnNames( PROJECT_ID.toString() ) //
631 .addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) //
632 .addEqualsExpression( NAMESPACE_ID.toString(), namespaceId ) //
633 .addEqualsExpression( PROJECT_ID.toString(), projectId ) //
636 for ( Row<String, String, String> row : result.get() )
638 this.artifactMetadataTemplate.deleteRow( row.getKey() );
643 public List<String> getProjectVersions( RepositorySession session, final String repoId, final String namespace, final String projectId )
644 throws MetadataResolutionException
647 QueryResult<OrderedRows<String, String, String>> result = HFactory //
648 .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
649 .setColumnFamily( cassandraArchivaManager.getProjectVersionMetadataFamilyName() ) //
650 .setColumnNames( PROJECT_VERSION.toString() ) //
651 .addEqualsExpression( REPOSITORY_NAME.toString(), repoId ) //
652 .addEqualsExpression( NAMESPACE_ID.toString(), namespace ) //
653 .addEqualsExpression( PROJECT_ID.toString(), projectId ) //
656 int count = result.get().getCount();
660 return Collections.emptyList();
663 Set<String> versions = new HashSet<>( count );
665 for ( Row<String, String, String> orderedRows : result.get() )
667 versions.add( getStringValue( orderedRows.getColumnSlice(), PROJECT_VERSION.toString() ) );
670 return new ArrayList<>( versions );
675 public ProjectMetadata getProject( RepositorySession session, final String repoId, final String namespace, final String id )
676 throws MetadataResolutionException
679 QueryResult<OrderedRows<String, String, String>> result = HFactory //
680 .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
681 .setColumnFamily( cassandraArchivaManager.getProjectFamilyName() ) //
682 .setColumnNames( PROJECT_ID.toString() ) //
683 .addEqualsExpression( REPOSITORY_NAME.toString(), repoId ) //
684 .addEqualsExpression( NAMESPACE_ID.toString(), namespace ) //
685 .addEqualsExpression( PROJECT_ID.toString(), id ) //
688 int count = result.get().getCount();
695 ProjectMetadata projectMetadata = new ProjectMetadata();
696 projectMetadata.setId( id );
697 projectMetadata.setNamespace( namespace );
699 logger.debug( "getProject repoId: {}, namespace: {}, projectId: {} -> {}", repoId, namespace, id,
702 return projectMetadata;
705 protected ProjectVersionMetadataModel mapProjectVersionMetadataModel( ColumnSlice<String, String> columnSlice )
707 ProjectVersionMetadataModel projectVersionMetadataModel = new ProjectVersionMetadataModel();
708 projectVersionMetadataModel.setId( getStringValue( columnSlice, ID.toString() ) );
709 projectVersionMetadataModel.setDescription( getStringValue( columnSlice, DESCRIPTION.toString() ) );
710 projectVersionMetadataModel.setName( getStringValue( columnSlice, NAME.toString() ) );
711 Namespace namespace = new Namespace( getStringValue( columnSlice, NAMESPACE_ID.toString() ), //
712 new Repository( getStringValue( columnSlice, REPOSITORY_NAME.toString() ) ) );
713 projectVersionMetadataModel.setNamespace( namespace );
714 projectVersionMetadataModel.setIncomplete(
715 Boolean.parseBoolean( getStringValue( columnSlice, "incomplete" ) ) );
716 projectVersionMetadataModel.setProjectId( getStringValue( columnSlice, PROJECT_ID.toString() ) );
717 projectVersionMetadataModel.setUrl( getStringValue( columnSlice, URL.toString() ) );
718 return projectVersionMetadataModel;
723 public void updateProjectVersion( RepositorySession session, String repositoryId, String namespaceId, String projectId,
724 ProjectVersionMetadata versionMetadata )
725 throws MetadataRepositoryException
729 Namespace namespace = getNamespace( repositoryId, namespaceId );
731 if ( namespace == null )
733 updateOrAddNamespace( repositoryId, namespaceId );
736 if ( getProject( session, repositoryId, namespaceId, projectId ) == null )
738 ProjectMetadata projectMetadata = new ProjectMetadata();
739 projectMetadata.setNamespace( namespaceId );
740 projectMetadata.setId( projectId );
741 updateProject( session, repositoryId, projectMetadata );
745 catch ( MetadataResolutionException e )
747 throw new MetadataRepositoryException( e.getMessage(), e );
750 QueryResult<OrderedRows<String, String, String>> result = HFactory //
751 .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
752 .setColumnFamily( cassandraArchivaManager.getProjectVersionMetadataFamilyName() ) //
753 .setColumnNames( PROJECT_VERSION.toString() ) //
754 .addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) //
755 .addEqualsExpression( NAMESPACE_ID.toString(), namespaceId ) //
756 .addEqualsExpression( PROJECT_ID.toString(), projectId ) //
757 .addEqualsExpression( PROJECT_VERSION.toString(), versionMetadata.getId() ) //
760 ProjectVersionMetadataModel projectVersionMetadataModel;
761 boolean creation = true;
762 if ( result.get().getCount() > 0 )
764 projectVersionMetadataModel =
765 mapProjectVersionMetadataModel( result.get().getList().get( 0 ).getColumnSlice() );
770 projectVersionMetadataModel = getModelMapper().map( versionMetadata, ProjectVersionMetadataModel.class );
773 projectVersionMetadataModel.setProjectId( projectId );
774 projectVersionMetadataModel.setNamespace( new Namespace( namespaceId, new Repository( repositoryId ) ) );
776 projectVersionMetadataModel.setCiManagement( versionMetadata.getCiManagement() );
777 projectVersionMetadataModel.setIssueManagement( versionMetadata.getIssueManagement() );
778 projectVersionMetadataModel.setOrganization( versionMetadata.getOrganization() );
779 projectVersionMetadataModel.setScm( versionMetadata.getScm() );
781 projectVersionMetadataModel.setMailingLists( versionMetadata.getMailingLists() );
782 projectVersionMetadataModel.setDependencies( versionMetadata.getDependencies() );
783 projectVersionMetadataModel.setLicenses( versionMetadata.getLicenses() );
785 // we don't test of repository and namespace really exist !
786 String key = new ProjectVersionMetadataModel.KeyBuilder() //
787 .withRepository( repositoryId ) //
788 .withNamespace( namespaceId ) //
789 .withProjectId( projectId ) //
790 .withProjectVersion( versionMetadata.getVersion() ) //
791 .withId( versionMetadata.getId() ) //
794 // FIXME nested objects to store!!!
797 String cf = cassandraArchivaManager.getProjectVersionMetadataFamilyName();
798 Mutator<String> mutator = projectVersionMetadataTemplate.createMutator()
800 .addInsertion( key, cf, column( PROJECT_ID.toString(), projectId ) ) //
801 .addInsertion( key, cf, column( REPOSITORY_NAME.toString(), repositoryId ) ) //
802 .addInsertion( key, cf, column( NAMESPACE_ID.toString(), namespaceId ) )//
803 .addInsertion( key, cf, column( PROJECT_VERSION.toString(), versionMetadata.getVersion() ) ); //
805 addInsertion( mutator, key, cf, DESCRIPTION.toString(), versionMetadata.getDescription() );
807 addInsertion( mutator, key, cf, NAME.toString(), versionMetadata.getName() );
809 addInsertion( mutator, key, cf, "incomplete", Boolean.toString( versionMetadata.isIncomplete() ) );
811 addInsertion( mutator, key, cf, URL.toString(), versionMetadata.getUrl() );
813 CiManagement ci = versionMetadata.getCiManagement();
816 addInsertion( mutator, key, cf, "ciManagement.system", ci.getSystem() );
817 addInsertion( mutator, key, cf, "ciManagement.url", ci.getUrl() );
822 IssueManagement issueManagement = versionMetadata.getIssueManagement();
824 if ( issueManagement != null )
826 addInsertion( mutator, key, cf, "issueManagement.system", issueManagement.getSystem() );
827 addInsertion( mutator, key, cf, "issueManagement.url", issueManagement.getUrl() );
832 Organization organization = versionMetadata.getOrganization();
833 if ( organization != null )
835 addInsertion( mutator, key, cf, "organization.name", organization.getName() );
836 addInsertion( mutator, key, cf, "organization.url", organization.getUrl() );
841 Scm scm = versionMetadata.getScm();
844 addInsertion( mutator, key, cf, "scm.url", scm.getUrl() );
845 addInsertion( mutator, key, cf, "scm.connection", scm.getConnection() );
846 addInsertion( mutator, key, cf, "scm.developerConnection", scm.getDeveloperConnection() );
850 recordMailingList( key, versionMetadata.getMailingLists() );
852 recordLicenses( key, versionMetadata.getLicenses() );
854 recordDependencies( key, versionMetadata.getDependencies(), repositoryId );
860 ColumnFamilyUpdater<String, String> updater = projectVersionMetadataTemplate.createUpdater( key );
861 addUpdateStringValue( updater, PROJECT_ID.toString(), projectId );
862 addUpdateStringValue( updater, REPOSITORY_NAME.toString(), repositoryId );
863 addUpdateStringValue( updater, NAMESPACE_ID.toString(), namespaceId );
864 addUpdateStringValue( updater, PROJECT_VERSION.toString(), versionMetadata.getVersion() );
865 addUpdateStringValue( updater, DESCRIPTION.toString(), versionMetadata.getDescription() );
867 addUpdateStringValue( updater, NAME.toString(), versionMetadata.getName() );
869 updater.setString( "incomplete", Boolean.toString( versionMetadata.isIncomplete() ) );
870 addUpdateStringValue( updater, URL.toString(), versionMetadata.getUrl() );
873 CiManagement ci = versionMetadata.getCiManagement();
876 addUpdateStringValue( updater, "ciManagement.system", ci.getSystem() );
877 addUpdateStringValue( updater, "ciManagement.url", ci.getUrl() );
881 IssueManagement issueManagement = versionMetadata.getIssueManagement();
882 if ( issueManagement != null )
884 addUpdateStringValue( updater, "issueManagement.system", issueManagement.getSystem() );
885 addUpdateStringValue( updater, "issueManagement.url", issueManagement.getUrl() );
889 Organization organization = versionMetadata.getOrganization();
890 if ( organization != null )
892 addUpdateStringValue( updater, "organization.name", organization.getName() );
893 addUpdateStringValue( updater, "organization.url", organization.getUrl() );
897 Scm scm = versionMetadata.getScm();
900 addUpdateStringValue( updater, "scm.url", scm.getUrl() );
901 addUpdateStringValue( updater, "scm.connection", scm.getConnection() );
902 addUpdateStringValue( updater, "scm.developerConnection", scm.getDeveloperConnection() );
906 // update is a delete record
907 removeMailingList( key );
908 recordMailingList( key, versionMetadata.getMailingLists() );
910 removeLicenses( key );
911 recordLicenses( key, versionMetadata.getLicenses() );
913 removeDependencies( key );
914 recordDependencies( key, versionMetadata.getDependencies(), repositoryId );
916 projectVersionMetadataTemplate.update( updater );
920 ArtifactMetadataModel artifactMetadataModel = new ArtifactMetadataModel();
921 artifactMetadataModel.setRepositoryId( repositoryId );
922 artifactMetadataModel.setNamespace( namespaceId );
923 artifactMetadataModel.setProject( projectId );
924 artifactMetadataModel.setProjectVersion( versionMetadata.getVersion() );
925 artifactMetadataModel.setVersion( versionMetadata.getVersion() );
926 updateFacets( versionMetadata, artifactMetadataModel );
932 public ProjectVersionMetadata getProjectVersion( RepositorySession session, final String repoId, final String namespace,
933 final String projectId, final String projectVersion )
934 throws MetadataResolutionException
937 QueryResult<OrderedRows<String, String, String>> result = HFactory //
938 .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
939 .setColumnFamily( cassandraArchivaManager.getProjectVersionMetadataFamilyName() ) //
940 .setColumnNames( PROJECT_VERSION.toString() ) //
941 .addEqualsExpression( REPOSITORY_NAME.toString(), repoId ) //
942 .addEqualsExpression( NAMESPACE_ID.toString(), namespace ) //
943 .addEqualsExpression( PROJECT_ID.toString(), projectId ) //
944 .addEqualsExpression( PROJECT_VERSION.toString(), projectVersion ) //
947 if ( result.get().getCount() < 1 )
952 String key = result.get().iterator().next().getKey();
954 ColumnFamilyResult<String, String> columnFamilyResult = this.projectVersionMetadataTemplate.queryColumns( key );
956 if ( !columnFamilyResult.hasResults() )
961 ProjectVersionMetadata projectVersionMetadata = new ProjectVersionMetadata();
962 projectVersionMetadata.setId( columnFamilyResult.getString( PROJECT_VERSION.toString() ) );
963 projectVersionMetadata.setDescription( columnFamilyResult.getString( DESCRIPTION.toString() ) );
964 projectVersionMetadata.setName( columnFamilyResult.getString( NAME.toString() ) );
966 projectVersionMetadata.setIncomplete( Boolean.parseBoolean( columnFamilyResult.getString( "incomplete" ) ) );
968 projectVersionMetadata.setUrl( columnFamilyResult.getString( URL.toString() ) );
970 String ciUrl = columnFamilyResult.getString( "ciManagement.url" );
971 String ciSystem = columnFamilyResult.getString( "ciManagement.system" );
973 if ( StringUtils.isNotEmpty( ciSystem ) || StringUtils.isNotEmpty( ciUrl ) )
975 projectVersionMetadata.setCiManagement( new CiManagement( ciSystem, ciUrl ) );
979 String issueUrl = columnFamilyResult.getString( "issueManagement.url" );
980 String issueSystem = columnFamilyResult.getString( "issueManagement.system" );
981 if ( StringUtils.isNotEmpty( issueSystem ) || StringUtils.isNotEmpty( issueUrl ) )
983 projectVersionMetadata.setIssueManagement( new IssueManagement( issueSystem, issueUrl ) );
987 String organizationUrl = columnFamilyResult.getString( "organization.url" );
988 String organizationName = columnFamilyResult.getString( "organization.name" );
989 if ( StringUtils.isNotEmpty( organizationUrl ) || StringUtils.isNotEmpty( organizationName ) )
991 projectVersionMetadata.setOrganization( new Organization( organizationName, organizationUrl ) );
995 String devConn = columnFamilyResult.getString( "scm.developerConnection" );
996 String conn = columnFamilyResult.getString( "scm.connection" );
997 String url = columnFamilyResult.getString( "scm.url" );
998 if ( StringUtils.isNotEmpty( devConn ) || StringUtils.isNotEmpty( conn ) || StringUtils.isNotEmpty( url ) )
1000 projectVersionMetadata.setScm( new Scm( conn, devConn, url ) );
1003 projectVersionMetadata.setMailingLists( getMailingLists( key ) );
1004 projectVersionMetadata.setLicenses( getLicenses( key ) );
1005 projectVersionMetadata.setDependencies( getDependencies( key ) );
1008 result = HFactory //
1009 .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
1010 .setColumnFamily( cassandraArchivaManager.getMetadataFacetFamilyName() ) //
1011 .setColumnNames( FACET_ID.toString(), KEY.toString(), VALUE.toString(), NAME.toString() ) //
1012 .addEqualsExpression( REPOSITORY_NAME.toString(), repoId ) //
1013 .addEqualsExpression( NAMESPACE_ID.toString(), namespace ) //
1014 .addEqualsExpression( PROJECT_ID.toString(), projectId ) //
1015 .addEqualsExpression( PROJECT_VERSION.toString(), projectVersion ) //
1018 Map<String, Map<String, String>> metadataFacetsPerFacetIds = new HashMap<>();
1020 for ( Row<String, String, String> row : result.get() )
1022 ColumnSlice<String, String> columnSlice = row.getColumnSlice();
1023 String facetId = getStringValue( columnSlice, FACET_ID.toString() );
1024 Map<String, String> metaValues = metadataFacetsPerFacetIds.computeIfAbsent( facetId, k -> new HashMap<>( ) );
1025 metaValues.put( getStringValue( columnSlice, KEY.toString() ), getStringValue( columnSlice, VALUE.toString() ) );
1028 if ( !metadataFacetsPerFacetIds.isEmpty() )
1030 for ( Map.Entry<String, Map<String, String>> entry : metadataFacetsPerFacetIds.entrySet() )
1032 MetadataFacetFactory<?> metadataFacetFactory = getFacetFactory( entry.getKey() );
1033 if ( metadataFacetFactory != null )
1035 MetadataFacet metadataFacet = metadataFacetFactory.createMetadataFacet();
1036 metadataFacet.fromProperties( entry.getValue() );
1037 projectVersionMetadata.addFacet( metadataFacet );
1042 return projectVersionMetadata;
1045 protected void recordChecksums( String repositoryId, String artifactMetadataKey, Map<String, String> checksums)
1047 if ( checksums == null || checksums.isEmpty() )
1051 Mutator<String> checksumMutator = this.checksumTemplate.createMutator();
1052 for ( Map.Entry<String, String> entry : checksums.entrySet())
1054 // we don't care about the key as the real used one with the projectVersionMetadata
1055 String keyChecksums = UUID.randomUUID().toString();
1056 String cfChecksums = cassandraArchivaManager.getChecksumFamilyName();
1058 addInsertion( checksumMutator, keyChecksums, cfChecksums, ARTIFACT_METADATA_MODEL_KEY,
1059 artifactMetadataKey );
1060 addInsertion( checksumMutator, keyChecksums, cfChecksums, CHECKSUM_ALG.toString(), entry.getKey());
1061 addInsertion( checksumMutator, keyChecksums, cfChecksums, CHECKSUM_VALUE.toString(),
1063 addInsertion(checksumMutator, keyChecksums, cfChecksums, REPOSITORY_NAME.toString(), repositoryId);
1066 checksumMutator.execute();
1069 protected void removeChecksums( String artifactMetadataKey )
1072 QueryResult<OrderedRows<String, String, String>> result =
1073 HFactory.createRangeSlicesQuery( cassandraArchivaManager.getKeyspace(), ss, ss, ss ) //
1074 .setColumnFamily( cassandraArchivaManager.getChecksumFamilyName() ) //
1075 .setColumnNames( CHECKSUM_ALG.toString() ) //
1076 .setRowCount( Integer.MAX_VALUE ) //
1077 .addEqualsExpression(ARTIFACT_METADATA_MODEL_KEY, artifactMetadataKey ) //
1080 if ( result.get().getCount() < 1 )
1085 for ( Row<String, String, String> row : result.get() )
1087 this.checksumTemplate.deleteRow( row.getKey() );
1092 protected Map<String, String> getChecksums( String artifactMetadataKey )
1094 Map<String, String> checksums = new HashMap<>();
1096 QueryResult<OrderedRows<String, String, String>> result =
1097 HFactory.createRangeSlicesQuery( cassandraArchivaManager.getKeyspace(), ss, ss, ss ) //
1098 .setColumnFamily( cassandraArchivaManager.getChecksumFamilyName() ) //
1099 .setColumnNames( ARTIFACT_METADATA_MODEL_KEY, REPOSITORY_NAME.toString(),
1100 CHECKSUM_ALG.toString(), CHECKSUM_VALUE.toString() ) //
1101 .setRowCount( Integer.MAX_VALUE ) //
1102 .addEqualsExpression(ARTIFACT_METADATA_MODEL_KEY, artifactMetadataKey) //
1104 for ( Row<String, String, String> row : result.get() )
1106 ColumnFamilyResult<String, String> columnFamilyResult =
1107 this.checksumTemplate.queryColumns( row.getKey() );
1109 checksums.put(columnFamilyResult.getString(CHECKSUM_ALG.toString()),
1110 columnFamilyResult.getString(CHECKSUM_VALUE.toString()));
1116 protected void recordMailingList( String projectVersionMetadataKey, List<MailingList> mailingLists )
1118 if ( mailingLists == null || mailingLists.isEmpty() )
1122 Mutator<String> mailingMutator = this.mailingListTemplate.createMutator();
1123 for ( MailingList mailingList : mailingLists )
1125 // we don't care about the key as the real used one with the projectVersionMetadata
1126 String keyMailingList = UUID.randomUUID().toString();
1127 String cfMailingList = cassandraArchivaManager.getMailingListFamilyName();
1129 addInsertion( mailingMutator, keyMailingList, cfMailingList, "projectVersionMetadataModel.key",
1130 projectVersionMetadataKey );
1131 addInsertion( mailingMutator, keyMailingList, cfMailingList, NAME.toString(), mailingList.getName() );
1132 addInsertion( mailingMutator, keyMailingList, cfMailingList, "mainArchiveUrl",
1133 mailingList.getMainArchiveUrl() );
1134 addInsertion( mailingMutator, keyMailingList, cfMailingList, "postAddress", mailingList.getPostAddress() );
1135 addInsertion( mailingMutator, keyMailingList, cfMailingList, "subscribeAddress",
1136 mailingList.getSubscribeAddress() );
1137 addInsertion( mailingMutator, keyMailingList, cfMailingList, "unsubscribeAddress",
1138 mailingList.getUnsubscribeAddress() );
1140 for ( String otherArchive : mailingList.getOtherArchives() )
1142 addInsertion( mailingMutator, keyMailingList, cfMailingList, "otherArchive." + idx, otherArchive );
1147 mailingMutator.execute();
1150 protected void removeMailingList( String projectVersionMetadataKey )
1153 QueryResult<OrderedRows<String, String, String>> result =
1154 HFactory.createRangeSlicesQuery( cassandraArchivaManager.getKeyspace(), ss, ss, ss ) //
1155 .setColumnFamily( cassandraArchivaManager.getMailingListFamilyName() ) //
1156 .setColumnNames( NAME.toString() ) //
1157 .setRowCount( Integer.MAX_VALUE ) //
1158 .addEqualsExpression( "projectVersionMetadataModel.key", projectVersionMetadataKey ) //
1161 if ( result.get().getCount() < 1 )
1166 for ( Row<String, String, String> row : result.get() )
1168 this.mailingListTemplate.deleteRow( row.getKey() );
1173 protected List<MailingList> getMailingLists( String projectVersionMetadataKey )
1175 List<MailingList> mailingLists = new ArrayList<>();
1177 QueryResult<OrderedRows<String, String, String>> result =
1178 HFactory.createRangeSlicesQuery( cassandraArchivaManager.getKeyspace(), ss, ss, ss ) //
1179 .setColumnFamily( cassandraArchivaManager.getMailingListFamilyName() ) //
1180 .setColumnNames( NAME.toString() ) //
1181 .setRowCount( Integer.MAX_VALUE ) //
1182 .addEqualsExpression( "projectVersionMetadataModel.key", projectVersionMetadataKey ) //
1184 for ( Row<String, String, String> row : result.get() )
1186 ColumnFamilyResult<String, String> columnFamilyResult =
1187 this.mailingListTemplate.queryColumns( row.getKey() );
1189 MailingList mailingList = new MailingList();
1190 mailingList.setName( columnFamilyResult.getString( NAME.toString() ) );
1191 mailingList.setMainArchiveUrl( columnFamilyResult.getString( "mainArchiveUrl" ) );
1192 mailingList.setPostAddress( columnFamilyResult.getString( "postAddress" ) );
1193 mailingList.setSubscribeAddress( columnFamilyResult.getString( "subscribeAddress" ) );
1194 mailingList.setUnsubscribeAddress( columnFamilyResult.getString( "unsubscribeAddress" ) );
1196 List<String> otherArchives = new ArrayList<>();
1198 for ( String columnName : columnFamilyResult.getColumnNames() )
1200 if ( StringUtils.startsWith( columnName, "otherArchive." ) )
1202 otherArchives.add( columnFamilyResult.getString( columnName ) );
1206 mailingList.setOtherArchives( otherArchives );
1207 mailingLists.add( mailingList );
1210 return mailingLists;
1213 protected void recordLicenses( String projectVersionMetadataKey, List<License> licenses )
1216 if ( licenses == null || licenses.isEmpty() )
1220 Mutator<String> licenseMutator = this.licenseTemplate.createMutator();
1222 for ( License license : licenses )
1224 // we don't care about the key as the real used one with the projectVersionMetadata
1225 String keyLicense = UUID.randomUUID().toString();
1226 String cfLicense = cassandraArchivaManager.getLicenseFamilyName();
1228 addInsertion( licenseMutator, keyLicense, cfLicense, "projectVersionMetadataModel.key",
1229 projectVersionMetadataKey );
1231 addInsertion( licenseMutator, keyLicense, cfLicense, NAME.toString(), license.getName() );
1233 addInsertion( licenseMutator, keyLicense, cfLicense, URL.toString(), license.getUrl() );
1236 licenseMutator.execute();
1239 protected void removeLicenses( String projectVersionMetadataKey )
1242 QueryResult<OrderedRows<String, String, String>> result =
1243 HFactory.createRangeSlicesQuery( cassandraArchivaManager.getKeyspace(), ss, ss, ss ) //
1244 .setColumnFamily( cassandraArchivaManager.getLicenseFamilyName() ) //
1245 .setColumnNames( NAME.toString() ) //
1246 .setRowCount( Integer.MAX_VALUE ) //
1247 .addEqualsExpression( "projectVersionMetadataModel.key", projectVersionMetadataKey ) //
1249 for ( Row<String, String, String> row : result.get() )
1251 this.licenseTemplate.deleteRow( row.getKey() );
1255 protected List<License> getLicenses( String projectVersionMetadataKey )
1257 List<License> licenses = new ArrayList<>();
1259 QueryResult<OrderedRows<String, String, String>> result =
1260 HFactory.createRangeSlicesQuery( cassandraArchivaManager.getKeyspace(), ss, ss, ss ) //
1261 .setColumnFamily( cassandraArchivaManager.getLicenseFamilyName() ) //
1262 .setColumnNames( "projectVersionMetadataModel.key" ) //
1263 .setRowCount( Integer.MAX_VALUE ) //
1264 .addEqualsExpression( "projectVersionMetadataModel.key", projectVersionMetadataKey ) //
1267 for ( Row<String, String, String> row : result.get() )
1269 ColumnFamilyResult<String, String> columnFamilyResult = this.licenseTemplate.queryColumns( row.getKey() );
1272 new License( columnFamilyResult.getString( NAME.toString() ), columnFamilyResult.getString( URL.toString() ) ) );
1279 protected void recordDependencies( String projectVersionMetadataKey, List<Dependency> dependencies,
1280 String repositoryId )
1283 if ( dependencies == null || dependencies.isEmpty() )
1287 Mutator<String> dependencyMutator = this.dependencyTemplate.createMutator();
1289 for ( Dependency dependency : dependencies )
1291 // we don't care about the key as the real used one with the projectVersionMetadata
1292 String keyDependency = UUID.randomUUID().toString();
1293 String cfDependency = cassandraArchivaManager.getDependencyFamilyName();
1295 addInsertion( dependencyMutator, keyDependency, cfDependency, "projectVersionMetadataModel.key",
1296 projectVersionMetadataKey );
1298 addInsertion( dependencyMutator, keyDependency, cfDependency, REPOSITORY_NAME.toString(), repositoryId );
1300 addInsertion( dependencyMutator, keyDependency, cfDependency, "classifier", dependency.getClassifier() );
1302 addInsertion( dependencyMutator, keyDependency, cfDependency, "optional",
1303 Boolean.toString( dependency.isOptional() ) );
1305 addInsertion( dependencyMutator, keyDependency, cfDependency, "scope", dependency.getScope() );
1307 addInsertion( dependencyMutator, keyDependency, cfDependency, "systemPath", dependency.getSystemPath() );
1309 addInsertion( dependencyMutator, keyDependency, cfDependency, "type", dependency.getType() );
1311 addInsertion( dependencyMutator, keyDependency, cfDependency, ARTIFACT_ID.toString(), dependency.getArtifactId() );
1313 addInsertion( dependencyMutator, keyDependency, cfDependency, GROUP_ID.toString(), dependency.getNamespace() );
1315 addInsertion( dependencyMutator, keyDependency, cfDependency, VERSION.toString(), dependency.getVersion() );
1318 dependencyMutator.execute();
1321 protected void removeDependencies( String projectVersionMetadataKey )
1324 QueryResult<OrderedRows<String, String, String>> result =
1325 HFactory.createRangeSlicesQuery( cassandraArchivaManager.getKeyspace(), ss, ss, ss ) //
1326 .setColumnFamily( cassandraArchivaManager.getDependencyFamilyName() ) //
1327 .setColumnNames( GROUP_ID.toString() ) //
1328 .setRowCount( Integer.MAX_VALUE ) //
1329 .addEqualsExpression( "projectVersionMetadataModel.key", projectVersionMetadataKey ) //
1331 for ( Row<String, String, String> row : result.get() )
1333 this.dependencyTemplate.deleteRow( row.getKey() );
1337 protected List<Dependency> getDependencies( String projectVersionMetadataKey )
1339 List<Dependency> dependencies = new ArrayList<>();
1341 QueryResult<OrderedRows<String, String, String>> result =
1342 HFactory.createRangeSlicesQuery( cassandraArchivaManager.getKeyspace(), ss, ss, ss ) //
1343 .setColumnFamily( cassandraArchivaManager.getDependencyFamilyName() ) //
1344 .setColumnNames( "projectVersionMetadataModel.key" ) //
1345 .setRowCount( Integer.MAX_VALUE ) //
1346 .addEqualsExpression( "projectVersionMetadataModel.key", projectVersionMetadataKey ) //
1349 for ( Row<String, String, String> row : result.get() )
1351 ColumnFamilyResult<String, String> columnFamilyResult =
1352 this.dependencyTemplate.queryColumns( row.getKey() );
1354 Dependency dependency = new Dependency();
1355 dependency.setClassifier( columnFamilyResult.getString( "classifier" ) );
1357 dependency.setOptional( Boolean.parseBoolean( columnFamilyResult.getString( "optional" ) ) );
1359 dependency.setScope( columnFamilyResult.getString( "scope" ) );
1361 dependency.setSystemPath( columnFamilyResult.getString( "systemPath" ) );
1363 dependency.setType( columnFamilyResult.getString( "type" ) );
1365 dependency.setArtifactId( columnFamilyResult.getString( ARTIFACT_ID.toString() ) );
1367 dependency.setNamespace( columnFamilyResult.getString( GROUP_ID.toString() ) );
1369 dependency.setVersion( columnFamilyResult.getString( VERSION.toString() ) );
1371 dependencies.add( dependency );
1374 return dependencies;
1377 private Map<String, String> mapChecksums(Map<ChecksumAlgorithm,String> checksums) {
1378 return checksums.entrySet().stream().collect(Collectors.toMap(
1379 e -> e.getKey().name(), Map.Entry::getValue
1383 private Map<ChecksumAlgorithm, String> mapChecksumsReverse(Map<String,String> checksums) {
1384 return checksums.entrySet().stream().collect(Collectors.toMap(
1385 e -> ChecksumAlgorithm.valueOf(e.getKey()), Map.Entry::getValue
1390 public void updateArtifact( RepositorySession session, String repositoryId, String namespaceId, String projectId, String projectVersion,
1391 ArtifactMetadata artifactMeta )
1392 throws MetadataRepositoryException
1395 Namespace namespace = getNamespace( repositoryId, namespaceId );
1396 if ( namespace == null )
1398 namespace = updateOrAddNamespace( repositoryId, namespaceId );
1401 ProjectMetadata projectMetadata = new ProjectMetadata();
1402 projectMetadata.setId( projectId );
1403 projectMetadata.setNamespace( namespaceId );
1404 updateProject( session, repositoryId, projectMetadata );
1406 String key = new ArtifactMetadataModel.KeyBuilder().withNamespace( namespace ).withProject( projectId ).withId(
1407 artifactMeta.getId() ).withProjectVersion( projectVersion ).build();
1411 boolean exists = this.artifactMetadataTemplate.isColumnsExist( key );
1416 ColumnFamilyUpdater<String, String> updater = this.artifactMetadataTemplate.createUpdater( key );
1417 updater.setLong( FILE_LAST_MODIFIED.toString(), artifactMeta.getFileLastModified().toInstant().toEpochMilli());
1418 updater.setLong( WHEN_GATHERED.toString(), artifactMeta.getWhenGathered().toInstant().toEpochMilli() );
1419 updater.setLong( SIZE.toString(), artifactMeta.getSize() );
1420 addUpdateStringValue( updater, VERSION.toString(), artifactMeta.getVersion() );
1421 removeChecksums(key);
1422 recordChecksums(repositoryId, key, mapChecksums(artifactMeta.getChecksums()));
1423 this.artifactMetadataTemplate.update( updater );
1427 String cf = this.cassandraArchivaManager.getArtifactMetadataFamilyName();
1429 this.artifactMetadataTemplate.createMutator() //
1430 .addInsertion( key, cf, column( ID.toString(), artifactMeta.getId() ) )//
1431 .addInsertion( key, cf, column( REPOSITORY_NAME.toString(), repositoryId ) ) //
1432 .addInsertion( key, cf, column( NAMESPACE_ID.toString(), namespaceId ) ) //
1433 .addInsertion( key, cf, column( PROJECT.toString(), artifactMeta.getProject() ) ) //
1434 .addInsertion( key, cf, column( PROJECT_VERSION.toString(), projectVersion ) ) //
1435 .addInsertion( key, cf, column( VERSION.toString(), artifactMeta.getVersion() ) ) //
1436 .addInsertion( key, cf, column( FILE_LAST_MODIFIED.toString(), artifactMeta.getFileLastModified().toInstant().toEpochMilli() ) ) //
1437 .addInsertion( key, cf, column( SIZE.toString(), artifactMeta.getSize() ) ) //
1438 .addInsertion( key, cf, column( WHEN_GATHERED.toString(), artifactMeta.getWhenGathered().toInstant().toEpochMilli() ) )//
1440 recordChecksums(repositoryId, key, mapChecksums(artifactMeta.getChecksums()));
1443 key = new ProjectVersionMetadataModel.KeyBuilder() //
1444 .withRepository( repositoryId ) //
1445 .withNamespace( namespace ) //
1446 .withProjectId( projectId ) //
1447 .withProjectVersion( projectVersion ) //
1448 .withId( artifactMeta.getId() ) //
1451 QueryResult<OrderedRows<String, String, String>> result = HFactory //
1452 .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
1453 .setColumnFamily( cassandraArchivaManager.getProjectVersionMetadataFamilyName() ) //
1454 .setColumnNames( VERSION.toString() ) //
1455 .addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) //
1456 .addEqualsExpression( NAMESPACE_ID.toString(), namespaceId ) //
1457 .addEqualsExpression( PROJECT_ID.toString(), projectId ) //
1458 .addEqualsExpression( PROJECT_VERSION.toString(), projectVersion ) //
1459 .addEqualsExpression( VERSION.toString(), artifactMeta.getVersion() ) //
1462 exists = result.get().getCount() > 0;
1466 String cf = this.cassandraArchivaManager.getProjectVersionMetadataFamilyName();
1468 projectVersionMetadataTemplate.createMutator() //
1469 .addInsertion( key, cf, column( NAMESPACE_ID.toString(), namespace.getName() ) ) //
1470 .addInsertion( key, cf, column( REPOSITORY_NAME.toString(), repositoryId ) ) //
1471 .addInsertion( key, cf, column( PROJECT_VERSION.toString(), projectVersion ) ) //
1472 .addInsertion( key, cf, column( PROJECT_ID.toString(), projectId ) ) //
1473 .addInsertion( key, cf, column( VERSION.toString(), artifactMeta.getVersion() ) ) //
1478 ArtifactMetadataModel artifactMetadataModel = new ArtifactMetadataModel();
1480 artifactMetadataModel.setRepositoryId( repositoryId );
1481 artifactMetadataModel.setNamespace( namespaceId );
1482 artifactMetadataModel.setProject( projectId );
1483 artifactMetadataModel.setProjectVersion( projectVersion );
1484 artifactMetadataModel.setVersion( artifactMeta.getVersion() );
1485 artifactMetadataModel.setFileLastModified( artifactMeta.getFileLastModified() == null
1486 ? ZonedDateTime.now().toInstant().toEpochMilli()
1487 : artifactMeta.getFileLastModified().toInstant().toEpochMilli() );
1488 artifactMetadataModel.setChecksums(mapChecksums(artifactMeta.getChecksums()));
1491 updateFacets( artifactMeta, artifactMetadataModel );
1496 public List<String> getArtifactVersions( RepositorySession session, final String repoId, final String namespace, final String projectId,
1497 final String projectVersion )
1498 throws MetadataResolutionException
1501 QueryResult<OrderedRows<String, String, String>> result = HFactory //
1502 .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
1503 .setColumnFamily( cassandraArchivaManager.getProjectVersionMetadataFamilyName() ) //
1504 .setColumnNames( VERSION.toString() ) //
1505 .addEqualsExpression( REPOSITORY_NAME.toString(), repoId ) //
1506 .addEqualsExpression( NAMESPACE_ID.toString(), namespace ) //
1507 .addEqualsExpression( PROJECT_ID.toString(), projectId ) //
1508 .addEqualsExpression( PROJECT_VERSION.toString(), projectVersion ) //
1511 final Set<String> versions = new HashSet<>();
1513 for ( Row<String, String, String> row : result.get() )
1515 versions.add( getStringValue( row.getColumnSlice(), VERSION.toString() ) );
1518 return new ArrayList<>( versions );
1523 * iterate over available facets to remove/add from the artifactMetadata
1525 * @param facetedMetadata
1526 * @param artifactMetadataModel only use for the key
1528 private void updateFacets( final FacetedMetadata facetedMetadata,
1529 final ArtifactMetadataModel artifactMetadataModel )
1532 String cf = cassandraArchivaManager.getMetadataFacetFamilyName();
1534 for ( final String facetId : getSupportedFacets() )
1536 MetadataFacet metadataFacet = facetedMetadata.getFacet( facetId );
1537 if ( metadataFacet == null )
1543 QueryResult<OrderedRows<String, String, String>> result =
1544 HFactory.createRangeSlicesQuery( keyspace, ss, ss, ss ) //
1545 .setColumnFamily( cf ) //
1546 .setColumnNames( REPOSITORY_NAME.toString() ) //
1547 .addEqualsExpression( REPOSITORY_NAME.toString(), artifactMetadataModel.getRepositoryId() ) //
1548 .addEqualsExpression( NAMESPACE_ID.toString(), artifactMetadataModel.getNamespace() ) //
1549 .addEqualsExpression( PROJECT_ID.toString(), artifactMetadataModel.getProject() ) //
1550 .addEqualsExpression( PROJECT_VERSION.toString(), artifactMetadataModel.getProjectVersion() ) //
1551 .addEqualsExpression( FACET_ID.toString(), facetId ) //
1554 for ( Row<String, String, String> row : result.get().getList() )
1556 this.metadataFacetTemplate.deleteRow( row.getKey() );
1559 Map<String, String> properties = metadataFacet.toProperties();
1561 for ( Map.Entry<String, String> entry : properties.entrySet() )
1563 String key = new MetadataFacetModel.KeyBuilder().withKey( entry.getKey() ).withArtifactMetadataModel(
1564 artifactMetadataModel ).withFacetId( facetId ).withName( metadataFacet.getName() ).build();
1565 Mutator<String> mutator = metadataFacetTemplate.createMutator() //
1566 .addInsertion( key, cf, column( REPOSITORY_NAME.toString(), artifactMetadataModel.getRepositoryId() ) ) //
1567 .addInsertion( key, cf, column( NAMESPACE_ID.toString(), artifactMetadataModel.getNamespace() ) ) //
1568 .addInsertion( key, cf, column( PROJECT_ID.toString(), artifactMetadataModel.getProject() ) ) //
1569 .addInsertion( key, cf, column( PROJECT_VERSION.toString(), artifactMetadataModel.getProjectVersion() ) ) //
1570 .addInsertion( key, cf, column( FACET_ID.toString(), facetId ) ) //
1571 .addInsertion( key, cf, column( KEY.toString(), entry.getKey() ) ) //
1572 .addInsertion( key, cf, column( VALUE.toString(), entry.getValue() ) );
1574 if ( metadataFacet.getName() != null )
1576 mutator.addInsertion( key, cf, column( NAME.toString(), metadataFacet.getName() ) );
1586 public List<String> getMetadataFacets( RepositorySession session, final String repositoryId, final String facetId )
1587 throws MetadataRepositoryException
1590 QueryResult<OrderedRows<String, String, String>> result = HFactory //
1591 .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
1592 .setColumnFamily( cassandraArchivaManager.getMetadataFacetFamilyName() ) //
1593 .setColumnNames( NAME.toString() ) //
1594 .addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) //
1595 .addEqualsExpression( FACET_ID.toString(), facetId ) //
1598 final List<String> facets = new ArrayList<>();
1600 for ( Row<String, String, String> row : result.get() )
1602 facets.add( getStringValue( row.getColumnSlice(), NAME.toString() ) );
1607 private <T> Spliterator<T> createResultSpliterator( QueryResult<OrderedRows<String, String, String>> result, BiFunction<Row<String, String, String>, T, T> converter) throws MetadataRepositoryException
1609 final int size = result.get().getCount();
1610 final Iterator<Row<String, String, String>> it = result.get( ).iterator( );
1612 return new Spliterator<T>( )
1614 private T lastItem = null;
1617 public boolean tryAdvance( Consumer<? super T> action )
1623 while ( it.hasNext( ) )
1625 Row<String, String, String> row = it.next( );
1626 T item = converter.apply( row, lastItem );
1627 if ( item != null && lastItem !=null && item != lastItem )
1629 action.accept( lastItem );
1635 action.accept( lastItem );
1645 public Spliterator<T> trySplit( )
1651 public long estimateSize( )
1657 public int characteristics( )
1659 return ORDERED+NONNULL+SIZED;
1666 * Implementation is not very performant, because sorting is part of the stream. I do not know how to specify the sort
1671 * @param repositoryId
1673 * @param queryParameter
1675 * @throws MetadataRepositoryException
1678 public <T extends MetadataFacet> Stream<T> getMetadataFacetStream(RepositorySession session, String repositoryId, Class<T> facetClazz, QueryParameter queryParameter) throws MetadataRepositoryException
1680 final MetadataFacetFactory<T> metadataFacetFactory = getFacetFactory( facetClazz );
1681 final String facetId = metadataFacetFactory.getFacetId( );
1683 QueryResult<OrderedRows<String, String, String>> result = HFactory //
1684 .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
1685 .setColumnFamily( cassandraArchivaManager.getMetadataFacetFamilyName( ) ) //
1686 .setColumnNames( NAME.toString( ), KEY.toString( ), VALUE.toString( ) ) //
1687 .addEqualsExpression( REPOSITORY_NAME.toString( ), repositoryId ) //
1688 .addEqualsExpression( FACET_ID.toString( ), facetId ) //
1689 .setRange( null, null, false, Integer.MAX_VALUE )
1690 .setRowCount( Integer.MAX_VALUE )
1695 return StreamSupport.stream( createResultSpliterator( result, ( Row<String, String, String> row, T lastItem)-> {
1696 ColumnSlice<String, String> columnSlice = row.getColumnSlice();
1697 String name = getStringValue( columnSlice, NAME.toString( ) );
1699 if (lastItem!=null && lastItem.getName().equals(name))
1701 updateItem = lastItem;
1704 updateItem = metadataFacetFactory.createMetadataFacet( repositoryId, name );
1706 String key = getStringValue( columnSlice, KEY.toString() );
1707 if (StringUtils.isNotEmpty( key ))
1709 Map<String, String> map = new HashMap<>( );
1710 map.put( key , getStringValue( columnSlice, VALUE.toString( ) ) );
1711 updateItem.fromProperties( map );
1715 }), false ).sorted( (f1, f2) -> f1.getName()!=null ? f1.getName().compareTo( f2.getName() ) : 1 ).skip( queryParameter.getOffset()).limit( queryParameter.getLimit());
1719 public boolean hasMetadataFacet( RepositorySession session, String repositoryId, String facetId )
1720 throws MetadataRepositoryException
1722 return !getMetadataFacets( session, repositoryId, facetId ).isEmpty();
1726 public <T extends MetadataFacet> T getMetadataFacet( RepositorySession session, final String repositoryId, final Class<T> facetClazz, final String name )
1727 throws MetadataRepositoryException
1729 final MetadataFacetFactory<T> metadataFacetFactory = getFacetFactory( facetClazz );
1730 if (metadataFacetFactory==null) {
1733 final String facetId = metadataFacetFactory.getFacetId( );
1735 QueryResult<OrderedRows<String, String, String>> result = HFactory //
1736 .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
1737 .setColumnFamily( cassandraArchivaManager.getMetadataFacetFamilyName() ) //
1738 .setColumnNames( KEY.toString(), VALUE.toString() ) //
1739 .addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) //
1740 .addEqualsExpression( FACET_ID.toString(), facetId ) //
1741 .addEqualsExpression( NAME.toString(), name ) //
1744 T metadataFacet = metadataFacetFactory.createMetadataFacet( repositoryId, name );
1745 int size = result.get().getCount();
1750 Map<String, String> map = new HashMap<>( size );
1751 for ( Row<String, String, String> row : result.get() )
1753 ColumnSlice<String, String> columnSlice = row.getColumnSlice();
1754 map.put( getStringValue( columnSlice, KEY.toString() ), getStringValue( columnSlice, VALUE.toString() ) );
1756 metadataFacet.fromProperties( map );
1757 return metadataFacet;
1761 public MetadataFacet getMetadataFacet( RepositorySession session, String repositoryId, String facetId, String name ) throws MetadataRepositoryException
1763 return getMetadataFacet( session, repositoryId, getFactoryClassForId( facetId ), name );
1767 public void addMetadataFacet( RepositorySession session, String repositoryId, MetadataFacet metadataFacet )
1768 throws MetadataRepositoryException
1771 if ( metadataFacet == null )
1776 if ( metadataFacet.toProperties().isEmpty() )
1778 String key = new MetadataFacetModel.KeyBuilder().withRepositoryId( repositoryId ).withFacetId(
1779 metadataFacet.getFacetId() ).withName( metadataFacet.getName() ).build();
1781 boolean exists = this.metadataFacetTemplate.isColumnsExist( key );
1785 ColumnFamilyUpdater<String, String> updater = this.metadataFacetTemplate.createUpdater( key );
1786 addUpdateStringValue( updater, FACET_ID.toString(), metadataFacet.getFacetId() );
1787 addUpdateStringValue( updater, NAME.toString(), metadataFacet.getName() );
1788 this.metadataFacetTemplate.update( updater );
1792 String cf = this.cassandraArchivaManager.getMetadataFacetFamilyName();
1793 this.metadataFacetTemplate.createMutator() //
1794 .addInsertion( key, cf, column( REPOSITORY_NAME.toString(), repositoryId ) ) //
1795 .addInsertion( key, cf, column( FACET_ID.toString(), metadataFacet.getFacetId() ) ) //
1796 .addInsertion( key, cf, column( NAME.toString(), metadataFacet.getName() ) ) //
1803 for ( Map.Entry<String, String> entry : metadataFacet.toProperties().entrySet() )
1805 String key = new MetadataFacetModel.KeyBuilder().withRepositoryId( repositoryId ).withFacetId(
1806 metadataFacet.getFacetId() ).withName( metadataFacet.getName() ).withKey( entry.getKey() ).build();
1808 boolean exists = this.metadataFacetTemplate.isColumnsExist( key );
1811 String cf = this.cassandraArchivaManager.getMetadataFacetFamilyName();
1812 this.metadataFacetTemplate.createMutator() //
1813 .addInsertion( key, cf, column( REPOSITORY_NAME.toString(), repositoryId ) ) //
1814 .addInsertion( key, cf, column( FACET_ID.toString(), metadataFacet.getFacetId() ) ) //
1815 .addInsertion( key, cf, column( NAME.toString(), metadataFacet.getName() ) ) //
1816 .addInsertion( key, cf, column( KEY.toString(), entry.getKey() ) ) //
1817 .addInsertion( key, cf, column( VALUE.toString(), entry.getValue() ) ) //
1822 ColumnFamilyUpdater<String, String> updater = this.metadataFacetTemplate.createUpdater( key );
1823 addUpdateStringValue( updater, VALUE.toString(), entry.getValue() );
1824 this.metadataFacetTemplate.update( updater );
1831 public void removeMetadataFacets( RepositorySession session, final String repositoryId, final String facetId )
1832 throws MetadataRepositoryException
1835 QueryResult<OrderedRows<String, String, String>> result = HFactory //
1836 .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
1837 .setColumnFamily( cassandraArchivaManager.getMetadataFacetFamilyName() ) //
1838 .setColumnNames( KEY.toString(), VALUE.toString() ) //
1839 .addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) //
1840 .addEqualsExpression( FACET_ID.toString(), facetId ) //
1843 for ( Row<String, String, String> row : result.get() )
1845 this.metadataFacetTemplate.deleteRow( row.getKey() );
1851 public void removeMetadataFacet( RepositorySession session, final String repositoryId, final String facetId, final String name )
1852 throws MetadataRepositoryException
1855 QueryResult<OrderedRows<String, String, String>> result = HFactory //
1856 .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
1857 .setColumnFamily( cassandraArchivaManager.getMetadataFacetFamilyName() ) //
1858 .setColumnNames( KEY.toString(), VALUE.toString() ) //
1859 .addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) //
1860 .addEqualsExpression( FACET_ID.toString(), facetId ) //
1861 .addEqualsExpression( NAME.toString(), name ) //
1864 for ( Row<String, String, String> row : result.get() )
1866 this.metadataFacetTemplate.deleteRow( row.getKey() );
1871 public List<ArtifactMetadata> getArtifactsByDateRange( RepositorySession session, final String repositoryId, final ZonedDateTime startTime,
1872 final ZonedDateTime endTime, QueryParameter queryParameter )
1873 throws MetadataRepositoryException
1876 LongSerializer ls = LongSerializer.get();
1877 RangeSlicesQuery<String, String, Long> query = HFactory //
1878 .createRangeSlicesQuery( keyspace, ss, ss, ls ) //
1879 .setColumnFamily( cassandraArchivaManager.getArtifactMetadataFamilyName() ) //
1880 .setColumnNames( ArtifactMetadataModel.COLUMNS ); //
1883 if ( startTime != null )
1885 query = query.addGteExpression( WHEN_GATHERED.toString(), startTime.toInstant().toEpochMilli() );
1887 if ( endTime != null )
1889 query = query.addLteExpression( WHEN_GATHERED.toString(), endTime.toInstant().toEpochMilli() );
1891 QueryResult<OrderedRows<String, String, Long>> result = query.execute();
1893 List<ArtifactMetadata> artifactMetadatas = new ArrayList<>( result.get().getCount() );
1894 Iterator<Row<String, String, Long>> keyIter = result.get().iterator();
1895 if (keyIter.hasNext()) {
1896 String key = keyIter.next().getKey();
1897 for (Row<String, String, Long> row : result.get()) {
1898 ColumnSlice<String, Long> columnSlice = row.getColumnSlice();
1899 String repositoryName = getAsStringValue(columnSlice, REPOSITORY_NAME.toString());
1900 if (StringUtils.equals(repositoryName, repositoryId)) {
1902 artifactMetadatas.add(mapArtifactMetadataLongColumnSlice(key, columnSlice));
1907 return artifactMetadatas;
1911 * For documentation see {@link MetadataRepository#getArtifactByDateRangeStream(RepositorySession, String, ZonedDateTime, ZonedDateTime, QueryParameter)}
1913 * This implementation orders the stream. It does not order the query in the backend.
1915 * @param session The repository session
1916 * @param repositoryId The repository id
1917 * @param startTime The start time, can be <code>null</code>
1918 * @param endTime The end time, can be <code>null</code>
1919 * @param queryParameter Additional parameters for the query that affect ordering and number of returned results.
1921 * @throws MetadataRepositoryException
1922 * @see MetadataRepository#getArtifactByDateRangeStream
1925 public Stream<ArtifactMetadata> getArtifactByDateRangeStream( RepositorySession session, String repositoryId, ZonedDateTime startTime, ZonedDateTime endTime, QueryParameter queryParameter) throws MetadataRepositoryException
1927 Comparator<ArtifactMetadata> comp = getArtifactMetadataComparator(queryParameter, "whenGathered");
1928 return getArtifactsByDateRange(session, repositoryId, startTime, endTime, queryParameter).stream().sorted(comp).skip(queryParameter.getOffset()).limit(queryParameter.getLimit());
1932 protected ArtifactMetadata mapArtifactMetadataLongColumnSlice( String key, ColumnSlice<String, Long> columnSlice )
1934 ArtifactMetadata artifactMetadata = new ArtifactMetadata();
1935 artifactMetadata.setNamespace( getAsStringValue( columnSlice, NAMESPACE_ID.toString() ) );
1936 artifactMetadata.setSize( getLongValue( columnSlice, SIZE.toString() ) );
1937 artifactMetadata.setId( getAsStringValue( columnSlice, ID.toString() ) );
1938 artifactMetadata.setFileLastModified( getLongValue( columnSlice, FILE_LAST_MODIFIED.toString() ) );
1939 artifactMetadata.setMd5( getAsStringValue( columnSlice, MD5.toString() ) );
1940 artifactMetadata.setProject( getAsStringValue( columnSlice, PROJECT.toString() ) );
1941 artifactMetadata.setProjectVersion( getAsStringValue( columnSlice, PROJECT_VERSION.toString() ) );
1942 artifactMetadata.setRepositoryId( getAsStringValue( columnSlice, REPOSITORY_NAME.toString() ) );
1943 artifactMetadata.setSha1( getAsStringValue( columnSlice, SHA1.toString() ) );
1944 artifactMetadata.setVersion( getAsStringValue( columnSlice, VERSION.toString() ) );
1945 Long whenGathered = getLongValue( columnSlice, WHEN_GATHERED.toString() );
1946 if ( whenGathered != null )
1948 artifactMetadata.setWhenGathered(ZonedDateTime.ofInstant(Instant.ofEpochMilli(whenGathered), STORAGE_TZ));
1950 artifactMetadata.setChecksums(mapChecksumsReverse(getChecksums(key)));
1951 return artifactMetadata;
1954 protected ArtifactMetadata mapArtifactMetadataStringColumnSlice( String key, ColumnSlice<String, String> columnSlice )
1956 ArtifactMetadata artifactMetadata = new ArtifactMetadata();
1957 artifactMetadata.setNamespace( getStringValue( columnSlice, NAMESPACE_ID.toString() ) );
1958 artifactMetadata.setSize( getAsLongValue( columnSlice, SIZE.toString() ) );
1959 artifactMetadata.setId( getStringValue( columnSlice, ID.toString() ) );
1960 artifactMetadata.setFileLastModified( getAsLongValue( columnSlice, FILE_LAST_MODIFIED.toString() ) );
1961 artifactMetadata.setMd5( getStringValue( columnSlice, MD5.toString() ) );
1962 artifactMetadata.setProject( getStringValue( columnSlice, PROJECT.toString() ) );
1963 artifactMetadata.setProjectVersion( getStringValue( columnSlice, PROJECT_VERSION.toString() ) );
1964 artifactMetadata.setRepositoryId( getStringValue( columnSlice, REPOSITORY_NAME.toString() ) );
1965 artifactMetadata.setSha1( getStringValue( columnSlice, SHA1.toString() ) );
1966 artifactMetadata.setVersion( getStringValue( columnSlice, VERSION.toString() ) );
1967 Long whenGathered = getAsLongValue( columnSlice, WHEN_GATHERED.toString() );
1968 if ( whenGathered != null )
1970 artifactMetadata.setWhenGathered(ZonedDateTime.ofInstant(Instant.ofEpochMilli(whenGathered), STORAGE_TZ));
1972 artifactMetadata.setChecksums(mapChecksumsReverse(getChecksums(key)));
1973 return artifactMetadata;
1977 public List<ArtifactMetadata> getArtifactsByChecksum(RepositorySession session, final String repositoryId, final String checksum )
1978 throws MetadataRepositoryException
1981 // cql cannot run or in queries so running twice the query
1982 Map<String, ArtifactMetadata> artifactMetadataMap = new HashMap<>();
1984 RangeSlicesQuery<String, String, String> query = HFactory //
1985 .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
1986 .setColumnFamily( cassandraArchivaManager.getChecksumFamilyName()) //
1987 .setColumnNames(ARTIFACT_METADATA_MODEL_KEY); //
1989 query = query.addEqualsExpression( CHECKSUM_VALUE.toString(), checksum )
1990 .addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId );
1992 QueryResult<OrderedRows<String, String, String>> result = query.execute();
1994 List<String> artifactKeys = new ArrayList<>();
1995 for ( Row<String, String, String> row : result.get() )
1997 ColumnSlice<String, String> columnSlice = row.getColumnSlice();
1999 artifactKeys.add(columnSlice.getColumnByName(ARTIFACT_METADATA_MODEL_KEY).getValue());
2003 for (String key : artifactKeys) {
2005 .createRangeSlicesQuery(keyspace, ss, ss, ss) //
2006 .setColumnFamily(cassandraArchivaManager.getArtifactMetadataFamilyName()) //
2007 .setColumnNames(NAMESPACE_ID.toString(), SIZE.toString(), ID.toString(), FILE_LAST_MODIFIED.toString(), MD5.toString(), PROJECT.toString(), PROJECT_VERSION.toString(),
2008 REPOSITORY_NAME.toString(), VERSION.toString(), WHEN_GATHERED.toString(), SHA1.toString())
2010 result = query.execute();
2012 for (Row<String, String, String> row : result.get()) {
2013 ColumnSlice<String, String> columnSlice = row.getColumnSlice();
2015 artifactMetadataMap.put(row.getKey(), mapArtifactMetadataStringColumnSlice(key, columnSlice));
2019 return new ArrayList<>(artifactMetadataMap.values());
2023 * Project version and artifact level metadata are stored in the same place, no distinctions in Cassandra
2024 * implementation, just calls {@link MetadataRepository#getArtifactsByAttribute(RepositorySession, String, String, String)}
2027 public List<ArtifactMetadata> getArtifactsByProjectVersionFacet( RepositorySession session, String key, String value, String repositoryId )
2028 throws MetadataRepositoryException
2030 return this.getArtifactsByAttribute( session, key, value, repositoryId );
2034 public List<ArtifactMetadata> getArtifactsByAttribute( RepositorySession session, String key, String value, String repositoryId )
2035 throws MetadataRepositoryException
2037 RangeSlicesQuery<String, String, String> query =
2038 HFactory.createRangeSlicesQuery( keyspace, ss, ss, ss ) //
2039 .setColumnFamily( cassandraArchivaManager.getMetadataFacetFamilyName() ) //
2040 .setColumnNames( MetadataFacetModel.COLUMNS ) //
2041 .addEqualsExpression( VALUE.toString(), value );
2045 query.addEqualsExpression( KEY.toString(), key ); //
2047 if ( repositoryId != null )
2049 query.addEqualsExpression( "repositoryName", repositoryId );
2052 QueryResult<OrderedRows<String, String, String>> metadataFacetResult = query.execute();
2053 if ( metadataFacetResult.get() == null || metadataFacetResult.get().getCount() < 1 )
2055 return Collections.emptyList();
2058 List<ArtifactMetadata> artifactMetadatas = new LinkedList<>( );
2060 // TODO doing multiple queries, there should be a way to get all the artifactMetadatas for any number of
2062 for ( Row<String, String, String> row : metadataFacetResult.get() )
2064 QueryResult<OrderedRows<String, String, String>> artifactMetadataResult =
2065 HFactory.createRangeSlicesQuery( keyspace, ss, ss, ss ) //
2066 .setColumnFamily( cassandraArchivaManager.getArtifactMetadataFamilyName() ) //
2067 .setColumnNames( ArtifactMetadataModel.COLUMNS ) //
2068 .setRowCount( Integer.MAX_VALUE ) //
2069 .addEqualsExpression( REPOSITORY_NAME.toString(),
2070 getStringValue( row.getColumnSlice(), REPOSITORY_NAME ) ) //
2071 .addEqualsExpression( NAMESPACE_ID.toString(), getStringValue( row.getColumnSlice(), NAMESPACE_ID ) ) //
2072 .addEqualsExpression( PROJECT.toString(), getStringValue( row.getColumnSlice(), PROJECT_ID ) ) //
2073 .addEqualsExpression( PROJECT_VERSION.toString(),
2074 getStringValue( row.getColumnSlice(), PROJECT_VERSION ) ) //
2077 if ( artifactMetadataResult.get() == null || artifactMetadataResult.get().getCount() < 1 )
2079 return Collections.emptyList();
2082 for ( Row<String, String, String> artifactMetadataRow : artifactMetadataResult.get() )
2084 String artifactKey = artifactMetadataRow.getKey();
2085 artifactMetadatas.add( mapArtifactMetadataStringColumnSlice( artifactKey, artifactMetadataRow.getColumnSlice() ) );
2089 return mapArtifactFacetToArtifact( metadataFacetResult, artifactMetadatas );
2093 public List<ArtifactMetadata> getArtifactsByProjectVersionAttribute( RepositorySession session, String key, String value, String repositoryId )
2094 throws MetadataRepositoryException
2096 QueryResult<OrderedRows<String, String, String>> result =
2097 HFactory.createRangeSlicesQuery( keyspace, ss, ss, ss ) //
2098 .setColumnFamily( cassandraArchivaManager.getProjectVersionMetadataFamilyName() ) //
2099 .setColumnNames( PROJECT_ID.toString(), REPOSITORY_NAME.toString(), NAMESPACE_ID.toString(),
2100 PROJECT_VERSION.toString() ) //
2101 .addEqualsExpression( key, value ) //
2104 int count = result.get().getCount();
2108 return Collections.emptyList();
2111 List<ArtifactMetadata> artifacts = new LinkedList<>( );
2113 for ( Row<String, String, String> row : result.get() )
2115 // TODO doing multiple queries, there should be a way to get all the artifactMetadatas for any number of
2119 artifacts.addAll( getArtifacts( session,
2120 getStringValue( row.getColumnSlice(), REPOSITORY_NAME ),
2121 getStringValue( row.getColumnSlice(), NAMESPACE_ID ),
2122 getStringValue( row.getColumnSlice(), PROJECT_ID ), getStringValue( row.getColumnSlice(), PROJECT_VERSION ) ) );
2124 catch ( MetadataResolutionException e )
2127 throw new IllegalStateException( e );
2134 public void removeArtifact( RepositorySession session, final String repositoryId, final String namespace, final String project,
2135 final String version, final String id )
2136 throws MetadataRepositoryException
2138 logger.debug( "removeTimestampedArtifact repositoryId: '{}', namespace: '{}', project: '{}', version: '{}', id: '{}'",
2139 repositoryId, namespace, project, version, id );
2141 new ArtifactMetadataModel.KeyBuilder().withRepositoryId( repositoryId ).withNamespace( namespace ).withId(
2142 id ).withProjectVersion( version ).withProject( project ).build();
2144 this.artifactMetadataTemplate.deleteRow( key );
2146 key = new ProjectVersionMetadataModel.KeyBuilder() //
2147 .withRepository( repositoryId ) //
2148 .withNamespace( namespace ) //
2149 .withProjectId( project ) //
2150 .withProjectVersion( version ) //
2154 this.projectVersionMetadataTemplate.deleteRow( key );
2158 public void removeTimestampedArtifact( RepositorySession session, ArtifactMetadata artifactMetadata, String baseVersion )
2159 throws MetadataRepositoryException
2161 logger.debug( "removeTimestampedArtifact repositoryId: '{}', namespace: '{}', project: '{}', version: '{}', id: '{}'",
2162 artifactMetadata.getRepositoryId(), artifactMetadata.getNamespace(),
2163 artifactMetadata.getProject(), baseVersion, artifactMetadata.getId() );
2165 new ArtifactMetadataModel.KeyBuilder().withRepositoryId( artifactMetadata.getRepositoryId() ).withNamespace(
2166 artifactMetadata.getNamespace() ).withId( artifactMetadata.getId() ).withProjectVersion(
2167 baseVersion ).withProject( artifactMetadata.getProject() ).build();
2169 this.artifactMetadataTemplate.deleteRow( key );
2174 public void removeFacetFromArtifact( RepositorySession session, final String repositoryId, final String namespace, final String project,
2175 final String version, final MetadataFacet metadataFacet )
2176 throws MetadataRepositoryException
2179 RangeSlicesQuery<String, String, String> query = HFactory //
2180 .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
2181 .setColumnFamily( cassandraArchivaManager.getArtifactMetadataFamilyName() ) //
2182 .setColumnNames( NAMESPACE_ID.toString() ); //
2184 query = query.addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId ) //
2185 .addEqualsExpression( NAMESPACE_ID.toString(), namespace ) //
2186 .addEqualsExpression( PROJECT.toString(), project ) //
2187 .addEqualsExpression( VERSION.toString(), version );
2189 QueryResult<OrderedRows<String, String, String>> result = query.execute();
2191 for ( Row<String, String, String> row : result.get() )
2193 this.artifactMetadataTemplate.deleteRow( row.getKey() );
2199 public List<ArtifactMetadata> getArtifacts( RepositorySession session, final String repositoryId )
2200 throws MetadataRepositoryException
2203 RangeSlicesQuery<String, String, String> query = HFactory //
2204 .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
2205 .setColumnFamily( cassandraArchivaManager.getArtifactMetadataFamilyName() ) //
2206 .setColumnNames( ArtifactMetadataModel.COLUMNS ); //
2208 query = query.addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId );
2210 QueryResult<OrderedRows<String, String, String>> result = query.execute();
2214 List<ArtifactMetadata> artifactMetadatas = new ArrayList<>( result.get().getCount() );
2216 for ( Row<String, String, String> row : result.get() )
2218 String key = row.getKey();
2219 ColumnSlice<String, String> columnSlice = row.getColumnSlice();
2220 artifactMetadatas.add( mapArtifactMetadataStringColumnSlice( key, columnSlice ) );
2224 return artifactMetadatas;
2229 public List<ProjectVersionReference> getProjectReferences( RepositorySession session, String repoId, String namespace, String projectId,
2230 String projectVersion )
2231 throws MetadataResolutionException
2233 QueryResult<OrderedRows<String, String, String>> result = HFactory //
2234 .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
2235 .setColumnFamily( cassandraArchivaManager.getDependencyFamilyName() ) //
2236 .setColumnNames( "projectVersionMetadataModel.key" ) //
2237 .addEqualsExpression( REPOSITORY_NAME.toString(), repoId ) //
2238 .addEqualsExpression( GROUP_ID.toString(), namespace ) //
2239 .addEqualsExpression( ARTIFACT_ID.toString(), projectId ) //
2240 .addEqualsExpression( VERSION.toString(), projectVersion ) //
2243 List<String> dependenciesIds = new ArrayList<>( result.get().getCount() );
2245 for ( Row<String, String, String> row : result.get().getList() )
2247 dependenciesIds.add( getStringValue( row.getColumnSlice(), "projectVersionMetadataModel.key" ) );
2250 List<ProjectVersionReference> references = new ArrayList<>( result.get().getCount() );
2252 for ( String key : dependenciesIds )
2254 ColumnFamilyResult<String, String> columnFamilyResult =
2255 this.projectVersionMetadataTemplate.queryColumns( key );
2256 references.add( new ProjectVersionReference( ProjectVersionReference.ReferenceType.DEPENDENCY, //
2257 columnFamilyResult.getString( PROJECT_ID.toString() ), //
2258 columnFamilyResult.getString( NAMESPACE_ID.toString() ), //
2259 columnFamilyResult.getString( PROJECT_VERSION.toString() ) ) );
2266 public void removeProjectVersion( RepositorySession session, final String repoId, final String namespace, final String projectId,
2267 final String projectVersion )
2268 throws MetadataRepositoryException
2271 QueryResult<OrderedRows<String, String, String>> result = HFactory //
2272 .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
2273 .setColumnFamily( cassandraArchivaManager.getProjectVersionMetadataFamilyName() ) //
2274 .setColumnNames( VERSION.toString() ) //
2275 .addEqualsExpression( REPOSITORY_NAME.toString(), repoId ) //
2276 .addEqualsExpression( NAMESPACE_ID.toString(), namespace ) //
2277 .addEqualsExpression( PROJECT_ID.toString(), projectId ) //
2278 .addEqualsExpression( PROJECT_VERSION.toString(), projectVersion ) //
2281 for ( Row<String, String, String> row : result.get().getList() )
2283 this.projectVersionMetadataTemplate.deleteRow( row.getKey() );
2284 removeMailingList( row.getKey() );
2285 removeLicenses( row.getKey() );
2286 removeDependencies( row.getKey() );
2289 RangeSlicesQuery<String, String, String> query = HFactory //
2290 .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
2291 .setColumnFamily( cassandraArchivaManager.getArtifactMetadataFamilyName() ) //
2292 .setColumnNames( NAMESPACE_ID.toString() ); //
2294 query = query.addEqualsExpression( REPOSITORY_NAME.toString(), repoId ) //
2295 .addEqualsExpression( NAMESPACE_ID.toString(), namespace ) //
2296 .addEqualsExpression( PROJECT.toString(), projectId ) //
2297 .addEqualsExpression( PROJECT_VERSION.toString(), projectVersion );
2299 result = query.execute();
2301 for ( Row<String, String, String> row : result.get() )
2303 this.artifactMetadataTemplate.deleteRow( row.getKey() );
2309 public List<ArtifactMetadata> getArtifacts( RepositorySession session, final String repoId, final String namespace,
2310 final String projectId, final String projectVersion )
2311 throws MetadataResolutionException
2314 QueryResult<OrderedRows<String, String, String>> result =
2315 HFactory.createRangeSlicesQuery( keyspace, ss, ss, ss ) //
2316 .setColumnFamily( cassandraArchivaManager.getArtifactMetadataFamilyName() ) //
2317 .setColumnNames( ArtifactMetadataModel.COLUMNS )//
2318 .setRowCount( Integer.MAX_VALUE ) //
2319 .addEqualsExpression( REPOSITORY_NAME.toString(), repoId ) //
2320 .addEqualsExpression( NAMESPACE_ID.toString(), namespace ) //
2321 .addEqualsExpression( PROJECT.toString(), projectId ) //
2322 .addEqualsExpression( PROJECT_VERSION.toString(), projectVersion ) //
2325 if ( result.get() == null || result.get().getCount() < 1 )
2327 return Collections.emptyList();
2330 List<ArtifactMetadata> artifactMetadatas = new ArrayList<>( result.get().getCount() );
2332 for ( Row<String, String, String> row : result.get() )
2334 String key = row.getKey();
2335 artifactMetadatas.add( mapArtifactMetadataStringColumnSlice( key, row.getColumnSlice() ) );
2338 result = HFactory.createRangeSlicesQuery( keyspace, ss, ss, ss ) //
2339 .setColumnFamily( cassandraArchivaManager.getMetadataFacetFamilyName() ) //
2340 .setColumnNames( MetadataFacetModel.COLUMNS ) //
2341 .setRowCount( Integer.MAX_VALUE ) //
2342 .addEqualsExpression( REPOSITORY_NAME.toString(), repoId ) //
2343 .addEqualsExpression( NAMESPACE_ID.toString(), namespace ) //
2344 .addEqualsExpression( PROJECT_ID.toString(), projectId ) //
2345 .addEqualsExpression( PROJECT_VERSION.toString(), projectVersion ) //
2348 return mapArtifactFacetToArtifact(result, artifactMetadatas);
2352 * Attach metadata to each of the ArtifactMetadata objects
2354 private List<ArtifactMetadata> mapArtifactFacetToArtifact( QueryResult<OrderedRows<String, String, String>> result, List<ArtifactMetadata> artifactMetadatas) {
2355 if ( result.get() == null || result.get().getCount() < 1 )
2357 return artifactMetadatas;
2360 final List<MetadataFacetModel> metadataFacetModels = new ArrayList<>( result.get().getCount() );
2362 for ( Row<String, String, String> row : result.get() )
2364 ColumnSlice<String, String> columnSlice = row.getColumnSlice();
2365 MetadataFacetModel metadataFacetModel = new MetadataFacetModel();
2366 metadataFacetModel.setFacetId( getStringValue( columnSlice, FACET_ID.toString() ) );
2367 metadataFacetModel.setName( getStringValue( columnSlice, NAME.toString() ) );
2368 metadataFacetModel.setValue( getStringValue( columnSlice, VALUE.toString() ) );
2369 metadataFacetModel.setKey( getStringValue( columnSlice, KEY.toString() ) );
2370 metadataFacetModel.setProjectVersion( getStringValue( columnSlice, PROJECT_VERSION.toString() ) );
2371 metadataFacetModels.add( metadataFacetModel );
2374 // rebuild MetadataFacet for artifacts
2376 for ( final ArtifactMetadata artifactMetadata : artifactMetadatas )
2378 Iterator<MetadataFacetModel> iterator = metadataFacetModels.stream( ).filter( metadataFacetModel -> {
2379 if ( metadataFacetModel != null )
2381 return StringUtils.equals( artifactMetadata.getVersion( ),
2382 metadataFacetModel.getProjectVersion( ) );
2387 Map<String, List<MetadataFacetModel>> metadataFacetValuesPerFacetId = new HashMap<>();
2388 while ( iterator.hasNext() )
2390 MetadataFacetModel metadataFacetModel = iterator.next();
2391 List<MetadataFacetModel> values = metadataFacetValuesPerFacetId.get( metadataFacetModel.getName() );
2392 if ( values == null )
2394 values = new ArrayList<>();
2395 metadataFacetValuesPerFacetId.put( metadataFacetModel.getFacetId(), values );
2397 values.add( metadataFacetModel );
2401 for ( Map.Entry<String, List<MetadataFacetModel>> entry : metadataFacetValuesPerFacetId.entrySet() )
2403 MetadataFacetFactory<?> metadataFacetFactory = getFacetFactory( entry.getKey() );
2404 if ( metadataFacetFactory != null )
2406 List<MetadataFacetModel> facetModels = entry.getValue();
2407 if ( !facetModels.isEmpty() )
2409 MetadataFacet metadataFacet = metadataFacetFactory.createMetadataFacet();
2410 Map<String, String> props = new HashMap<>( facetModels.size() );
2411 for ( MetadataFacetModel metadataFacetModel : facetModels )
2413 props.put( metadataFacetModel.getKey(), metadataFacetModel.getValue() );
2415 metadataFacet.fromProperties( props );
2416 artifactMetadata.addFacet( metadataFacet );
2422 return artifactMetadatas;
2427 throws MetadataRepositoryException
2429 logger.trace( "close" );
2433 private static class ModelMapperHolder
2435 private static ModelMapper MODEL_MAPPER = new ModelMapper();
2438 protected ModelMapper getModelMapper()
2440 return ModelMapperHolder.MODEL_MAPPER;
2444 * This implementation just calls getArtifactsByAttribute( null, text, repositoryId ). We can't search artifacts by
2448 public List<ArtifactMetadata> searchArtifacts( final RepositorySession session, final String repositoryId,
2449 final String text, final boolean exact )
2450 throws MetadataRepositoryException
2452 return this.getArtifactsByAttribute( session, null, text, repositoryId );
2456 * The exact parameter is ignored as we can't do non exact searches in Cassandra
2459 public List<ArtifactMetadata> searchArtifacts( final RepositorySession session, final String repositoryId,
2460 final String key, final String text, final boolean exact )
2461 throws MetadataRepositoryException
2464 List<ArtifactMetadata> artifacts = new LinkedList<>( );
2465 artifacts.addAll( this.getArtifactsByAttribute( session, key, text, repositoryId ) );
2466 artifacts.addAll( this.getArtifactsByProjectVersionAttribute( session, key, text, repositoryId ) );
2471 public Stream<ArtifactMetadata> getArtifactStream( final RepositorySession session, final String repositoryId,
2472 final QueryParameter queryParameter ) throws MetadataResolutionException
2474 RangeSlicesQuery<String, String, String> query = HFactory //
2475 .createRangeSlicesQuery( keyspace, ss, ss, ss ) //
2476 .setColumnFamily( cassandraArchivaManager.getArtifactMetadataFamilyName( ) ) //
2477 .setColumnNames( ArtifactMetadataModel.COLUMNS ); //
2479 query = query.addEqualsExpression( REPOSITORY_NAME.toString(), repositoryId );
2481 QueryResult<OrderedRows<String, String, String>> result = query.execute();
2485 return StreamSupport.stream( createResultSpliterator( result, ( Row<String, String, String> row, ArtifactMetadata last ) ->
2486 mapArtifactMetadataStringColumnSlice( row.getKey( ), row.getColumnSlice( ) ) ), false )
2487 .skip( queryParameter.getOffset( ) ).limit( queryParameter.getLimit( ) );
2489 catch ( MetadataRepositoryException e )
2491 throw new MetadataResolutionException( e.getMessage( ), e );
2496 public Stream<ArtifactMetadata> getArtifactStream( final RepositorySession session, final String repoId,
2497 final String namespace, final String projectId, final String projectVersion,
2498 final QueryParameter queryParameter ) throws MetadataResolutionException
2500 // Currently we have to align the facets with the artifacts, which means querying artifacts, querying facets and combining them.
2501 // I so no stream friendly way to do this, so we just use the collection based method and return the stream.
2502 // TODO: Maybe we can query the facets for each artifact separately, but not sure, if this affects performance significantly
2503 // We need some data to verify this.
2504 return getArtifacts( session, repoId, namespace, projectId, projectVersion ).stream( ).skip( queryParameter.getOffset( ) ).limit( queryParameter.getLimit( ) );