git-svn-id: https://svn.apache.org/repos/asf/archiva/branches/archiva-database-decoupling@694629 13f79535-47bb-0310-9956-ffa450edef68archiva-database-decoupling
@@ -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> |
@@ -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 | |||
} | |||
} | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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(); | |||
} |
@@ -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 | |||
{ | |||
} |
@@ -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 | |||
{ | |||
} |
@@ -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); | |||
} |
@@ -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); | |||
} | |||
} | |||
} |
@@ -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()); | |||
} | |||
} |
@@ -42,5 +42,6 @@ | |||
<module>archiva-transaction</module> | |||
<module>archiva-artifact-converter</module> | |||
<module>archiva-converter</module> | |||
<module>archiva-event</module> | |||
</modules> | |||
</project> |