Repository: karaf Updated Branches: refs/heads/master b8c2617c2 -> 8aabfbd43
[KARAF-4370] EventAdmin commands Project: http://git-wip-us.apache.org/repos/asf/karaf/repo Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/8aabfbd4 Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/8aabfbd4 Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/8aabfbd4 Branch: refs/heads/master Commit: 8aabfbd4368327117eb20dc79e420aa050613c33 Parents: b8c2617 Author: Christian Schneider <[email protected]> Authored: Wed Mar 16 18:35:37 2016 +0100 Committer: Christian Schneider <[email protected]> Committed: Wed Mar 16 18:35:37 2016 +0100 ---------------------------------------------------------------------- event/.gitignore | 1 + event/pom.xml | 90 ++++++++++++++++++++ .../apache/karaf/event/EventDisplayCommand.java | 57 +++++++++++++ .../org/apache/karaf/event/EventPrinter.java | 69 +++++++++++++++ .../apache/karaf/event/EventSendCommand.java | 64 ++++++++++++++ .../apache/karaf/event/EventTailCommand.java | 76 +++++++++++++++++ .../karaf/event/service/EventCollector.java | 69 +++++++++++++++ .../karaf/event/service/TopicPredicate.java | 40 +++++++++ .../karaf/event/EventDisplayCommandTest.java | 44 ++++++++++ .../apache/karaf/event/EventPrinterTest.java | 70 +++++++++++++++ .../karaf/event/EventSendCommandTest.java | 55 ++++++++++++ .../karaf/event/EventTailCommandTest.java | 70 +++++++++++++++ .../karaf/event/service/EventCollectorTest.java | 76 +++++++++++++++++ .../karaf/event/service/TopicPredicateTest.java | 57 +++++++++++++ pom.xml | 1 + 15 files changed, 839 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/karaf/blob/8aabfbd4/event/.gitignore ---------------------------------------------------------------------- diff --git a/event/.gitignore b/event/.gitignore new file mode 100644 index 0000000..b83d222 --- /dev/null +++ b/event/.gitignore @@ -0,0 +1 @@ +/target/ http://git-wip-us.apache.org/repos/asf/karaf/blob/8aabfbd4/event/pom.xml ---------------------------------------------------------------------- diff --git a/event/pom.xml b/event/pom.xml new file mode 100644 index 0000000..748e5e6 --- /dev/null +++ b/event/pom.xml @@ -0,0 +1,90 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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"> + + <!-- + + 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. + --> + + <modelVersion>4.0.0</modelVersion> + + <parent> + <artifactId>karaf</artifactId> + <groupId>org.apache.karaf</groupId> + <version>4.1.0-SNAPSHOT</version> + <relativePath>../../pom.xml</relativePath> + </parent> + + <artifactId>org.apache.karaf.event</artifactId> + <packaging>bundle</packaging> + <name>Apache Karaf :: OSGi Services :: Event</name> + <description>EventAdmin Commands</description> + + <build> + <plugins> + <plugin> + <groupId>org.apache.karaf.tooling</groupId> + <artifactId>karaf-services-maven-plugin</artifactId> + </plugin> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <configuration> + <instructions> + <_dsannotations>*</_dsannotations> + </instructions> + </configuration> + </plugin> + </plugins> + </build> + + <dependencies> + <dependency> + <groupId>org.osgi</groupId> + <artifactId>org.osgi.core</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.apache.felix</groupId> + <artifactId>org.apache.felix.eventadmin</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.osgi</groupId> + <artifactId>org.osgi.compendium</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.apache.karaf.shell</groupId> + <artifactId>org.apache.karaf.shell.core</artifactId> + <version>4.0.4</version> + <optional>true</optional> + </dependency> + <dependency> + <groupId>org.apache.karaf</groupId> + <artifactId>org.apache.karaf.util</artifactId> + <scope>provided</scope> + </dependency> + + <dependency> + <groupId>org.hamcrest</groupId> + <artifactId>hamcrest-all</artifactId> + <version>1.3</version> + <scope>test</scope> + </dependency> + </dependencies> + +</project> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/karaf/blob/8aabfbd4/event/src/main/java/org/apache/karaf/event/EventDisplayCommand.java ---------------------------------------------------------------------- diff --git a/event/src/main/java/org/apache/karaf/event/EventDisplayCommand.java b/event/src/main/java/org/apache/karaf/event/EventDisplayCommand.java new file mode 100644 index 0000000..37d8f3c --- /dev/null +++ b/event/src/main/java/org/apache/karaf/event/EventDisplayCommand.java @@ -0,0 +1,57 @@ +/* + * 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. + */ +package org.apache.karaf.event; + +import static org.apache.karaf.event.service.TopicPredicate.matchTopic; + +import org.apache.karaf.event.service.EventCollector; +import org.apache.karaf.shell.api.action.Action; +import org.apache.karaf.shell.api.action.Argument; +import org.apache.karaf.shell.api.action.Command; +import org.apache.karaf.shell.api.action.Option; +import org.apache.karaf.shell.api.action.lifecycle.Reference; +import org.apache.karaf.shell.api.action.lifecycle.Service; +import org.apache.karaf.shell.api.console.Session; +import org.osgi.framework.BundleContext; + +@Command(scope = "event", name = "display", description = "Shows events") +@Service +public class EventDisplayCommand implements Action { + + @Reference + Session session; + + @Reference + BundleContext context; + + @Reference + EventCollector collector; + + @Argument + String topicFilter = "*"; + + @Option(name = "-v") + boolean verbose = false; + + @Override + public Object execute() throws Exception { + EventPrinter printer = new EventPrinter(session.getConsole(), verbose); + collector.getEvents().filter(matchTopic(topicFilter)).forEach(printer); + return null; + } + +} http://git-wip-us.apache.org/repos/asf/karaf/blob/8aabfbd4/event/src/main/java/org/apache/karaf/event/EventPrinter.java ---------------------------------------------------------------------- diff --git a/event/src/main/java/org/apache/karaf/event/EventPrinter.java b/event/src/main/java/org/apache/karaf/event/EventPrinter.java new file mode 100644 index 0000000..314dc9d --- /dev/null +++ b/event/src/main/java/org/apache/karaf/event/EventPrinter.java @@ -0,0 +1,69 @@ +/* + * 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. + */ +package org.apache.karaf.event; + +import java.io.PrintStream; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.Date; +import java.util.function.Consumer; + +import org.osgi.service.event.Event; + +public class EventPrinter implements Consumer<Event>{ + private PrintStream out; + private boolean verbose; + + public EventPrinter(PrintStream out, boolean verbose) { + this.out = out; + this.verbose = verbose; + } + + + @Override + public void accept(Event event) { + out.println(getTimeStamp(event) + " - " + event.getTopic()); + if (verbose) { + for (String key : event.getPropertyNames()) { + if (!key.equals("event.topics") && !key.equals("timestamp")) { + out.println(key + ": " + getPrintValue(event, key)); + } + } + out.println(); + out.flush(); + } + } + + private String getTimeStamp(Event event) { + Long ts = (Long)event.getProperty("timestamp"); + if (ts == null) { + return "0000-00-00 00:00:00"; + } + DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + return df.format(new Date(ts)); + } + + private Object getPrintValue(Event event, String key) { + Object value = event.getProperty(key); + if (value.getClass().isArray()) { + return Arrays.toString((Object[])value); + } + return value.toString(); + } + +} http://git-wip-us.apache.org/repos/asf/karaf/blob/8aabfbd4/event/src/main/java/org/apache/karaf/event/EventSendCommand.java ---------------------------------------------------------------------- diff --git a/event/src/main/java/org/apache/karaf/event/EventSendCommand.java b/event/src/main/java/org/apache/karaf/event/EventSendCommand.java new file mode 100644 index 0000000..ba3ab1b --- /dev/null +++ b/event/src/main/java/org/apache/karaf/event/EventSendCommand.java @@ -0,0 +1,64 @@ +/* + * 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. + */ +package org.apache.karaf.event; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.karaf.shell.api.action.Action; +import org.apache.karaf.shell.api.action.Argument; +import org.apache.karaf.shell.api.action.Command; +import org.apache.karaf.shell.api.action.lifecycle.Reference; +import org.apache.karaf.shell.api.action.lifecycle.Service; +import org.apache.karaf.shell.api.console.Session; +import org.osgi.service.event.Event; +import org.osgi.service.event.EventAdmin; + +@Command(scope = "event", name = "send", description = "Send a simple event to a topic") +@Service +public class EventSendCommand implements Action { + @Reference + Session session; + + @Reference + EventAdmin eventAdmin; + + @Argument + String topic; + + @Argument(multiValued=true) + String propertiesSt; + + @Override + public Object execute() throws Exception { + eventAdmin.sendEvent(new Event(topic, parse(propertiesSt))); + return null; + } + + Map<String, String> parse(String propSt) { + Map<String, String> properties = new HashMap<>(); + for (String keyValue : propSt.split(",")) { + String[] splitted = keyValue.split("="); + if (splitted.length != 2) { + throw new IllegalArgumentException("Invalid entry " + keyValue); + } + properties.put(splitted[0], splitted[1]); + }; + return properties; + } + +} http://git-wip-us.apache.org/repos/asf/karaf/blob/8aabfbd4/event/src/main/java/org/apache/karaf/event/EventTailCommand.java ---------------------------------------------------------------------- diff --git a/event/src/main/java/org/apache/karaf/event/EventTailCommand.java b/event/src/main/java/org/apache/karaf/event/EventTailCommand.java new file mode 100644 index 0000000..7be8840 --- /dev/null +++ b/event/src/main/java/org/apache/karaf/event/EventTailCommand.java @@ -0,0 +1,76 @@ +/* + * 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. + */ +package org.apache.karaf.event; + +import static org.apache.karaf.event.service.TopicPredicate.matchTopic; + +import java.util.function.Consumer; +import java.util.function.Predicate; + +import org.apache.karaf.event.service.EventCollector; +import org.apache.karaf.shell.api.action.Action; +import org.apache.karaf.shell.api.action.Argument; +import org.apache.karaf.shell.api.action.Command; +import org.apache.karaf.shell.api.action.Option; +import org.apache.karaf.shell.api.action.lifecycle.Reference; +import org.apache.karaf.shell.api.action.lifecycle.Service; +import org.apache.karaf.shell.api.console.Session; +import org.osgi.framework.BundleContext; +import org.osgi.service.event.Event; + +@Command(scope = "event", name = "tail", description = "Shows events and listens for incoming events") +@Service +public class EventTailCommand implements Action { + + @Reference + Session session; + + @Reference + BundleContext context; + + @Reference + EventCollector collector; + + @Argument + String topicFilter = "*"; + + @Option(name = "-v") + boolean verbose = false; + + @Override + public Object execute() throws Exception { + EventPrinter printer = new EventPrinter(session.getConsole(), verbose); + Consumer<Event> filteredPrinter = executeIf(matchTopic(topicFilter), printer); + collector.addConsumer(filteredPrinter); + try { + waitTillInterrupted(); + } catch (InterruptedException e) { + collector.removeConsumer(filteredPrinter); + } + return null; + } + + private <T> Consumer<T> executeIf(Predicate<T> pred, Consumer<T> consumer) { + return t -> {if (pred.test(t)) consumer.accept(t);}; + } + + private void waitTillInterrupted() throws InterruptedException { + while (true) { + Thread.sleep(100); + } + } +} http://git-wip-us.apache.org/repos/asf/karaf/blob/8aabfbd4/event/src/main/java/org/apache/karaf/event/service/EventCollector.java ---------------------------------------------------------------------- diff --git a/event/src/main/java/org/apache/karaf/event/service/EventCollector.java b/event/src/main/java/org/apache/karaf/event/service/EventCollector.java new file mode 100644 index 0000000..0a42d6d --- /dev/null +++ b/event/src/main/java/org/apache/karaf/event/service/EventCollector.java @@ -0,0 +1,69 @@ +/* + * 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. + */ +package org.apache.karaf.event.service; + +import java.util.Deque; +import java.util.HashSet; +import java.util.Set; +import java.util.concurrent.ConcurrentLinkedDeque; +import java.util.function.Consumer; +import java.util.stream.Stream; + +import org.osgi.service.component.annotations.Component; +import org.osgi.service.event.Event; +import org.osgi.service.event.EventHandler; + +@Component( + service = {EventHandler.class, EventCollector.class}, + name = "org.apache.karaf.eventadmin.collector", + immediate = true, + property = "event.topics=*" + ) +public class EventCollector implements EventHandler { + private Deque<Event> events; + private int maxSize; + private Set<Consumer<Event>> consumers; + + public EventCollector() { + events = new ConcurrentLinkedDeque<>(); + maxSize = 100; + consumers = new HashSet<>(); + } + + @Override + public synchronized void handleEvent(Event event) { + events.addLast(event); + if (events.size() > maxSize) { + events.removeFirst(); + } + consumers.forEach(c -> c.accept(event)); + } + + public Stream<Event> getEvents() { + return events.stream(); + } + + public synchronized void addConsumer(Consumer<Event> eventConsumer) { + events.forEach(eventConsumer); + consumers.add(eventConsumer); + } + + public synchronized void removeConsumer(Consumer<Event> eventConsumer) { + consumers.remove(eventConsumer); + } + +} http://git-wip-us.apache.org/repos/asf/karaf/blob/8aabfbd4/event/src/main/java/org/apache/karaf/event/service/TopicPredicate.java ---------------------------------------------------------------------- diff --git a/event/src/main/java/org/apache/karaf/event/service/TopicPredicate.java b/event/src/main/java/org/apache/karaf/event/service/TopicPredicate.java new file mode 100644 index 0000000..974f6e6 --- /dev/null +++ b/event/src/main/java/org/apache/karaf/event/service/TopicPredicate.java @@ -0,0 +1,40 @@ +/* + * 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. + */ +package org.apache.karaf.event.service; + +import java.util.function.Predicate; +import java.util.regex.Pattern; + +import org.osgi.service.event.Event; + +public class TopicPredicate implements Predicate<Event> { + private Pattern pattern; + + private TopicPredicate(String topicFilter) { + pattern = Pattern.compile(topicFilter.replace("*", ".*")); + } + + @Override + public boolean test(Event event) { + return pattern.matcher(event.getTopic()).matches(); + } + + public static Predicate<Event> matchTopic(String topicFilter) { + return new TopicPredicate(topicFilter); + } + +} http://git-wip-us.apache.org/repos/asf/karaf/blob/8aabfbd4/event/src/test/java/org/apache/karaf/event/EventDisplayCommandTest.java ---------------------------------------------------------------------- diff --git a/event/src/test/java/org/apache/karaf/event/EventDisplayCommandTest.java b/event/src/test/java/org/apache/karaf/event/EventDisplayCommandTest.java new file mode 100644 index 0000000..0822f73 --- /dev/null +++ b/event/src/test/java/org/apache/karaf/event/EventDisplayCommandTest.java @@ -0,0 +1,44 @@ +/* + * 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. + */ +package org.apache.karaf.event; + +import static org.easymock.EasyMock.createControl; +import static org.easymock.EasyMock.expect; + +import java.util.HashMap; + +import org.apache.karaf.event.service.EventCollector; +import org.apache.karaf.shell.api.console.Session; +import org.easymock.IMocksControl; +import org.junit.Test; +import org.osgi.service.event.Event; + +public class EventDisplayCommandTest { + + @Test + public void testExecute() throws Exception { + IMocksControl c = createControl(); + EventDisplayCommand display = new EventDisplayCommand(); + display.session = c.createMock(Session.class); + expect(display.session.getConsole()).andReturn(System.out); + display.collector = new EventCollector(); + display.collector.handleEvent(new Event("myTopic", new HashMap<>())); + c.replay(); + display.execute(); + c.verify(); + } +} http://git-wip-us.apache.org/repos/asf/karaf/blob/8aabfbd4/event/src/test/java/org/apache/karaf/event/EventPrinterTest.java ---------------------------------------------------------------------- diff --git a/event/src/test/java/org/apache/karaf/event/EventPrinterTest.java b/event/src/test/java/org/apache/karaf/event/EventPrinterTest.java new file mode 100644 index 0000000..cee5b0f --- /dev/null +++ b/event/src/test/java/org/apache/karaf/event/EventPrinterTest.java @@ -0,0 +1,70 @@ +/* + * 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. + */ +package org.apache.karaf.event; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.junit.Assert.assertThat; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.io.UnsupportedEncodingException; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.HashMap; + +import org.junit.Test; +import org.osgi.service.event.Event; + +public class EventPrinterTest { + DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm"); + + @Test + public void testPrint() throws UnsupportedEncodingException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + PrintStream out = new PrintStream(baos); + new EventPrinter(out, false).accept(event()); + String result = baos.toString("utf-8"); + assertThat(result, equalTo("2016-01-01 12:00:00 - myTopic\n")); + } + + @Test + public void testPrintVerbose() throws UnsupportedEncodingException { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + PrintStream out = new PrintStream(baos); + new EventPrinter(out, true).accept(event()); + String result = baos.toString("utf-8"); + assertThat(result, equalTo("2016-01-01 12:00:00 - myTopic\n" + + "a: b\n" + + "c: [d, e]\n\n")); + } + + private Event event() { + HashMap<String, Object> props = new HashMap<>(); + props.put("a", "b"); + props.put("c", new String[]{"d", "e"}); + Date date; + try { + date = df.parse("2016-01-01 12:00:00"); + } catch (ParseException e) { + throw new RuntimeException(e); + } + props.put("timestamp", date.getTime()); + return new Event("myTopic", props); + } +} http://git-wip-us.apache.org/repos/asf/karaf/blob/8aabfbd4/event/src/test/java/org/apache/karaf/event/EventSendCommandTest.java ---------------------------------------------------------------------- diff --git a/event/src/test/java/org/apache/karaf/event/EventSendCommandTest.java b/event/src/test/java/org/apache/karaf/event/EventSendCommandTest.java new file mode 100644 index 0000000..fb87c4b --- /dev/null +++ b/event/src/test/java/org/apache/karaf/event/EventSendCommandTest.java @@ -0,0 +1,55 @@ +package org.apache.karaf.event; + +import static org.easymock.EasyMock.capture; +import static org.easymock.EasyMock.expectLastCall; +import static org.easymock.EasyMock.mock; +import static org.easymock.EasyMock.newCapture; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.verify; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.junit.Assert.assertThat; + +import java.util.HashMap; +import java.util.Map; + +import org.easymock.Capture; +import org.junit.Test; +import org.osgi.service.event.Event; +import org.osgi.service.event.EventAdmin; + +public class EventSendCommandTest { + @Test + public void testExecute() throws Exception { + EventSendCommand send = new EventSendCommand(); + send.eventAdmin = mock(EventAdmin.class); + Capture<Event> eventCapture = newCapture(); + send.eventAdmin.sendEvent(capture(eventCapture)); + expectLastCall(); + + replay(send.eventAdmin); + send.topic = "myTopic"; + send.propertiesSt = "a=b"; + send.execute(); + verify(send.eventAdmin); + + Event event = eventCapture.getValue(); + assertThat(event.getTopic(), equalTo("myTopic")); + assertThat(event.getProperty("a"), equalTo("b")); + } + + @Test + public void testParse() { + String propSt = "a=b,b=c"; + Map<String, String> expectedMap = new HashMap<>(); + expectedMap.put("a", "b"); + expectedMap.put("b", "c"); + Map<String, String> props = new EventSendCommand().parse(propSt); + assertThat(props.entrySet(), equalTo(expectedMap.entrySet())); + } + + @Test(expected=IllegalArgumentException.class) + public void testParseError() { + String propSt = "a=b,c="; + new EventSendCommand().parse(propSt); + } +} http://git-wip-us.apache.org/repos/asf/karaf/blob/8aabfbd4/event/src/test/java/org/apache/karaf/event/EventTailCommandTest.java ---------------------------------------------------------------------- diff --git a/event/src/test/java/org/apache/karaf/event/EventTailCommandTest.java b/event/src/test/java/org/apache/karaf/event/EventTailCommandTest.java new file mode 100644 index 0000000..b18f725 --- /dev/null +++ b/event/src/test/java/org/apache/karaf/event/EventTailCommandTest.java @@ -0,0 +1,70 @@ +/* + * 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. + */ +package org.apache.karaf.event; + +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.mock; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.verify; + +import java.io.PrintStream; +import java.util.HashMap; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +import org.apache.karaf.event.service.EventCollector; +import org.apache.karaf.shell.api.console.Session; +import org.junit.Test; +import org.osgi.service.event.Event; + +public class EventTailCommandTest { + + private Exception exception; + + @Test + public void testTail() throws Exception { + EventTailCommand tail = new EventTailCommand(); + tail.session = mock(Session.class); + tail.collector = new EventCollector(); + PrintStream out = System.out; + expect(tail.session.getConsole()).andReturn(out); + exception = null; + replay(tail.session); + + ExecutorService executor = Executors.newSingleThreadExecutor(); + executor.execute(() -> { + try { + tail.execute(); + } catch (Exception e) { + exception = e; + } + }); + tail.collector.handleEvent(event()); + Thread.sleep(200); + executor.shutdownNow(); + executor.awaitTermination(100, TimeUnit.SECONDS); + if (exception != null) { + throw exception; + } + verify(tail.session); + } + + private Event event() { + return new Event("myTopic", new HashMap<>()); + } +} http://git-wip-us.apache.org/repos/asf/karaf/blob/8aabfbd4/event/src/test/java/org/apache/karaf/event/service/EventCollectorTest.java ---------------------------------------------------------------------- diff --git a/event/src/test/java/org/apache/karaf/event/service/EventCollectorTest.java b/event/src/test/java/org/apache/karaf/event/service/EventCollectorTest.java new file mode 100644 index 0000000..535ee0d --- /dev/null +++ b/event/src/test/java/org/apache/karaf/event/service/EventCollectorTest.java @@ -0,0 +1,76 @@ +/* + * 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. + */ +package org.apache.karaf.event.service; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + +import java.util.HashMap; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Consumer; +import java.util.stream.IntStream; + +import org.junit.Test; +import org.osgi.service.event.Event; + +public class EventCollectorTest { + + @Test + public void testHandleEvent() throws Exception { + EventCollector collector = new EventCollector(); + assertThat(collector.getEvents().count(), equalTo(0l)); + collector.handleEvent(event("myTopic")); + assertThat(collector.getEvents().count(), equalTo(1l)); + assertThat(collector.getEvents().findFirst().get().getTopic(), equalTo("myTopic")); + + } + + @Test + public void testLimit() { + EventCollector collector = new EventCollector(); + collector.handleEvent(event("first")); + IntStream.rangeClosed(1, 99).forEach(c -> collector.handleEvent(event("myTopic"))); + assertThat(collector.getEvents().count(), equalTo(100l)); + collector.handleEvent(event("last")); + assertThat(collector.getEvents().count(), equalTo(100l)); + assertTrue(collector.getEvents().noneMatch(event -> event.getTopic().endsWith("first"))); + assertTrue(collector.getEvents().anyMatch(event -> event.getTopic().endsWith("last"))); + } + + @Test + public void testAddRemoveConsumer() { + final AtomicInteger count = new AtomicInteger(); + Consumer<Event> countingConsumer = event -> count.incrementAndGet(); + EventCollector collector = new EventCollector(); + collector.handleEvent(event("myTopic")); + collector.addConsumer(countingConsumer); + assertThat(count.get(), equalTo(1)); + + collector.handleEvent(event("another")); + assertThat(count.get(), equalTo(2)); + + collector.removeConsumer(countingConsumer); + collector.handleEvent(event("and/another")); + assertThat(count.get(), equalTo(2)); + } + + private Event event(String topic) { + return new Event(topic, new HashMap<>()); + } + +} http://git-wip-us.apache.org/repos/asf/karaf/blob/8aabfbd4/event/src/test/java/org/apache/karaf/event/service/TopicPredicateTest.java ---------------------------------------------------------------------- diff --git a/event/src/test/java/org/apache/karaf/event/service/TopicPredicateTest.java b/event/src/test/java/org/apache/karaf/event/service/TopicPredicateTest.java new file mode 100644 index 0000000..fca6f59 --- /dev/null +++ b/event/src/test/java/org/apache/karaf/event/service/TopicPredicateTest.java @@ -0,0 +1,57 @@ +/* + * 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. + */ +package org.apache.karaf.event.service; + +import static org.apache.karaf.event.service.TopicPredicate.matchTopic; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.util.HashMap; +import java.util.function.Predicate; + +import org.junit.Test; +import org.osgi.service.event.Event; + +public class TopicPredicateTest { + + @Test + public void testMatchAll() { + Predicate<Event> matcher = matchTopic("*"); + assertTrue(matcher.test(event("myTopic"))); + assertTrue(matcher.test(event("my/other"))); + } + + @Test + public void testMatchSpecific() { + Predicate<Event> matcher = matchTopic("myTopic"); + assertTrue(matcher.test(event("myTopic"))); + assertFalse(matcher.test(event("myTopic/test"))); + assertFalse(matcher.test(event("my/other"))); + } + + @Test + public void testMatchSubTopics() { + Predicate<Event> matcher = matchTopic("myTopic*"); + assertTrue(matcher.test(event("myTopic"))); + assertTrue(matcher.test(event("myTopic/test"))); + assertFalse(matcher.test(event("my/other"))); + } + + private Event event(String topic) { + return new Event(topic, new HashMap<String, String>()); + } +} http://git-wip-us.apache.org/repos/asf/karaf/blob/8aabfbd4/pom.xml ---------------------------------------------------------------------- diff --git a/pom.xml b/pom.xml index 31826b9..4bcf505 100644 --- a/pom.xml +++ b/pom.xml @@ -68,6 +68,7 @@ <module>services</module> <module>subsystem</module> <module>profile</module> + <module>event</module> <module>tooling</module> <module>assemblies</module> <module>demos</module>
