Enhancing repository events

This commit is contained in:
Martin Stockhammer 2019-09-12 13:09:40 +02:00
parent b072f6921d
commit 9948797e50
20 changed files with 861 additions and 698 deletions

View File

@ -36,6 +36,7 @@
import org.apache.archiva.repository.RepositoryException;
import org.apache.archiva.repository.RepositoryProvider;
import org.apache.archiva.repository.RepositoryType;
import org.apache.archiva.repository.events.Event;
import org.apache.archiva.repository.features.ArtifactCleanupFeature;
import org.apache.archiva.repository.features.IndexCreationFeature;
import org.apache.archiva.repository.features.RemoteIndexFeature;
@ -255,7 +256,7 @@ public RemoteRepositoryConfiguration getRemoteConfiguration( RemoteRepository re
}
@Override
public <T> void raise(org.apache.archiva.repository.RepositoryEvent<T> event) {
public void raise(Event event) {
}

View File

@ -32,7 +32,8 @@
import org.apache.archiva.repository.ReleaseScheme;
import org.apache.archiva.repository.RemoteRepository;
import org.apache.archiva.repository.RepositoryCredentials;
import org.apache.archiva.repository.RepositoryEvent;
import org.apache.archiva.repository.events.Event;
import org.apache.archiva.repository.events.RepositoryValueEvent;
import org.apache.archiva.repository.RepositoryException;
import org.apache.archiva.repository.RepositoryGroup;
import org.apache.archiva.repository.RepositoryProvider;
@ -284,7 +285,7 @@ public RemoteRepositoryConfiguration getRemoteConfiguration( RemoteRepository re
}
@Override
public <T> void raise(RepositoryEvent<T> event) {
public void raise(Event event) {
}
}

View File

@ -20,12 +20,12 @@
*/
import org.apache.archiva.indexer.ArchivaIndexingContext;
import org.apache.archiva.repository.events.RepositoryEventHandler;
import org.apache.archiva.repository.storage.RepositoryStorage;
import org.apache.archiva.repository.features.RepositoryFeature;
import org.apache.archiva.repository.storage.StorageAsset;
import java.net.URI;
import java.nio.file.Path;
import java.util.Locale;
import java.util.Set;

View File

@ -22,6 +22,7 @@
import org.apache.archiva.configuration.ManagedRepositoryConfiguration;
import org.apache.archiva.configuration.RemoteRepositoryConfiguration;
import org.apache.archiva.configuration.RepositoryGroupConfiguration;
import org.apache.archiva.repository.events.RepositoryEventListener;
import java.io.IOException;
import java.util.Set;

View File

@ -1,4 +1,4 @@
package org.apache.archiva.repository;
package org.apache.archiva.repository.events;
/*
* Licensed to the Apache Software Foundation (ASF) under one
@ -21,49 +21,47 @@
import java.time.LocalDateTime;
/**
* Repository event. Repository events are used for providing information about repository changes.
*
* @param <T>
*/
public class RepositoryEvent<T> {
public class Event<O> {
Event previous;
final O originator;
final EventType type;
final Repository repo;
final T value;
final T oldValue;
final LocalDateTime instant;
public RepositoryEvent(EventType type, Repository repo, T oldValue, T value) {
public Event(EventType type, O originator) {
this.originator = originator;
this.type = type;
this.repo = repo;
this.value = value;
this.oldValue = oldValue;
this.instant = LocalDateTime.now();
}
public interface EventType {
String name();
private <OO> Event(Event<OO> previous, O originator) {
this.previous = previous;
this.originator = originator;
this.type = previous.getType();
this.instant = previous.getInstant();
}
public EventType getType() {
return type;
};
public Repository getRepository() {
return repo;
};
public T getValue() {
return value;
}
public T getOldValue() {
return oldValue;
}
public LocalDateTime getInstant() {
return instant;
}
public O getOriginator() {
return originator;
}
public <NO> Event<NO> recreate(NO newOrigin) {
return new Event(this, newOrigin);
}
public Event getPreviousEvent() {
return previous;
}
public boolean hasPreviousEvent() {
return previous!=null;
}
}

View File

@ -0,0 +1,25 @@
package org.apache.archiva.repository.events;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
public interface EventType {
String name();
}

View File

@ -0,0 +1,33 @@
package org.apache.archiva.repository.events;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import org.apache.archiva.repository.Repository;
public class LifecycleEvent<O> extends RepositoryEvent<O> {
public enum LifecycleEventType implements EventType {
REGISTERED,UNREGISTERED,UPDATED
}
public LifecycleEvent(LifecycleEventType type, O origin, Repository repository) {
super(type, origin, repository);
}
}

View File

@ -0,0 +1,36 @@
package org.apache.archiva.repository.events;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import org.apache.archiva.repository.Repository;
public class RepositoryEvent<O> extends Event<O> {
private final Repository repository;
public RepositoryEvent(EventType type, O origin, Repository repository) {
super(type, origin);
this.repository = repository;
}
public Repository getRepository() {
return repository;
}
}

View File

@ -0,0 +1,40 @@
package org.apache.archiva.repository.events;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import java.util.Set;
/**
* A repository event handler raises events to its registered listeners.
* Listeners may register for all events that are raised or only to a subset of events.
*
*/
public interface RepositoryEventHandler {
void register(RepositoryEventListener listener);
void register(RepositoryEventListener listener, EventType type);
void register(RepositoryEventListener listener, Set<? extends EventType> types);
void unregister(RepositoryEventListener listener);
void clearListeners();
}

View File

@ -1,4 +1,4 @@
package org.apache.archiva.repository;
package org.apache.archiva.repository.events;
/*
* Licensed to the Apache Software Foundation (ASF) under one
@ -19,10 +19,12 @@
* under the License.
*/
import org.apache.archiva.repository.events.RepositoryValueEvent;
/**
* Listener that accepts repository events.
*/
public interface RepositoryEventListener {
<T> void raise(RepositoryEvent<T> event);
void raise(Event event);
}

View File

@ -1,4 +1,4 @@
package org.apache.archiva.repository;
package org.apache.archiva.repository.events;
/*
* Licensed to the Apache Software Foundation (ASF) under one
@ -19,14 +19,13 @@
* under the License.
*/
/**
* Implementations of this interface are able to handle repository event listeners
*/
public interface RepositoryEventHandler {
public class RepositoryRegistryEvent<O> extends Event {
void addListener(RepositoryEventListener listener);
public enum RegistryEventType implements EventType {
RELOADED,DESTROYED
}
void removeListener(RepositoryEventListener listener);
void clearListeners();
public RepositoryRegistryEvent(RegistryEventType type, O origin) {
super(type, origin);
}
}

View File

@ -0,0 +1,48 @@
package org.apache.archiva.repository.events;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import org.apache.archiva.repository.Repository;
/**
* Repository event. Repository events are used for providing information about repository changes.
*
* @param <V>
*/
public class RepositoryValueEvent<O, V> extends RepositoryEvent<O> {
final V value;
final V oldValue;
public RepositoryValueEvent(EventType type, O origin, Repository repo, V oldValue, V value) {
super(type, origin, repo);
this.value = value;
this.oldValue = oldValue;
}
public V getValue() {
return value;
}
public V getOldValue() {
return oldValue;
}
}

View File

@ -19,8 +19,8 @@
* under the License.
*/
import org.apache.archiva.repository.RepositoryEvent;
import org.apache.archiva.repository.RepositoryEventListener;
import org.apache.archiva.repository.events.Event;
import org.apache.archiva.repository.events.RepositoryEventListener;
import java.util.ArrayList;
import java.util.Collection;
@ -56,7 +56,7 @@ public void clearListeners() {
this.listener.clear();
}
protected <T> void raiseEvent(RepositoryEvent<T> event) {
public void pushEvent(Event event) {
for(RepositoryEventListener listr : listener) {
listr.raise(event);
}

View File

@ -20,29 +20,30 @@
*/
import org.apache.archiva.repository.Repository;
import org.apache.archiva.repository.RepositoryEvent;
import org.apache.archiva.repository.events.EventType;
import org.apache.archiva.repository.events.RepositoryValueEvent;
import java.net.URI;
public class IndexCreationEvent extends RepositoryEvent<URI> {
public class IndexCreationEvent<O> extends RepositoryValueEvent<O, URI> {
public enum Index implements EventType {
INDEX_URI_CHANGE, PACKED_INDEX_URI_CHANGE
}
IndexCreationEvent(Repository repo, URI oldValue, URI value) {
super(Index.INDEX_URI_CHANGE, repo, oldValue, value);
IndexCreationEvent(Repository repo, O origin, URI oldValue, URI value) {
super(Index.INDEX_URI_CHANGE, origin, repo, oldValue, value);
}
IndexCreationEvent(Index type, Repository repo, URI oldValue, URI value) {
super(type, repo, oldValue, value);
IndexCreationEvent(Index type, O origin, Repository repo, URI oldValue, URI value) {
super(type, origin, repo, oldValue, value);
}
public static final IndexCreationEvent indexUriChange(Repository repo, URI oldValue, URI newValue) {
return new IndexCreationEvent(Index.INDEX_URI_CHANGE, repo, oldValue, newValue);
public static final <O> IndexCreationEvent indexUriChange(O origin, Repository repo, URI oldValue, URI newValue) {
return new IndexCreationEvent(Index.INDEX_URI_CHANGE, origin, repo, oldValue, newValue);
}
public static final IndexCreationEvent packedIndexUriChange(Repository repo, URI oldValue, URI newValue) {
return new IndexCreationEvent(Index.PACKED_INDEX_URI_CHANGE, repo, oldValue, newValue);
public static final <O> IndexCreationEvent packedIndexUriChange(O origin, Repository repo, URI oldValue, URI newValue) {
return new IndexCreationEvent(Index.PACKED_INDEX_URI_CHANGE, origin, repo, oldValue, newValue);
}
}

View File

@ -21,7 +21,7 @@
import org.apache.archiva.repository.Repository;
import org.apache.archiva.repository.RepositoryEventListener;
import org.apache.archiva.repository.events.RepositoryEventListener;
import org.apache.archiva.repository.storage.StorageAsset;
import org.apache.commons.lang3.StringUtils;
@ -113,7 +113,7 @@ public void setIndexPath( URI indexPath )
{
URI oldVal = this.indexPath;
this.indexPath = indexPath;
raiseEvent(IndexCreationEvent.indexUriChange(repo, oldVal, this.indexPath));
pushEvent(IndexCreationEvent.indexUriChange(this, repo, oldVal, this.indexPath));
}
@ -157,7 +157,7 @@ public URI getPackedIndexPath() {
public void setPackedIndexPath(URI packedIndexPath) {
URI oldVal = this.packedIndexPath;
this.packedIndexPath = packedIndexPath;
raiseEvent(IndexCreationEvent.packedIndexUriChange(repo, oldVal, this.packedIndexPath));
pushEvent(IndexCreationEvent.packedIndexUriChange(this, repo, oldVal, this.packedIndexPath));
}
/**

View File

@ -23,6 +23,7 @@
import org.apache.commons.lang3.StringUtils;
import java.net.URI;
import java.net.URISyntaxException;
import java.time.Duration;
/**
@ -32,6 +33,15 @@ public class RemoteIndexFeature implements RepositoryFeature<RemoteIndexFeature>
private boolean downloadRemoteIndex = false;
private URI indexUri;
{
try {
indexUri = new URI(".index");
} catch (URISyntaxException e) {
// Ignore
}
}
private boolean downloadRemoteIndexOnStartup = false;
private Duration downloadTimeout = Duration.ofSeconds( 600 );
private String proxyId = "";

View File

@ -24,6 +24,7 @@
import com.cronutils.model.definition.CronDefinitionBuilder;
import com.cronutils.parser.CronParser;
import org.apache.archiva.indexer.ArchivaIndexingContext;
import org.apache.archiva.repository.events.*;
import org.apache.archiva.repository.storage.RepositoryStorage;
import org.apache.archiva.repository.storage.StorageAsset;
import org.apache.archiva.repository.features.RepositoryFeature;
@ -39,7 +40,6 @@
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.nio.file.CopyOption;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@ -76,6 +76,7 @@ public abstract class AbstractRepository implements EditableRepository, Reposito
private String layout = "default";
public static final CronDefinition CRON_DEFINITION = CronDefinitionBuilder.instanceDefinitionFor(CronType.QUARTZ);
private List<RepositoryEventListener> listeners = new ArrayList<>();
private Map<EventType, List<RepositoryEventListener>> listenerTypeMap = new HashMap<>();
Map<Class<? extends RepositoryFeature<?>>, RepositoryFeature<?>> featureMap = new HashMap<>( );
@ -315,24 +316,65 @@ public void close() {
}
@Override
public <T> void raise(RepositoryEvent<T> event) {
for(RepositoryEventListener listener : listeners) {
listener.raise(event);
public void raise(Event event) {
callListeners(event, listeners);
if (listenerTypeMap.containsKey(event.getType())) {
callListeners(event, listenerTypeMap.get(event.getType()));
}
}
public void addListener(RepositoryEventListener listener) {
private void callListeners(Event event, List<RepositoryEventListener> evtListeners) {
for(RepositoryEventListener listener : evtListeners) {
try {
listener.raise(event);
} catch (Throwable e) {
log.error("Could not raise event {} on listener {}: {}", event, listener, e.getMessage());
}
}
}
@Override
public void register(RepositoryEventListener listener) {
if (!this.listeners.contains(listener)) {
this.listeners.add(listener);
}
}
public void removeListener(RepositoryEventListener listener) {
this.removeListener(listener);
@Override
public void register(RepositoryEventListener listener, EventType type) {
List<RepositoryEventListener> listeners;
if (listenerTypeMap.containsKey(type)) {
listeners = listenerTypeMap.get(type);
} else {
listeners = new ArrayList<>();
listenerTypeMap.put(type, listeners);
}
if (!listeners.contains(listener)) {
listeners.add(listener);
}
}
@Override
public void register(RepositoryEventListener listener, Set<? extends EventType> types) {
for (EventType type : types) {
register(listener, type);
}
}
@Override
public void unregister(RepositoryEventListener listener) {
listeners.remove(listener);
for (List<RepositoryEventListener> listeners : listenerTypeMap.values()) {
listeners.remove(listener);
}
}
@Override
public void clearListeners() {
this.listeners.clear();
this.listenerTypeMap.clear();
}
@Override

View File

@ -23,6 +23,8 @@
import org.apache.archiva.configuration.RemoteRepositoryConfiguration;
import org.apache.archiva.configuration.RepositoryGroupConfiguration;
import org.apache.archiva.repository.*;
import org.apache.archiva.repository.events.Event;
import org.apache.archiva.repository.events.RepositoryValueEvent;
import org.apache.archiva.repository.features.ArtifactCleanupFeature;
import org.apache.archiva.repository.features.IndexCreationFeature;
import org.apache.archiva.repository.features.RemoteIndexFeature;
@ -259,7 +261,7 @@ public RemoteRepositoryConfiguration getRemoteConfiguration( RemoteRepository re
}
@Override
public <T> void raise(RepositoryEvent<T> event) {
public void raise(Event event) {
}
}

View File

@ -32,7 +32,8 @@
import org.apache.archiva.repository.ReleaseScheme;
import org.apache.archiva.repository.RemoteRepository;
import org.apache.archiva.repository.RepositoryCredentials;
import org.apache.archiva.repository.RepositoryEvent;
import org.apache.archiva.repository.events.Event;
import org.apache.archiva.repository.events.RepositoryValueEvent;
import org.apache.archiva.repository.RepositoryException;
import org.apache.archiva.repository.RepositoryGroup;
import org.apache.archiva.repository.RepositoryProvider;
@ -280,7 +281,7 @@ public RemoteRepositoryConfiguration getRemoteConfiguration( RemoteRepository re
}
@Override
public <T> void raise(RepositoryEvent<T> event) {
public void raise(Event event) {
}
}