merge remaining changes from archiva-database-decoupling branch
git-svn-id: https://svn.apache.org/repos/asf/archiva/branches/MRM-976@706263 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/archiva-modules/archiva-base/archiva-event/pom.xml b/archiva-modules/archiva-base/archiva-event/pom.xml
new file mode 100644
index 0000000..139cfc1
--- /dev/null
+++ b/archiva-modules/archiva-base/archiva-event/pom.xml
@@ -0,0 +1,34 @@
+<?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/maven-v4_0_0.xsd">
+ <parent>
+ <groupId>org.apache.archiva</groupId>
+ <artifactId>archiva-base</artifactId>
+ <version>1.2-SNAPSHOT</version>
+ </parent>
+
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>org.apache.archiva</groupId>
+ <artifactId>archiva-event</artifactId>
+ <packaging>jar</packaging>
+ <version>1.2-SNAPSHOT</version>
+ <name>Archiva Base :: Event</name>
+</project>
diff --git a/archiva-modules/archiva-base/archiva-event/src/main/java/org/apache/archiva/event/AsynchronousEventBus.java b/archiva-modules/archiva-base/archiva-event/src/main/java/org/apache/archiva/event/AsynchronousEventBus.java
new file mode 100644
index 0000000..2087085
--- /dev/null
+++ b/archiva-modules/archiva-base/archiva-event/src/main/java/org/apache/archiva/event/AsynchronousEventBus.java
@@ -0,0 +1,117 @@
+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.Collections;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.LinkedBlockingQueue;
+
+/**
+ * Simple Async Event Bus implementation
+ *
+ * @author jdumay
+ */
+public class AsynchronousEventBus implements EventBus
+{
+ private final Set<EventObserver> observers = Collections.synchronizedSet(new HashSet());
+
+ private final BlockingQueue<Event> events = new LinkedBlockingQueue<Event>();
+
+ private final Thread workerThread;
+
+ private final int threads;
+
+ public AsynchronousEventBus(int threads)
+ {
+ this.threads = threads;
+ workerThread = new Thread(new WorkerRunnable());
+ workerThread.start();
+ }
+
+ public void emit(EventEmitter emitter, EventMessage message)
+ {
+ events.offer(new Event(emitter, message));
+ }
+
+ public void subscribe(EventObserver observer)
+ {
+ observers.add(observer);
+ }
+
+ public void unsubscribe(EventObserver observer)
+ {
+ observers.remove(observer);
+ }
+
+ public Set<EventObserver> getObservers() {
+ return new HashSet<EventObserver>(observers);
+ }
+
+ class WorkerRunnable implements Runnable
+ {
+ private final ExecutorService service;
+
+ public WorkerRunnable()
+ {
+ service = Executors.newFixedThreadPool(threads);
+ }
+
+ public void run()
+ {
+ while (true)
+ {
+ dequeueAndExecute();
+ }
+ }
+
+ private void dequeueAndExecute()
+ {
+ try
+ {
+ final Event event = events.take();
+ for (final EventObserver observer : observers)
+ {
+ service.execute(new Runnable()
+ {
+ public void run()
+ {
+ try
+ {
+ observer.observe(event);
+ }
+ finally
+ {
+ //log me
+ }
+ }
+ });
+ }
+ }
+ catch (InterruptedException e)
+ {
+ //Do nothing
+ }
+ }
+ }
+}
diff --git a/archiva-modules/archiva-base/archiva-event/src/main/java/org/apache/archiva/event/Event.java b/archiva-modules/archiva-base/archiva-event/src/main/java/org/apache/archiva/event/Event.java
new file mode 100644
index 0000000..e41d19e
--- /dev/null
+++ b/archiva-modules/archiva-base/archiva-event/src/main/java/org/apache/archiva/event/Event.java
@@ -0,0 +1,55 @@
+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.
+ */
+
+/**
+ * Encaptulation of both the EventEmitter and the EventMessage
+ * to represent a single event
+ */
+public final class Event
+{
+ private final EventEmitter emitter;
+
+ private final EventMessage message;
+
+ public Event(EventEmitter emitter, EventMessage message)
+ {
+ this.emitter = emitter;
+ this.message = message;
+ }
+
+ /**
+ * Get the Emitter who emitted the Event
+ * @return emitter
+ */
+ public EventEmitter getEmitter()
+ {
+ return emitter;
+ }
+
+ /**
+ * Get the EventMessage
+ * @return message
+ */
+ public EventMessage getMessage()
+ {
+ return message;
+ }
+}
diff --git a/archiva-modules/archiva-base/archiva-event/src/main/java/org/apache/archiva/event/EventBus.java b/archiva-modules/archiva-base/archiva-event/src/main/java/org/apache/archiva/event/EventBus.java
new file mode 100644
index 0000000..6445cb9
--- /dev/null
+++ b/archiva-modules/archiva-base/archiva-event/src/main/java/org/apache/archiva/event/EventBus.java
@@ -0,0 +1,53 @@
+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.Set;
+
+/**
+ * Allows implementer to emit to, subscribe and unsubscribe EventObservers
+ */
+public interface EventBus
+{
+ /**
+ * Emit a event
+ * @param emitter
+ * @param message
+ */
+ void emit(EventEmitter emitter, EventMessage message);
+
+ /**
+ * Allows the subscriber to receive messages from this event bus
+ * @param observer
+ */
+ void subscribe(EventObserver observer);
+
+ /**
+ * Stops the observer from receiving any messages
+ * @param observer
+ */
+ void unsubscribe(EventObserver observer);
+
+ /**
+ * Get the set of registered EventObservers
+ * @return
+ */
+ Set<EventObserver> getObservers();
+}
diff --git a/archiva-modules/archiva-base/archiva-event/src/main/java/org/apache/archiva/event/EventEmitter.java b/archiva-modules/archiva-base/archiva-event/src/main/java/org/apache/archiva/event/EventEmitter.java
new file mode 100644
index 0000000..4cdab91
--- /dev/null
+++ b/archiva-modules/archiva-base/archiva-event/src/main/java/org/apache/archiva/event/EventEmitter.java
@@ -0,0 +1,24 @@
+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.
+ */
+
+public interface EventEmitter
+{
+}
diff --git a/archiva-modules/archiva-base/archiva-event/src/main/java/org/apache/archiva/event/EventMessage.java b/archiva-modules/archiva-base/archiva-event/src/main/java/org/apache/archiva/event/EventMessage.java
new file mode 100644
index 0000000..8f39dec
--- /dev/null
+++ b/archiva-modules/archiva-base/archiva-event/src/main/java/org/apache/archiva/event/EventMessage.java
@@ -0,0 +1,24 @@
+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.
+ */
+
+public interface EventMessage
+{
+}
diff --git a/archiva-modules/archiva-base/archiva-event/src/main/java/org/apache/archiva/event/EventObserver.java b/archiva-modules/archiva-base/archiva-event/src/main/java/org/apache/archiva/event/EventObserver.java
new file mode 100644
index 0000000..bb5f07d
--- /dev/null
+++ b/archiva-modules/archiva-base/archiva-event/src/main/java/org/apache/archiva/event/EventObserver.java
@@ -0,0 +1,25 @@
+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.
+ */
+
+public interface EventObserver
+{
+ void observe(Event event);
+}
diff --git a/archiva-modules/archiva-base/archiva-event/src/test/java/org/apache/archiva/event/AsynchronousEventBusTest.java b/archiva-modules/archiva-base/archiva-event/src/test/java/org/apache/archiva/event/AsynchronousEventBusTest.java
new file mode 100644
index 0000000..b688389
--- /dev/null
+++ b/archiva-modules/archiva-base/archiva-event/src/test/java/org/apache/archiva/event/AsynchronousEventBusTest.java
@@ -0,0 +1,70 @@
+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.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import junit.framework.TestCase;
+
+public class AsynchronousEventBusTest extends TestCase
+{
+ public void testSubscribeUnsubscribe() throws Exception
+ {
+ AsynchronousEventBus bus = new AsynchronousEventBus(1);
+ MockObserver observer = new MockObserver();
+
+ assertEquals(0, bus.getObservers().size());
+
+ bus.subscribe(observer);
+ assertTrue(bus.getObservers().contains(observer));
+
+ bus.unsubscribe(observer);
+ assertFalse(bus.getObservers().contains(bus));
+ }
+
+ public void testAllEventsAreObserved() throws Exception
+ {
+ AsynchronousEventBus bus = new AsynchronousEventBus(1);
+ MockObserver observer = new MockObserver();
+ bus.subscribe(observer);
+
+ for (int i = 0; i < 10; i++)
+ {
+ bus.emit(new EventEmitter() {}, new EventMessage() {});
+ }
+
+ while (observer.observedEvents.size() != 10)
+ {
+ }
+
+ assertEquals(10, observer.observedEvents.size());
+ }
+
+ class MockObserver implements EventObserver
+ {
+ final List<Event> observedEvents = Collections.synchronizedList(new ArrayList());
+
+ public void observe(Event event)
+ {
+ observedEvents.add(event);
+ }
+ }
+}
diff --git a/archiva-modules/archiva-base/archiva-event/src/test/java/org/apache/archiva/event/EventTest.java b/archiva-modules/archiva-base/archiva-event/src/test/java/org/apache/archiva/event/EventTest.java
new file mode 100644
index 0000000..5710f07
--- /dev/null
+++ b/archiva-modules/archiva-base/archiva-event/src/test/java/org/apache/archiva/event/EventTest.java
@@ -0,0 +1,35 @@
+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 junit.framework.TestCase;
+
+public class EventTest extends TestCase
+{
+ public void testEvent()
+ {
+ EventEmitter emitter = new EventEmitter() {};
+ EventMessage message = new EventMessage() {};
+ Event event = new Event(emitter, message);
+
+ assertEquals(emitter, event.getEmitter());
+ assertEquals(message, event.getMessage());
+ }
+}
diff --git a/archiva-modules/archiva-base/pom.xml b/archiva-modules/archiva-base/pom.xml
index f95c75f..c6b7de9 100644
--- a/archiva-modules/archiva-base/pom.xml
+++ b/archiva-modules/archiva-base/pom.xml
@@ -42,5 +42,6 @@
<module>archiva-transaction</module>
<module>archiva-artifact-converter</module>
<module>archiva-converter</module>
+ <module>archiva-event</module>
</modules>
</project>
diff --git a/branch-working-notes.txt b/branch-working-notes.txt
new file mode 100644
index 0000000..495464e
--- /dev/null
+++ b/branch-working-notes.txt
@@ -0,0 +1,30 @@
+Stage 1: remove use of database and index from core consumers (move implementation into respective database and index modules)
+
+Done!
+
+Stage 2: separate model from JPOX annotated classes, centralising JPOX use in database
+
+* archiva-model to be reviewed, possibly split into a basic model with extensible parts. See metadata proposal
+* add consumer to generate Archiva metadata at same time as database model
+
+Stage 3: add a basic repository querying API for base artifact information and retrieval of metadata
+
+* RSS, browse
+* consider repository-api refactorings
+* at this point, should be able to have functional Archiva without a database
+* note that metadata need not be stored with the artifacts themselves, but will be by default
+
+Stage 4: incorporation of event API
+
+* used to centralise arrival, removal, etc of files/artifacts in the repository
+* errors should be events as well to avoid exceptions in the logs and instead meaningful handling/reporting
+* could also be used for configuration events
+* consider hooking the audit log to this as well
+
+Stage 5: isolate scanning code
+
+* Repository should operate without scanning code, it should push events if enabled
+* better assessment of its progress, performance
+* removal of database / repository scanning duality - all operations are driven by the event bus
+* move some database operations to a housekeeping scheduled task (same for index), make scheduled tasks a listable item based on available plugins
+