diff options
author | Martin Schreier <martin_s@apache.org> | 2022-02-13 10:27:32 +0100 |
---|---|---|
committer | Martin Schreier <martin_s@apache.org> | 2022-02-13 10:27:32 +0100 |
commit | 0a2dab16770cce10bda6fa2cc2e2d9c7d64c5dbf (patch) | |
tree | 1e633e0ae7fc56a857b5467a12a67adfc017b9e2 | |
parent | 99bd81ac000598105529473a53f62a5b53d885a5 (diff) | |
download | archiva-0a2dab16770cce10bda6fa2cc2e2d9c7d64c5dbf.tar.gz archiva-0a2dab16770cce10bda6fa2cc2e2d9c7d64c5dbf.zip |
Improving event API
41 files changed, 942 insertions, 132 deletions
diff --git a/archiva-modules/archiva-base/archiva-consumers/archiva-consumer-archetype/pom.xml b/archiva-modules/archiva-base/archiva-consumers/archiva-consumer-archetype/pom.xml index 42844565e..6e2f82f47 100644 --- a/archiva-modules/archiva-base/archiva-consumers/archiva-consumer-archetype/pom.xml +++ b/archiva-modules/archiva-base/archiva-consumers/archiva-consumer-archetype/pom.xml @@ -76,6 +76,12 @@ <artifactId>jcl-over-slf4j</artifactId> </dependency> + <!-- Test scope --> + <dependency> + <groupId>org.apache.archiva.event</groupId> + <artifactId>archiva-event-api</artifactId> + <scope>test</scope> + </dependency> <dependency> <groupId>org.apache.archiva</groupId> <artifactId>archiva-consumer-api</artifactId> diff --git a/archiva-modules/archiva-base/archiva-event-api/pom.xml b/archiva-modules/archiva-base/archiva-event-api/pom.xml new file mode 100644 index 000000000..6c9119c53 --- /dev/null +++ b/archiva-modules/archiva-base/archiva-event-api/pom.xml @@ -0,0 +1,41 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ 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. + --> + +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <parent> + <artifactId>archiva-base</artifactId> + <groupId>org.apache.archiva</groupId> + <version>3.0.0-SNAPSHOT</version> + </parent> + <modelVersion>4.0.0</modelVersion> + + <name>Archiva :: Base :: Event API</name> + <groupId>org.apache.archiva.event</groupId> + <artifactId>archiva-event-api</artifactId> + + <dependencies> + <dependency> + <groupId>org.apache.archiva</groupId> + <artifactId>archiva-common</artifactId> + </dependency> + </dependencies> + +</project>
\ No newline at end of file diff --git a/archiva-modules/archiva-base/archiva-common/src/main/java/org/apache/archiva/event/EventManager.java b/archiva-modules/archiva-base/archiva-event-api/src/main/java/org/apache/archiva/event/AbstractEventManager.java index 00a240066..6d2ddff7a 100644 --- a/archiva-modules/archiva-base/archiva-common/src/main/java/org/apache/archiva/event/EventManager.java +++ b/archiva-modules/archiva-base/archiva-event-api/src/main/java/org/apache/archiva/event/AbstractEventManager.java @@ -1,5 +1,4 @@ package org.apache.archiva.event; - /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file @@ -9,8 +8,7 @@ package org.apache.archiva.event; * "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 - * + * 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 @@ -22,41 +20,47 @@ package org.apache.archiva.event; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.*; +import java.util.LinkedHashSet; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; -public class EventManager implements EventSource +/** + * @author Martin Schreier <martin_s@apache.org> + */ +public class AbstractEventManager implements EventSource { + private static final Logger log = LoggerFactory.getLogger( AbstractEventManager.class ); - private static final Logger LOG = LoggerFactory.getLogger(EventManager.class); - - private final ConcurrentHashMap<EventType<? extends Event>, Set<EventHandler>> handlerMap = new ConcurrentHashMap<>(); - - private final Object source; - - public EventManager(Object source) { - if (source==null) { - throw new IllegalArgumentException("The source may not be null"); - } - this.source = source; - } + protected final ConcurrentHashMap<EventType<? extends Event>, Set<EventHandler>> handlerMap = new ConcurrentHashMap<>(); @Override - public <T extends Event> void registerEventHandler(EventType<T> type, EventHandler<? super T> eventHandler) { + public <T extends Event> void registerEventHandler( EventType<T> type, EventHandler<? super T> eventHandler) { Set<EventHandler> handlers = handlerMap.computeIfAbsent(type, t -> new LinkedHashSet<>()); if (!handlers.contains(eventHandler)) { handlers.add(eventHandler); } + log.debug( "Event handler registered: " + eventHandler.getClass( ) ); } @Override - public <T extends Event> void unregisterEventHandler(EventType<T> type, EventHandler<? super T> eventHandler) { + public <T extends Event> void unregisterEventHandler( EventType<T> type, EventHandler<? super T> eventHandler) { if (handlerMap.containsKey(type)) { handlerMap.get(type).remove(eventHandler); + log.debug( "Event handler unregistered: " + eventHandler.getClass( ) ); } } - public void fireEvent(Event fireEvent) { + /** + * Fires the given event for the given source. If the source of the provided event does not match the <code>source</code> + * parameter the event will be chained. + * + * The event will be sent to all registered event handler. Exceptions during handling are not propagated to the + * caller. + * + * @param fireEvent the event to fire + * @param source the source object + */ + public void fireEvent(Event fireEvent, Object source) { final EventType<? extends Event> type = fireEvent.getType(); Event event; if (fireEvent.getSource()!=source) { @@ -66,14 +70,14 @@ public class EventManager implements EventSource } for (EventType<? extends Event> handlerType : handlerMap.keySet()) { if (EventType.isInstanceOf(type, handlerType)) { - for (EventHandler handler : handlerMap.get(handlerType)) { - try { - handler.handle(event); - } catch (Exception e) { - // We catch all errors from handlers - LOG.error("An error occured during event handling: {}", e.getMessage(), e); - } + for (EventHandler handler : handlerMap.get(handlerType)) { + try { + handler.handle(event); + } catch (Throwable e) { + // We catch all errors from handlers + log.error("An error occured during event handling: {}", e.getMessage(), e); } + } } } } diff --git a/archiva-modules/archiva-base/archiva-event-api/src/main/java/org/apache/archiva/event/BasicEventManager.java b/archiva-modules/archiva-base/archiva-event-api/src/main/java/org/apache/archiva/event/BasicEventManager.java new file mode 100644 index 000000000..f952b9eaa --- /dev/null +++ b/archiva-modules/archiva-base/archiva-event-api/src/main/java/org/apache/archiva/event/BasicEventManager.java @@ -0,0 +1,41 @@ +package org.apache.archiva.event; + +/* + * 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.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class BasicEventManager extends AbstractEventManager implements EventSource +{ + + private static final Logger LOG = LoggerFactory.getLogger( BasicEventManager.class); + + private final Object source; + + public BasicEventManager( Object source) { + if (source==null) { + throw new IllegalArgumentException("The source may not be null"); + } + this.source = source; + } + + public void fireEvent(Event fireEvent) { + super.fireEvent( fireEvent, source ); + } +} diff --git a/archiva-modules/archiva-base/archiva-common/src/main/java/org/apache/archiva/event/Event.java b/archiva-modules/archiva-base/archiva-event-api/src/main/java/org/apache/archiva/event/Event.java index eda85701e..2439105de 100644 --- a/archiva-modules/archiva-base/archiva-common/src/main/java/org/apache/archiva/event/Event.java +++ b/archiva-modules/archiva-base/archiva-event-api/src/main/java/org/apache/archiva/event/Event.java @@ -9,8 +9,7 @@ package org.apache.archiva.event; * "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 - * + * 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 @@ -21,6 +20,9 @@ package org.apache.archiva.event; import java.time.LocalDateTime; import java.util.EventObject; +import java.util.HashMap; +import java.util.Map; +import java.util.stream.Collectors; /** * Base class for events. Events have a type and a source. @@ -41,6 +43,8 @@ public class Event extends EventObject implements Cloneable { private final EventType<? extends Event> type; private final LocalDateTime createTime; + private HashMap<Class<? extends EventContext>, EventContext> contextMap = new HashMap<>( ); + public Event(EventType<? extends Event> type, Object originator) { super(originator); this.type = type; @@ -52,6 +56,7 @@ public class Event extends EventObject implements Cloneable { this.previous = previous; this.type = previous.getType(); this.createTime = previous.getCreateTime(); + this.contextMap = previous.contextMap; } /** @@ -70,6 +75,38 @@ public class Event extends EventObject implements Cloneable { return createTime; } + public <T extends EventContext> T getContext(Class<T> contextClazz) throws IllegalArgumentException { + if (contextMap.containsKey( contextClazz )) { + return (T) contextMap.get( contextClazz ); + } else { + T ctx = null; + for ( Map.Entry<Class<? extends EventContext>, EventContext> clazzEntry : contextMap.entrySet()) { + if ( contextClazz.isAssignableFrom( clazzEntry.getKey() ) ) + { + ctx = (T) clazzEntry.getValue( ); + break; + } + } + if (ctx!=null) { + contextMap.put( contextClazz, ctx ); + return ctx; + } + } + throw new IllegalArgumentException( "No matching event context registered for " + contextClazz ); + } + + public Map<String, String> getContextData() { + return contextMap.entrySet( ).stream( ).flatMap( ctx -> ctx.getValue( ).getData( ).entrySet( ).stream( ) ) + .collect( Collectors.toMap( Map.Entry::getKey, Map.Entry::getValue ) ); + } + + public <T extends EventContext> void setContext( Class<T> clazz, T context) { + this.contextMap.put( clazz, context ); + } + + public <T extends EventContext> void setContext( T context) { + this.contextMap.put( context.getClass(), context ); + } /** * Recreates the event with the given instance as the new source. The @@ -81,6 +118,7 @@ public class Event extends EventObject implements Cloneable { Event newEvent = (Event) this.clone(); newEvent.previous = this; newEvent.source = newSource; + newEvent.contextMap = this.contextMap; return newEvent; } diff --git a/archiva-modules/archiva-base/archiva-event-api/src/main/java/org/apache/archiva/event/EventContext.java b/archiva-modules/archiva-base/archiva-event-api/src/main/java/org/apache/archiva/event/EventContext.java new file mode 100644 index 000000000..9e113de06 --- /dev/null +++ b/archiva-modules/archiva-base/archiva-event-api/src/main/java/org/apache/archiva/event/EventContext.java @@ -0,0 +1,48 @@ +package org.apache.archiva.event; +/* + * 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.Map; + +/** + * Context information about a specific event. + * This is used to provide specific information about the event context by using the generic + * event interface. + * Some event handler may need information about the underlying event but have no access to the + * API classes that represent the event. + * + * Context information is always string based and should not depend on external classes apart from JDK classes. + * + * @author Martin Schreier <martin_s@apache.org> + */ +public interface EventContext +{ + /** + * Returns the prefix used for entry keys in the repository data map. + * @return the prefix string for this context + */ + String getPrefix(); + + /** + * Returns the context data as map of strings. Each entry key is prefixed with + * the unique prefix of this context. + * + * @return the map of key value pairs stored in this context + */ + Map<String,String> getData(); +} diff --git a/archiva-modules/archiva-base/archiva-event-api/src/main/java/org/apache/archiva/event/EventContextBuilder.java b/archiva-modules/archiva-base/archiva-event-api/src/main/java/org/apache/archiva/event/EventContextBuilder.java new file mode 100644 index 000000000..41f10ceec --- /dev/null +++ b/archiva-modules/archiva-base/archiva-event-api/src/main/java/org/apache/archiva/event/EventContextBuilder.java @@ -0,0 +1,72 @@ +package org.apache.archiva.event; +/* + * 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.event.context.RepositoryContext; +import org.apache.archiva.event.context.RestContext; +import org.apache.archiva.event.context.UserContext; + +/** + * Static helper class that allows to set certain context data + * + * @author Martin Schreier <martin_s@apache.org> + */ +public class EventContextBuilder +{ + Event evt; + + public static void setUserContext(Event evt, String user, String remoteAddress) { + evt.setContext( UserContext.class, new UserContext( user, remoteAddress ) ); + } + + public static void setRestcontext(Event evt, String service, String path, String operation, int resultCode, String... parameters ) { + evt.setContext( RestContext.class, new RestContext( service, path, operation, resultCode, parameters ) ); + } + + public static void setRepositoryContext(Event evt, String id, String type, String flavour ) { + evt.setContext( RepositoryContext.class, new RepositoryContext( id, type, flavour ) ); + } + + private EventContextBuilder( Event evt) { + this.evt = evt; + } + + public static EventContextBuilder withEvent( Event evt ) + { + return new EventContextBuilder( evt ); + } + + public EventContextBuilder withUser( String user, String remoteAddress) { + setUserContext( this.evt, user, remoteAddress ); + return this; + } + + public EventContextBuilder witRest( String service, String path, String operation, int resultCode, String... parameters) { + setRestcontext( this.evt, service, path, operation, resultCode, parameters ); + return this; + } + + public EventContextBuilder withRepository(String id, String type, String flavour) { + setRepositoryContext( this.evt, id, type, flavour ); + return this; + } + + public Event apply() { + return this.evt; + } +} diff --git a/archiva-modules/archiva-base/archiva-common/src/main/java/org/apache/archiva/event/EventHandler.java b/archiva-modules/archiva-base/archiva-event-api/src/main/java/org/apache/archiva/event/EventHandler.java index f98adcdab..f98adcdab 100644 --- a/archiva-modules/archiva-base/archiva-common/src/main/java/org/apache/archiva/event/EventHandler.java +++ b/archiva-modules/archiva-base/archiva-event-api/src/main/java/org/apache/archiva/event/EventHandler.java diff --git a/archiva-modules/archiva-base/archiva-common/src/main/java/org/apache/archiva/event/EventSource.java b/archiva-modules/archiva-base/archiva-event-api/src/main/java/org/apache/archiva/event/EventSource.java index 452a5e9d9..452a5e9d9 100644 --- a/archiva-modules/archiva-base/archiva-common/src/main/java/org/apache/archiva/event/EventSource.java +++ b/archiva-modules/archiva-base/archiva-event-api/src/main/java/org/apache/archiva/event/EventSource.java diff --git a/archiva-modules/archiva-base/archiva-common/src/main/java/org/apache/archiva/event/EventType.java b/archiva-modules/archiva-base/archiva-event-api/src/main/java/org/apache/archiva/event/EventType.java index 50d42679e..6927c818a 100644 --- a/archiva-modules/archiva-base/archiva-common/src/main/java/org/apache/archiva/event/EventType.java +++ b/archiva-modules/archiva-base/archiva-event-api/src/main/java/org/apache/archiva/event/EventType.java @@ -9,8 +9,7 @@ package org.apache.archiva.event; * "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 - * + * 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 @@ -82,6 +81,18 @@ public class EventType<T extends Event> implements Serializable { return superType; } + public String getPath() { + List<String> path = new ArrayList<>( ); + EventType eventType = this; + while(eventType!=ROOT) + { + path.add( eventType.name( ) ); + eventType = this.getSuperType( ); + } + Collections.reverse( path ); + return String.join( "/", path ); + } + private void register(EventType<? extends T> subType) { if (subTypes == null) { subTypes = new WeakHashMap<>(); diff --git a/archiva-modules/archiva-base/archiva-event-api/src/main/java/org/apache/archiva/event/context/RepositoryContext.java b/archiva-modules/archiva-base/archiva-event-api/src/main/java/org/apache/archiva/event/context/RepositoryContext.java new file mode 100644 index 000000000..4df023d1b --- /dev/null +++ b/archiva-modules/archiva-base/archiva-event-api/src/main/java/org/apache/archiva/event/context/RepositoryContext.java @@ -0,0 +1,90 @@ +package org.apache.archiva.event.context; +/* + * 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.event.EventContext; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; + +/** + * This context provides repository data. + * + * @author Martin Schreier <martin_s@apache.org> + */ +public class RepositoryContext implements EventContext, Serializable +{ + private static final long serialVersionUID = -4172663291198878307L; + + private static final String PREFIX = "repository"; + + private final String id; + private final String type; + private final String flavour; + + public RepositoryContext( String id, String type, String flavour ) + { + this.id = id; + this.type = type; + this.flavour = flavour; + } + + /** + * Returns the repository id + * @return the repository id + */ + public String getId( ) + { + return id; + } + + /** + * Returns the repository type (e.g. MAVEN) + * @return the string representation of the repository type + */ + public String getType( ) + { + return type; + } + + /** + * Returns the repository flavour (e.g. Remote, Managed, Group) + * @return + */ + public String getFlavour( ) + { + return flavour; + } + + @Override + public Map<String, String> getData( ) + { + Map<String, String> values = new HashMap<>( ); + values.put( PREFIX+".id", id ); + values.put( PREFIX+".type", type ); + values.put( PREFIX+".flavour", flavour ); + return values; + } + + @Override + public String getPrefix( ) + { + return PREFIX; + } +} diff --git a/archiva-modules/archiva-base/archiva-event-api/src/main/java/org/apache/archiva/event/context/RestContext.java b/archiva-modules/archiva-base/archiva-event-api/src/main/java/org/apache/archiva/event/context/RestContext.java new file mode 100644 index 000000000..615759d42 --- /dev/null +++ b/archiva-modules/archiva-base/archiva-event-api/src/main/java/org/apache/archiva/event/context/RestContext.java @@ -0,0 +1,96 @@ +package org.apache.archiva.event.context; +/* + * 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.event.EventContext; + +import java.io.Serializable; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Provides information about a REST call. + * + * @author Martin Schreier <martin_s@apache.org> + */ +public class RestContext implements EventContext, Serializable +{ + private static final long serialVersionUID = -4109505194250928317L; + + public static final String PREFIX = "rest"; + + private final String service; + private final String path; + private final String operation; + private final List<String> parameters; + private final int resultCode; + + + public RestContext( String service, String path, String operation, int resultCode, String... parameters ) + { + this.service = service; + this.path = path; + this.operation = operation; + this.resultCode = resultCode; + this.parameters = Arrays.asList( parameters ); + } + + public String getService( ) + { + return service; + } + + public String getPath( ) + { + return path; + } + + public String getOperation( ) + { + return operation; + } + + public List<String> getParameters( ) + { + return parameters; + } + + public int getResultCode( ) + { + return resultCode; + } + + @Override + public Map<String, String> getData( ) + { + Map<String, String> values = new HashMap<>( ); + values.put( PREFIX+".service", service ); + values.put( PREFIX+".path", path ); + values.put( PREFIX+".operation", operation ); + values.put( PREFIX+".parameter", String.join( ",", parameters ) ); + return values; + } + + @Override + public String getPrefix( ) + { + return PREFIX; + } +} diff --git a/archiva-modules/archiva-base/archiva-event-api/src/main/java/org/apache/archiva/event/context/UserContext.java b/archiva-modules/archiva-base/archiva-event-api/src/main/java/org/apache/archiva/event/context/UserContext.java new file mode 100644 index 000000000..8a83c73c8 --- /dev/null +++ b/archiva-modules/archiva-base/archiva-event-api/src/main/java/org/apache/archiva/event/context/UserContext.java @@ -0,0 +1,71 @@ +package org.apache.archiva.event.context; +/* + * 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.event.EventContext; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; + +/** + * This context provides user information. + * + * @author Martin Schreier <martin_s@apache.org> + */ +public class UserContext implements EventContext, Serializable +{ + private static final long serialVersionUID = -3499164111736559781L; + + private static final String PREFIX = "user"; + + private final String userId; + private final String remoteAddress; + + public UserContext( String user, String remoteAddress ) + { + this.userId = user == null ? "" : user; + this.remoteAddress = remoteAddress == null ? "" : remoteAddress; + + } + + public String getUserId( ) + { + return userId; + } + + public String getRemoteAddress( ) + { + return remoteAddress; + } + + @Override + public Map<String, String> getData( ) + { + Map<String, String> values = new HashMap<>( ); + values.put( PREFIX+".user_id", userId ); + values.put( PREFIX+".remote_address", remoteAddress ); + return values; + } + + @Override + public String getPrefix( ) + { + return PREFIX; + } +} diff --git a/archiva-modules/archiva-base/archiva-event-api/src/main/java/org/apache/archiva/event/package-info.java b/archiva-modules/archiva-base/archiva-event-api/src/main/java/org/apache/archiva/event/package-info.java new file mode 100644 index 000000000..30db350f0 --- /dev/null +++ b/archiva-modules/archiva-base/archiva-event-api/src/main/java/org/apache/archiva/event/package-info.java @@ -0,0 +1,37 @@ +/* + * 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. + */ + +/** + * This module provides an event mechanism for all archiva subsystems. + * + * The events are hierarchical organized. That means each subsystem has its own event manager that collects events + * and processes and forwards them to the parent event manager (normally the central event manager). + * Each event manager clones the event and stores the origin event in the chain before forwarding them to the parent manager. + * + * Event Types are also hierarchical. There is one special type {@link org.apache.archiva.event.EventType#ROOT} that is the + * root type and has no parent type. All other types must be descendants of the ROOT type. + * + * Event types may have certain methods to access context information. But context information can also be accessed in a + * subsystem independent way using the event context data. Event contexts provide access to data without using the + * subsystem API and classes. + * Event types may be used for filtering events. + * + * @since 3.0 + * @author Martin Schreier <martin_s@apache.org> + */ +package org.apache.archiva.event;
\ No newline at end of file diff --git a/archiva-modules/archiva-base/archiva-common/src/test/java/org/apache/archiva/event/EventManagerTest.java b/archiva-modules/archiva-base/archiva-event-api/src/test/java/org/apache/archiva/event/BasicEventManagerTest.java index f894cb574..6e0ba611b 100644 --- a/archiva-modules/archiva-base/archiva-common/src/test/java/org/apache/archiva/event/EventManagerTest.java +++ b/archiva-modules/archiva-base/archiva-event-api/src/test/java/org/apache/archiva/event/BasicEventManagerTest.java @@ -9,8 +9,7 @@ package org.apache.archiva.event; * "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 - * + * 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 @@ -29,7 +28,7 @@ import static org.junit.jupiter.api.Assertions.*; /** * @author Martin Stockhammer <martin_s@apache.org> */ -public class EventManagerTest +public class BasicEventManagerTest { private class TestHandler implements EventHandler<Event> { @@ -53,7 +52,7 @@ public class EventManagerTest @Test public void registerEventHandler( ) { - EventManager eventManager = new EventManager( this ); + BasicEventManager eventManager = new BasicEventManager( this ); TestHandler handler1 = new TestHandler( ); TestHandler handler2 = new TestHandler( ); TestHandler handler3 = new TestHandler( ); @@ -92,7 +91,7 @@ public class EventManagerTest @Test public void unregisterEventHandler( ) { - EventManager eventManager = new EventManager( this ); + BasicEventManager eventManager = new BasicEventManager( this ); TestHandler handler1 = new TestHandler( ); TestHandler handler2 = new TestHandler( ); TestHandler handler3 = new TestHandler( ); @@ -124,7 +123,7 @@ public class EventManagerTest public void fireEvent( ) { Object other = new Object( ); - EventManager eventManager = new EventManager( this ); + BasicEventManager eventManager = new BasicEventManager( this ); assertThrows( NullPointerException.class, ( ) -> eventManager.fireEvent( null ) ); Event event = new Event( EventType.ROOT, other ); assertEquals( other, event.getSource( ) ); diff --git a/archiva-modules/archiva-base/archiva-event-central/pom.xml b/archiva-modules/archiva-base/archiva-event-central/pom.xml new file mode 100644 index 000000000..cd8a5b084 --- /dev/null +++ b/archiva-modules/archiva-base/archiva-event-central/pom.xml @@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ 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. + --> + +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <parent> + <artifactId>archiva-base</artifactId> + <groupId>org.apache.archiva</groupId> + <version>3.0.0-SNAPSHOT</version> + </parent> + <modelVersion>4.0.0</modelVersion> + + <groupId>org.apache.archiva.event</groupId> + <artifactId>archiva-event-central</artifactId> + + <dependencies> + <dependency> + <groupId>org.apache.archiva.event</groupId> + <artifactId>archiva-event-api</artifactId> + </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-context</artifactId> + </dependency> + </dependencies> + +</project>
\ No newline at end of file diff --git a/archiva-modules/archiva-base/archiva-event-central/src/main/java/org/apache/archiva/event/central/CentralEventManager.java b/archiva-modules/archiva-base/archiva-event-central/src/main/java/org/apache/archiva/event/central/CentralEventManager.java new file mode 100644 index 000000000..44ba9df43 --- /dev/null +++ b/archiva-modules/archiva-base/archiva-event-central/src/main/java/org/apache/archiva/event/central/CentralEventManager.java @@ -0,0 +1,42 @@ +package org.apache.archiva.event.central; +/* + * 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.event.AbstractEventManager; +import org.apache.archiva.event.Event; +import org.apache.archiva.event.EventHandler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +/** + * Event manager that collects all events from archiva subsystems. + * + * @author Martin Schreier <martin_s@apache.org> + */ +@Service("eventManager#archiva") +public class CentralEventManager extends AbstractEventManager implements EventHandler<Event> +{ + private static final Logger log = LoggerFactory.getLogger( CentralEventManager.class ); + + @Override + public void handle( Event event ) + { + log.info( "Event: type={}, sourceClass={}, source={}", event.getType( ), event.getSource().getClass(), event.getSource() ); + } +} diff --git a/archiva-modules/archiva-base/archiva-event-central/src/main/resources/META-INF/spring-context.xml b/archiva-modules/archiva-base/archiva-event-central/src/main/resources/META-INF/spring-context.xml new file mode 100644 index 000000000..654b2f876 --- /dev/null +++ b/archiva-modules/archiva-base/archiva-event-central/src/main/resources/META-INF/spring-context.xml @@ -0,0 +1,32 @@ +<?xml version="1.0"?> + +<!-- + ~ 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. + --> +<beans xmlns="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:context="http://www.springframework.org/schema/context" + xsi:schemaLocation="http://www.springframework.org/schema/beans + http://www.springframework.org/schema/beans/spring-beans.xsd + http://www.springframework.org/schema/context + http://www.springframework.org/schema/context/spring-context.xsd" + default-lazy-init="true"> + + <context:annotation-config /> + <context:component-scan base-package="org.apache.archiva.event.central"/> + +</beans>
\ No newline at end of file diff --git a/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-default/pom.xml b/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-default/pom.xml index 8c231f2c1..b34922d17 100644 --- a/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-default/pom.xml +++ b/archiva-modules/archiva-base/archiva-repository-admin/archiva-repository-admin-default/pom.xml @@ -34,6 +34,10 @@ <dependencies> <dependency> + <groupId>org.apache.archiva.event</groupId> + <artifactId>archiva-event-api</artifactId> + </dependency> + <dependency> <groupId>org.apache.archiva.configuration</groupId> <artifactId>archiva-configuration-provider</artifactId> </dependency> diff --git a/archiva-modules/archiva-base/archiva-repository-api/pom.xml b/archiva-modules/archiva-base/archiva-repository-api/pom.xml index 4ae27d9e3..820525f9c 100644 --- a/archiva-modules/archiva-base/archiva-repository-api/pom.xml +++ b/archiva-modules/archiva-base/archiva-repository-api/pom.xml @@ -35,6 +35,10 @@ <dependencies> <dependency> + <groupId>org.apache.archiva.event</groupId> + <artifactId>archiva-event-api</artifactId> + </dependency> + <dependency> <groupId>org.apache.archiva</groupId> <artifactId>archiva-common</artifactId> </dependency> diff --git a/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/RepositoryHandler.java b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/RepositoryHandler.java index 8ed6c37da..4b877d905 100644 --- a/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/RepositoryHandler.java +++ b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/RepositoryHandler.java @@ -277,11 +277,11 @@ public interface RepositoryHandler<R extends Repository, C extends AbstractRepos * Returns the repository variant, this handler manages. * @return the concrete variant class */ - Class<R> getVariant(); + Class<R> getFlavour(); /** * Returns the repository configuration variant, this handler manages. * @return the concrete configuration variant class */ - Class<C> getConfigurationVariant(); + Class<C> getConfigurationFlavour(); } diff --git a/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/event/RepositoryEvent.java b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/event/RepositoryEvent.java index 88c95adde..a4b667b3c 100644 --- a/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/event/RepositoryEvent.java +++ b/archiva-modules/archiva-base/archiva-repository-api/src/main/java/org/apache/archiva/repository/event/RepositoryEvent.java @@ -20,8 +20,12 @@ package org.apache.archiva.repository.event; */ import org.apache.archiva.event.Event; +import org.apache.archiva.event.EventContextBuilder; import org.apache.archiva.event.EventType; +import org.apache.archiva.repository.ManagedRepository; +import org.apache.archiva.repository.RemoteRepository; import org.apache.archiva.repository.Repository; +import org.apache.archiva.repository.RepositoryGroup; /** * A repository event is specific to a repository and holds a reference to the repository that @@ -39,6 +43,12 @@ public class RepositoryEvent extends Event public RepositoryEvent(EventType<? extends RepositoryEvent> type, Object origin, Repository repository) { super(type, origin); this.repository = repository; + EventContextBuilder builder = EventContextBuilder.withEvent( this ); + if (repository!=null) + { + builder.withRepository( repository.getId( ), repository.getType( ).name( ), getFlavour( repository ) ); + } + builder.apply( ); } public Repository getRepository() { @@ -49,4 +59,16 @@ public class RepositoryEvent extends Event public EventType<? extends RepositoryEvent> getType() { return (EventType<? extends RepositoryEvent>) super.getType(); } + + private String getFlavour(Repository repository) { + if (repository instanceof RemoteRepository ) { + return RemoteRepository.class.getName( ); + } else if (repository instanceof ManagedRepository ) { + return ManagedRepository.class.getName( ); + } else if ( repository instanceof RepositoryGroup ) { + return RepositoryGroup.class.getName( ); + } else { + return "UNKNOWN"; + } + } } diff --git a/archiva-modules/archiva-base/archiva-repository-layer/pom.xml b/archiva-modules/archiva-base/archiva-repository-layer/pom.xml index b9b6f4558..8c424f6de 100644 --- a/archiva-modules/archiva-base/archiva-repository-layer/pom.xml +++ b/archiva-modules/archiva-base/archiva-repository-layer/pom.xml @@ -70,6 +70,10 @@ <artifactId>archiva-common</artifactId> </dependency> <dependency> + <groupId>org.apache.archiva.event</groupId> + <artifactId>archiva-event-central</artifactId> + </dependency> + <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> </dependency> diff --git a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/base/AbstractRepository.java b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/base/AbstractRepository.java index ca15e5f31..7a10b7387 100644 --- a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/base/AbstractRepository.java +++ b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/base/AbstractRepository.java @@ -24,7 +24,7 @@ import com.cronutils.model.definition.CronDefinition; import com.cronutils.model.definition.CronDefinitionBuilder; import org.apache.archiva.event.Event; import org.apache.archiva.event.EventHandler; -import org.apache.archiva.event.EventManager; +import org.apache.archiva.event.BasicEventManager; import org.apache.archiva.event.EventType; import org.apache.archiva.indexer.ArchivaIndexingContext; import org.apache.archiva.repository.EditableRepository; @@ -86,7 +86,7 @@ public abstract class AbstractRepository implements EditableRepository, EventHan public static final CronDefinition CRON_DEFINITION = CronDefinitionBuilder.instanceDefinitionFor(CronType.QUARTZ); private RepositoryState state; - private final EventManager eventManager; + private final BasicEventManager eventManager; Map<Class<? extends RepositoryFeature<?>>, RepositoryFeature<?>> featureMap = new HashMap<>( ); @@ -100,7 +100,7 @@ public abstract class AbstractRepository implements EditableRepository, EventHan this.storage = repositoryStorage; this.location = repositoryStorage.getLocation(); this.openStatus.compareAndSet(false, true); - this.eventManager = new EventManager(this); + this.eventManager = new BasicEventManager(this); } public AbstractRepository(Locale primaryLocale, RepositoryType type, String id, String name, RepositoryStorage repositoryStorage) { @@ -111,7 +111,7 @@ public abstract class AbstractRepository implements EditableRepository, EventHan this.storage = repositoryStorage; this.location = repositoryStorage.getLocation(); this.openStatus.compareAndSet(false, true); - this.eventManager = new EventManager(this); + this.eventManager = new BasicEventManager(this); } protected void setPrimaryLocale(Locale locale) { diff --git a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/base/AbstractRepositoryHandler.java b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/base/AbstractRepositoryHandler.java index 0e17aacd6..2ffeac281 100644 --- a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/base/AbstractRepositoryHandler.java +++ b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/base/AbstractRepositoryHandler.java @@ -22,7 +22,7 @@ import org.apache.archiva.configuration.model.AbstractRepositoryConfiguration; import org.apache.archiva.configuration.model.Configuration; import org.apache.archiva.configuration.provider.IndeterminateConfigurationException; import org.apache.archiva.event.Event; -import org.apache.archiva.event.EventManager; +import org.apache.archiva.event.BasicEventManager; import org.apache.archiva.event.EventType; import org.apache.archiva.repository.EditableRepository; import org.apache.archiva.repository.Repository; @@ -61,14 +61,14 @@ public abstract class AbstractRepositoryHandler<R extends Repository, C extends private CombinedValidator<R> combinedValidator; private final Class<R> repositoryClazz; private final Class<C> configurationClazz; - private final EventManager eventManager; + private final BasicEventManager eventManager; private final Map<String, R> repositoryMap = new HashMap<>( ); private final ConfigurationHandler configurationHandler; public AbstractRepositoryHandler(Class<R> repositoryClazz, Class<C> configurationClazz, ConfigurationHandler configurationHandler) { this.repositoryClazz = repositoryClazz; this.configurationClazz = configurationClazz; - this.eventManager = new EventManager( this ); + this.eventManager = new BasicEventManager( this ); this.configurationHandler = configurationHandler; } @@ -142,13 +142,13 @@ public abstract class AbstractRepositoryHandler<R extends Repository, C extends } @Override - public Class<R> getVariant( ) + public Class<R> getFlavour( ) { return this.repositoryClazz; } @Override - public Class<C> getConfigurationVariant( ) + public Class<C> getConfigurationFlavour( ) { return this.configurationClazz; } diff --git a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/base/ArchivaRepositoryRegistry.java b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/base/ArchivaRepositoryRegistry.java index 1d0c32207..c3a3c0b05 100644 --- a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/base/ArchivaRepositoryRegistry.java +++ b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/base/ArchivaRepositoryRegistry.java @@ -31,8 +31,10 @@ import org.apache.archiva.configuration.model.RemoteRepositoryConfiguration; import org.apache.archiva.configuration.model.RepositoryGroupConfiguration; import org.apache.archiva.event.Event; import org.apache.archiva.event.EventHandler; -import org.apache.archiva.event.EventManager; +import org.apache.archiva.event.BasicEventManager; +import org.apache.archiva.event.EventSource; import org.apache.archiva.event.EventType; +import org.apache.archiva.event.central.CentralEventManager; import org.apache.archiva.indexer.ArchivaIndexManager; import org.apache.archiva.indexer.ArchivaIndexingContext; import org.apache.archiva.indexer.IndexCreationFailedException; @@ -65,6 +67,7 @@ import org.springframework.stereotype.Service; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import javax.inject.Inject; +import javax.inject.Named; import java.util.Collection; import java.util.Collections; import java.util.HashMap; @@ -111,9 +114,13 @@ public class ArchivaRepositoryRegistry implements ConfigurationListener, EventHa @Inject List<RepositoryValidator<? extends Repository>> repositoryValidatorList; + @Inject + @Named("eventManager#archiva") + CentralEventManager centralEventManager; + private boolean ignoreIndexing = false; - private final EventManager eventManager; + private final BasicEventManager eventManager; private final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock( ); @@ -133,7 +140,7 @@ public class ArchivaRepositoryRegistry implements ConfigurationListener, EventHa public ArchivaRepositoryRegistry( ConfigurationHandler configurationHandler, List<RepositoryValidator<? extends Repository>> validatorList ) { - this.eventManager = new EventManager( this ); + this.eventManager = new BasicEventManager( this ); this.configurationHandler = configurationHandler; this.validators = initValidatorList( validatorList ); } @@ -172,6 +179,7 @@ public class ArchivaRepositoryRegistry implements ConfigurationListener, EventHa provider.addRepositoryEventHandler( this ); } this.configurationHandler.addListener( this ); + registerEventHandler( EventType.ROOT, centralEventManager ); } finally { @@ -1162,15 +1170,15 @@ public class ArchivaRepositoryRegistry implements ConfigurationListener, EventHa @Override public void registerHandler( RepositoryHandler<?, ?> handler ) { - if ( handler.getVariant( ).isAssignableFrom( RepositoryGroup.class ) ) + if ( handler.getFlavour( ).isAssignableFrom( RepositoryGroup.class ) ) { registerGroupHandler( (RepositoryHandler<RepositoryGroup, RepositoryGroupConfiguration>) handler ); } - else if ( handler.getVariant( ).isAssignableFrom( ManagedRepository.class ) ) + else if ( handler.getFlavour( ).isAssignableFrom( ManagedRepository.class ) ) { registerManagedRepositoryHandler( (RepositoryHandler<ManagedRepository, ManagedRepositoryConfiguration>) handler ); } - else if ( handler.getVariant().isAssignableFrom( RemoteRepository.class )) { + else if ( handler.getFlavour().isAssignableFrom( RemoteRepository.class )) { registerRemoteRepositoryHandler( (RepositoryHandler<RemoteRepository, RemoteRepositoryConfiguration>) handler ); } } diff --git a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/base/managed/ManagedRepositoryHandler.java b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/base/managed/ManagedRepositoryHandler.java index f7cf8a46f..b46c12a79 100644 --- a/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/base/managed/ManagedRepositoryHandler.java +++ b/archiva-modules/archiva-base/archiva-repository-layer/src/main/java/org/apache/archiva/repository/base/managed/ManagedRepositoryHandler.java @@ -47,6 +47,8 @@ import org.springframework.stereotype.Service; import javax.annotation.PostConstruct; import javax.inject.Named; import java.io.IOException; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; diff --git a/archiva-modules/archiva-base/archiva-repository-layer/src/test/java/org/apache/archiva/repository/base/group/RepositoryGroupHandlerTest.java b/archiva-modules/archiva-base/archiva-repository-layer/src/test/java/org/apache/archiva/repository/base/group/RepositoryGroupHandlerTest.java index fb607e427..be4933beb 100644 --- a/archiva-modules/archiva-base/archiva-repository-layer/src/test/java/org/apache/archiva/repository/base/group/RepositoryGroupHandlerTest.java +++ b/archiva-modules/archiva-base/archiva-repository-layer/src/test/java/org/apache/archiva/repository/base/group/RepositoryGroupHandlerTest.java @@ -148,7 +148,7 @@ class RepositoryGroupHandlerTest private RepositoryGroupHandler createHandler( ) { - Mockito.when( managedRepositoryHandler.getVariant( ) ).thenReturn( ManagedRepository.class ); + Mockito.when( managedRepositoryHandler.getFlavour( ) ).thenReturn( ManagedRepository.class ); final ManagedRepository internalRepo; try { @@ -161,7 +161,7 @@ class RepositoryGroupHandlerTest Mockito.when( managedRepositoryHandler.get( ArgumentMatchers.eq("internal") ) ).thenReturn( internalRepo ); repositoryRegistry.registerHandler( managedRepositoryHandler ); - Mockito.when( remoteRepositoryHandler.getVariant( ) ).thenReturn( RemoteRepository.class ); + Mockito.when( remoteRepositoryHandler.getFlavour( ) ).thenReturn( RemoteRepository.class ); final RemoteRepository centralRepo; try { diff --git a/archiva-modules/archiva-base/pom.xml b/archiva-modules/archiva-base/pom.xml index 55b0f87f1..91c0278ca 100644 --- a/archiva-modules/archiva-base/pom.xml +++ b/archiva-modules/archiva-base/pom.xml @@ -33,6 +33,7 @@ <site.staging.base>${project.parent.basedir}</site.staging.base> </properties> <modules> + <module>archiva-event-api</module> <module>archiva-test-utils</module> <module>archiva-common</module> <module>archiva-mock</module> @@ -53,5 +54,6 @@ <module>archiva-security-common</module> <module>archiva-storage-api</module> <module>archiva-storage-fs</module> + <module>archiva-event-central</module> </modules> </project> diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/pom.xml b/archiva-modules/archiva-maven/archiva-maven-repository/pom.xml index 7c042b5c7..140652477 100644 --- a/archiva-modules/archiva-maven/archiva-maven-repository/pom.xml +++ b/archiva-modules/archiva-maven/archiva-maven-repository/pom.xml @@ -33,6 +33,10 @@ <dependencies> <dependency> + <groupId>org.apache.archiva.event</groupId> + <artifactId>archiva-event-api</artifactId> + </dependency> + <dependency> <groupId>org.apache.archiva</groupId> <artifactId>archiva-repository-api</artifactId> </dependency> diff --git a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/MavenRepositoryProvider.java b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/MavenRepositoryProvider.java index 8319e2704..bb740960c 100644 --- a/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/MavenRepositoryProvider.java +++ b/archiva-modules/archiva-maven/archiva-maven-repository/src/main/java/org/apache/archiva/maven/repository/MavenRepositoryProvider.java @@ -118,6 +118,16 @@ public class MavenRepositoryProvider implements RepositoryProvider { return repo; } + private Path getBaseDir(String location) { + String lPathStr = location == null ? "" : location; + Path lPath = Paths.get( lPathStr ); + if (lPath.isAbsolute()) { + return lPath.getParent( ); + } else { + return archivaConfiguration.getRepositoryBaseDir( ).resolve( lPath ); + } + } + @Override public MavenRemoteRepository createRemoteInstance(String id, String name) { return createRemoteInstance(id, name, archivaConfiguration.getRemoteRepositoryBaseDir()); @@ -194,7 +204,7 @@ public class MavenRepositoryProvider implements RepositoryProvider { @Override public ManagedRepository createManagedInstance(ManagedRepositoryConfiguration cfg) throws RepositoryException { - MavenManagedRepository repo = createManagedInstance(cfg.getId(), cfg.getName(), Paths.get(cfg.getLocation()).getParent()); + MavenManagedRepository repo = createManagedInstance( cfg.getId( ), cfg.getName( ), getBaseDir( cfg.getLocation( ) ) ); updateManagedInstance(repo, cfg); return repo; } diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/v2/model/MavenManagedRepository.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/v2/model/MavenManagedRepository.java index 01ec552c0..d3ce96819 100644 --- a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/v2/model/MavenManagedRepository.java +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/v2/model/MavenManagedRepository.java @@ -73,37 +73,6 @@ public class MavenManagedRepository extends Repository super.setType( RepositoryType.MAVEN.name( ) ); } - protected static void update(MavenManagedRepository repo, ManagedRepository beanRepo) { - repo.setDescription( beanRepo.getDescription() ); - repo.setId( beanRepo.getId() ); - repo.setIndex( true ); - repo.setLayout( beanRepo.getLayout() ); - repo.setBlocksRedeployments( beanRepo.blocksRedeployments() ); - repo.setReleaseSchemes( beanRepo.getActiveReleaseSchemes().stream().map( Objects::toString).collect( Collectors.toList()) ); - repo.setLocation( beanRepo.getLocation().toString() ); - repo.setName( beanRepo.getName()); - repo.setScanned( beanRepo.isScanned() ); - repo.setSchedulingDefinition( beanRepo.getSchedulingDefinition() ); - ArtifactCleanupFeature artifactCleanupFeature = beanRepo.getFeature( ArtifactCleanupFeature.class ); - repo.setDeleteSnapshotsOfRelease( artifactCleanupFeature.isDeleteReleasedSnapshots()); - repo.setRetentionCount( artifactCleanupFeature.getRetentionCount()); - repo.setRetentionPeriod( artifactCleanupFeature.getRetentionPeriod() ); - IndexCreationFeature icf = beanRepo.getFeature( IndexCreationFeature.class ); - repo.setIndex( icf.hasIndex( ) ); - repo.setIndexPath( icf.getIndexPath( ).getPath( ) ); - repo.setPackedIndexPath( icf.getPackedIndexPath( ).getPath( ) ); - repo.setSkipPackedIndexCreation( icf.isSkipPackedIndexCreation() ); - StagingRepositoryFeature srf = beanRepo.getFeature( StagingRepositoryFeature.class ); - repo.setHasStagingRepository( srf.isStageRepoNeeded( ) ); - repo.setStagingRepository( srf.getStagingRepository()!=null?srf.getStagingRepository().getId():"" ); - } - - public static MavenManagedRepository of( ManagedRepository beanRepo ) { - MavenManagedRepository repo = new MavenManagedRepository( ); - update( repo, beanRepo ); - return repo; - } - @Schema(name="blocks_redeployments",description = "True, if redeployments to this repository are not allowed") public boolean isBlocksRedeployments( ) { diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/v2/model/MavenManagedRepositoryUpdate.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/v2/model/MavenManagedRepositoryUpdate.java index 5536ae9b0..1fcb1a0e3 100644 --- a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/v2/model/MavenManagedRepositoryUpdate.java +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/v2/model/MavenManagedRepositoryUpdate.java @@ -17,6 +17,7 @@ package org.apache.archiva.rest.api.v2.model; * under the License. */ +import io.swagger.v3.oas.annotations.media.Schema; import org.apache.archiva.repository.ManagedRepository; import java.io.Serializable; @@ -24,17 +25,13 @@ import java.io.Serializable; /** * @author Martin Stockhammer <martin_s@apache.org> */ +@Schema(name="MavenManagedRepositoryUpdate",description = "Data object for updating maven managed repositories") public class MavenManagedRepositoryUpdate extends MavenManagedRepository implements Serializable { private static final long serialVersionUID = -9181643343284109862L; private boolean resetStats = false; - public static MavenManagedRepositoryUpdate of( ManagedRepository repository ) { - MavenManagedRepositoryUpdate repo = new MavenManagedRepositoryUpdate( ); - update( repo, repository ); - return repo; - } - + @Schema(name="reset_stats",description = "True, if statistics should be reset after update") public boolean isResetStats( ) { return resetStats; diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/v2/model/map/MavenRepositoryMapper.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/v2/model/map/MavenRepositoryMapper.java index 1e4ed68a0..75be52388 100644 --- a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/v2/model/map/MavenRepositoryMapper.java +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/v2/model/map/MavenRepositoryMapper.java @@ -64,14 +64,22 @@ public class MavenRepositoryMapper extends RestServiceMapper<MavenManagedReposit if (source.getLayout()!=null) target.setLayout( source.getLayout() ); if (source.getLocation()!=null) - target.setLocation( source.getLocation() ); + { + target.setLocation( source.getLocation( ) ); + } else { + if (target.getLocation()==null) { + target.setLocation( "" ); + } + } + if (source.getPackedIndexPath()!=null) target.setPackedIndexDir( source.getPackedIndexPath() ); if (source.getSchedulingDefinition()!=null) target.setRefreshCronExpression( source.getSchedulingDefinition() ); target.setReleases( source.getReleaseSchemes( ).contains( ReleaseScheme.RELEASE.name() ) ); target.setRetentionCount( source.getRetentionCount() ); - target.setRetentionPeriod( source.getRetentionPeriod().getDays() ); + if (source.getRetentionPeriod()!=null) + target.setRetentionPeriod( source.getRetentionPeriod().getDays() ); target.setScanned( source.isScanned() ); target.setSkipPackedIndexCreation( source.isSkipPackedIndexCreation() ); target.setSnapshots( source.getReleaseSchemes( ).contains( ReleaseScheme.SNAPSHOT.name() ) ); diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/v2/svc/ErrorKeys.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/v2/svc/ErrorKeys.java index cc0a836a2..57e4d401f 100644 --- a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/v2/svc/ErrorKeys.java +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/main/java/org/apache/archiva/rest/api/v2/svc/ErrorKeys.java @@ -122,4 +122,10 @@ public interface ErrorKeys * When the operation needs authentication, but not authenticated user was found in the request context. */ String NOT_AUTHENTICATED = PREFIX + "user.not_authenticated"; + + /** + * Repository add action failed + */ + String REPOSITORY_ADD_FAILED = PREFIX + "add.failed"; + } diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/test/java/org/apache/archiva/rest/api/v2/model/map/MavenRepositoryMapperTest.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/test/java/org/apache/archiva/rest/api/v2/model/map/MavenRepositoryMapperTest.java index 0fd77703c..3f0e04e12 100644 --- a/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/test/java/org/apache/archiva/rest/api/v2/model/map/MavenRepositoryMapperTest.java +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-api/src/test/java/org/apache/archiva/rest/api/v2/model/map/MavenRepositoryMapperTest.java @@ -141,6 +141,51 @@ class MavenRepositoryMapperTest } @Test + void updateWithNullValues( ) + { + MavenRepositoryMapper mapper = new MavenRepositoryMapper( ); + MavenManagedRepository repo = new MavenManagedRepository( ); + ManagedRepositoryConfiguration result = new ManagedRepositoryConfiguration( ); + repo.setId( "repo01" ); + repo.setName( "Repo 01" ); + repo.setDescription( "This is repo 01" ); + repo.setLocation( null ); + repo.setHasStagingRepository( true ); + repo.setSchedulingDefinition( "0,1,2 * * * *" ); + repo.setPackedIndexPath( null ); + repo.setIndexPath( null ); + repo.setIndex( true ); + repo.setDeleteSnapshotsOfRelease( false ); + repo.setBlocksRedeployments( false ); + repo.setReleaseSchemes( Arrays.asList( ReleaseScheme.RELEASE.name(), ReleaseScheme.SNAPSHOT.name() ) ); + repo.setCharacteristic( Repository.CHARACTERISTIC_MANAGED ); + repo.setScanned( true ); + repo.setRetentionPeriod( null ); + repo.setRetentionCount( 15 ); + repo.setSkipPackedIndexCreation( false ); + repo.setStagingRepository( null ); + mapper.update( repo, result ); + + assertNotNull( result ); + assertEquals( "repo01", result.getId( ) ); + assertEquals( "Repo 01", result.getName( ) ); + assertEquals( "This is repo 01", result.getDescription( ) ); + assertNotNull( result.getLocation( ) ); + assertTrue( result.isStageRepoNeeded( ) ); + assertEquals( "0,1,2 * * * *", result.getRefreshCronExpression( ) ); + assertEquals( "", result.getIndexDir( ) ); + assertEquals( "", result.getPackedIndexDir( ) ); + assertFalse( result.isDeleteReleasedSnapshots( ) ); + assertFalse( result.isBlockRedeployments( ) ); + assertTrue( result.isSnapshots( ) ); + assertTrue( result.isReleases( ) ); + assertTrue( result.isScanned( ) ); + assertEquals( 100, result.getRetentionPeriod( ) ); + assertEquals( 15, result.getRetentionCount( ) ); + assertFalse( result.isSkipPackedIndexCreation( ) ); + } + + @Test void reverseMap( ) throws IOException, URISyntaxException, UnsupportedURIException { MavenRepositoryMapper mapper = new MavenRepositoryMapper( ); diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/pom.xml b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/pom.xml index 7dd8dad50..519fb1e5b 100644 --- a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/pom.xml +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/pom.xml @@ -49,6 +49,10 @@ <artifactId>archiva-storage-api</artifactId> </dependency> <dependency> + <groupId>org.apache.archiva.event</groupId> + <artifactId>archiva-event-api</artifactId> + </dependency> + <dependency> <groupId>org.apache.archiva</groupId> <artifactId>archiva-repository-admin-api</artifactId> </dependency> diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/v2/svc/AbstractService.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/v2/svc/AbstractService.java new file mode 100644 index 000000000..09e367e8a --- /dev/null +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/v2/svc/AbstractService.java @@ -0,0 +1,51 @@ +package org.apache.archiva.rest.v2.svc; +/* + * 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.admin.model.AuditInformation; +import org.apache.archiva.redback.rest.services.RedbackAuthenticationThreadLocal; +import org.apache.archiva.redback.rest.services.RedbackRequestInformation; +import org.apache.archiva.redback.users.User; + +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.core.Context; + +/** + * @author Martin Schreier <martin_s@apache.org> + */ +public class AbstractService +{ + @Context + private HttpServletRequest httpServletRequest; + + protected AuditInformation getAuditInformation( ) + { + RedbackRequestInformation redbackRequestInformation = RedbackAuthenticationThreadLocal.get( ); + User user; + String remoteAddr; + if (redbackRequestInformation==null) { + user = null; + remoteAddr = httpServletRequest.getRemoteAddr( ); + } else + { + user = redbackRequestInformation.getUser( ); + remoteAddr = redbackRequestInformation.getRemoteAddr( ); + } + return new AuditInformation( user, remoteAddr ); + } +} diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/v2/svc/maven/DefaultMavenManagedRepositoryService.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/v2/svc/maven/DefaultMavenManagedRepositoryService.java index 5bec54dff..406acff59 100644 --- a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/v2/svc/maven/DefaultMavenManagedRepositoryService.java +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/main/java/org/apache/archiva/rest/v2/svc/maven/DefaultMavenManagedRepositoryService.java @@ -20,13 +20,12 @@ package org.apache.archiva.rest.v2.svc.maven; import org.apache.archiva.admin.model.AuditInformation; import org.apache.archiva.admin.model.RepositoryAdminException; import org.apache.archiva.admin.model.managed.ManagedRepositoryAdmin; +import org.apache.archiva.common.MultiModelMapper; import org.apache.archiva.components.rest.model.PagedResult; import org.apache.archiva.components.rest.util.QueryHelper; import org.apache.archiva.configuration.model.ManagedRepositoryConfiguration; import org.apache.archiva.redback.authentication.AuthenticationResult; import org.apache.archiva.redback.authorization.AuthorizationException; -import org.apache.archiva.redback.rest.services.RedbackAuthenticationThreadLocal; -import org.apache.archiva.redback.rest.services.RedbackRequestInformation; import org.apache.archiva.redback.system.DefaultSecuritySession; import org.apache.archiva.redback.system.SecuritySession; import org.apache.archiva.redback.system.SecuritySystem; @@ -36,6 +35,7 @@ import org.apache.archiva.redback.users.UserNotFoundException; import org.apache.archiva.repository.ManagedRepository; import org.apache.archiva.repository.ReleaseScheme; import org.apache.archiva.repository.Repository; +import org.apache.archiva.repository.RepositoryException; import org.apache.archiva.repository.RepositoryRegistry; import org.apache.archiva.repository.RepositoryType; import org.apache.archiva.repository.content.ContentItem; @@ -44,10 +44,12 @@ import org.apache.archiva.repository.storage.fs.FsStorageUtil; import org.apache.archiva.rest.api.v2.model.FileInfo; import org.apache.archiva.rest.api.v2.model.MavenManagedRepository; import org.apache.archiva.rest.api.v2.model.MavenManagedRepositoryUpdate; +import org.apache.archiva.rest.api.v2.model.map.ServiceMapperFactory; import org.apache.archiva.rest.api.v2.svc.ArchivaRestServiceException; import org.apache.archiva.rest.api.v2.svc.ErrorKeys; import org.apache.archiva.rest.api.v2.svc.ErrorMessage; import org.apache.archiva.rest.api.v2.svc.maven.MavenManagedRepositoryService; +import org.apache.archiva.rest.v2.svc.AbstractService; import org.apache.archiva.security.common.ArchivaRoleConstants; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; @@ -65,14 +67,14 @@ import java.util.List; import java.util.function.Predicate; import java.util.stream.Collectors; -import static org.apache.archiva.security.common.ArchivaRoleConstants.OPERATION_READ_REPOSITORY; import static org.apache.archiva.security.common.ArchivaRoleConstants.OPERATION_ADD_ARTIFACT; +import static org.apache.archiva.security.common.ArchivaRoleConstants.OPERATION_READ_REPOSITORY; /** * @author Martin Stockhammer <martin_s@apache.org> */ @Service("v2.managedMavenRepositoryService#rest") -public class DefaultMavenManagedRepositoryService implements MavenManagedRepositoryService +public class DefaultMavenManagedRepositoryService extends AbstractService implements MavenManagedRepositoryService { @Context HttpServletResponse httpServletResponse; @@ -80,6 +82,8 @@ public class DefaultMavenManagedRepositoryService implements MavenManagedReposit @Context UriInfo uriInfo; + + private static final Logger log = LoggerFactory.getLogger( DefaultMavenManagedRepositoryService.class ); private static final QueryHelper<ManagedRepository> QUERY_HELPER = new QueryHelper<>( new String[]{"id", "name"} ); static @@ -96,36 +100,20 @@ public class DefaultMavenManagedRepositoryService implements MavenManagedReposit private final ManagedRepositoryAdmin managedRepositoryAdmin; private final RepositoryRegistry repositoryRegistry; private final SecuritySystem securitySystem; + private final ServiceMapperFactory serviceMapperFactory; + private final MultiModelMapper<MavenManagedRepository, ManagedRepositoryConfiguration, ManagedRepository> mapper; + public DefaultMavenManagedRepositoryService( SecuritySystem securitySystem, RepositoryRegistry repositoryRegistry, - ManagedRepositoryAdmin managedRepositoryAdmin ) + ManagedRepositoryAdmin managedRepositoryAdmin, + ServiceMapperFactory serviceMapperFactory ) throws IllegalArgumentException { this.securitySystem = securitySystem; this.repositoryRegistry = repositoryRegistry; this.managedRepositoryAdmin = managedRepositoryAdmin; - } - - protected AuditInformation getAuditInformation( ) - { - RedbackRequestInformation redbackRequestInformation = RedbackAuthenticationThreadLocal.get( ); - User user; - String remoteAddr; - if (redbackRequestInformation==null) { - user = null; - remoteAddr = null; - } else - { - user = redbackRequestInformation.getUser( ); - remoteAddr = redbackRequestInformation.getRemoteAddr( ); - } - return new AuditInformation( user, remoteAddr ); - } - - public static ManagedRepositoryConfiguration toConfig(MavenManagedRepository repo) { - ManagedRepositoryConfiguration cfg = new ManagedRepositoryConfiguration( ); - return cfg; - + this.serviceMapperFactory = serviceMapperFactory; + this.mapper = serviceMapperFactory.getMapper( MavenManagedRepository.class, ManagedRepositoryConfiguration.class, ManagedRepository.class ); } @Override @@ -140,7 +128,7 @@ public class DefaultMavenManagedRepositoryService implements MavenManagedReposit final Comparator<ManagedRepository> comparator = QUERY_HELPER.getComparator( orderBy, order ); int totalCount = Math.toIntExact( repos.stream( ).filter( queryFilter ).count( ) ); return PagedResult.of( totalCount, offset, limit, repos.stream( ).filter( queryFilter ).sorted( comparator ) - .map( MavenManagedRepository::of ).skip( offset ).limit( limit ).collect( Collectors.toList( ) ) ); + .map( mapper::reverseMap ).skip( offset ).limit( limit ).collect( Collectors.toList( ) ) ); } catch (ArithmeticException e) { log.error( "Invalid number of repositories detected." ); @@ -158,7 +146,7 @@ public class DefaultMavenManagedRepositoryService implements MavenManagedReposit if (repo.getType()!=RepositoryType.MAVEN) { throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_WRONG_TYPE, repositoryId, repo.getType().name() ), 404 ); } - return MavenManagedRepository.of( repo ); + return mapper.reverseMap( repo ); } @Override @@ -220,13 +208,14 @@ public class DefaultMavenManagedRepositoryService implements MavenManagedReposit } try { - managedRepositoryAdmin.addManagedRepository( convert( managedRepository ), managedRepository.hasStagingRepository(), getAuditInformation() ); + repositoryRegistry.putRepository( mapper.map( managedRepository ) ); httpServletResponse.setStatus( 201 ); - return MavenManagedRepository.of( repositoryRegistry.getManagedRepository( repoId ) ); + return mapper.reverseMap( repositoryRegistry.getManagedRepository( repoId ) ); } - catch ( RepositoryAdminException e ) + catch ( RepositoryException e ) { - throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_ADMIN_ERROR, e.getMessage( ) ) ); + log.error( "Could not create repository: {}", e.getMessage( ), e ); + throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_ADD_FAILED, repoId ) ); } } @@ -241,7 +230,7 @@ public class DefaultMavenManagedRepositoryService implements MavenManagedReposit if (newRepo==null) { throw new ArchivaRestServiceException( ErrorMessage.of( ErrorKeys.REPOSITORY_UPDATE_FAILED, repositoryId ) ); } - return MavenManagedRepository.of( newRepo ); + return mapper.reverseMap( newRepo ); } catch ( RepositoryAdminException e ) { diff --git a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/test/java/org/apache/archiva/rest/v2/svc/maven/NativeMavenManagedRepositoryServiceTest.java b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/test/java/org/apache/archiva/rest/v2/svc/maven/NativeMavenManagedRepositoryServiceTest.java index 3dffabed1..d012d6175 100644 --- a/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/test/java/org/apache/archiva/rest/v2/svc/maven/NativeMavenManagedRepositoryServiceTest.java +++ b/archiva-modules/archiva-web/archiva-rest/archiva-rest-services/src/test/java/org/apache/archiva/rest/v2/svc/maven/NativeMavenManagedRepositoryServiceTest.java @@ -100,7 +100,6 @@ public class NativeMavenManagedRepositoryServiceTest extends AbstractNativeRestS } - @Disabled @Test @Order( 2 ) void testCreateRepository() { @@ -111,7 +110,7 @@ public class NativeMavenManagedRepositoryServiceTest extends AbstractNativeRestS assertNotNull( json ); assertEquals( "repo001", json.get( "id" ) ); assertEquals( "Repository 001", json.get( "name" ) ); - assertEquals( "maven", json.get( "type" ) ); + assertEquals( "MAVEN", json.get( "type" ) ); assertEquals( "This is repository 001", json.get( "description" ) ); } @@ -237,6 +237,16 @@ <dependency> + <groupId>org.apache.archiva.event</groupId> + <artifactId>archiva-event-api</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.apache.archiva.event</groupId> + <artifactId>archiva-event-central</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> <groupId>org.apache.archiva.maven</groupId> <artifactId>archiva-maven-common</artifactId> <version>${project.version}</version> |