├── .mvn └── wrapper │ ├── maven-wrapper.jar │ └── maven-wrapper.properties ├── command-bus-cdi ├── src │ ├── main │ │ ├── resources │ │ │ └── META-INF │ │ │ │ ├── services │ │ │ │ └── javax.enterprise.inject.spi.Extension │ │ │ │ └── beans.xml │ │ └── java │ │ │ └── com │ │ │ └── cloudogu │ │ │ └── cb │ │ │ └── cdi │ │ │ ├── Registry.java │ │ │ ├── CDICommandBus.java │ │ │ ├── CommandProvider.java │ │ │ └── CDIExtension.java │ └── test │ │ └── java │ │ └── com │ │ └── cloudogu │ │ └── cb │ │ ├── ByeCommand.java │ │ ├── HelloCommand.java │ │ ├── ByeCommandHandler.java │ │ ├── MessageCollector.java │ │ ├── HelloCommandHandler.java │ │ └── cdi │ │ ├── CommandBusFactory.java │ │ ├── CDICommandBusTest.java │ │ └── CDIITCase.java └── pom.xml ├── .gitignore ├── LICENSE ├── .editorconfig ├── command-bus-core ├── src │ ├── test │ │ ├── java │ │ │ └── com │ │ │ │ └── cloudogu │ │ │ │ └── cb │ │ │ │ ├── EchoCommandHandler.java │ │ │ │ ├── EchoCommand.java │ │ │ │ └── decorator │ │ │ │ ├── TimerTest.java │ │ │ │ ├── PrometheusMetricsCountingCommandBusTest.java │ │ │ │ ├── PrometheusMetricsTimingCommandBusTest.java │ │ │ │ ├── DurationFormatterTest.java │ │ │ │ ├── MicrometerCountingCommandBusTest.java │ │ │ │ ├── ValidatingCommandBusTest.java │ │ │ │ ├── MicrometerTimingCommandBusTest.java │ │ │ │ └── LoggingCommandBusTest.java │ │ └── resources │ │ │ └── logback-test.xml │ └── main │ │ └── java │ │ ├── com │ │ └── cloudogu │ │ │ └── cb │ │ │ ├── Command.java │ │ │ ├── CommandHandler.java │ │ │ └── CommandBus.java │ │ └── de │ │ └── triology │ │ └── cb │ │ └── decorator │ │ ├── Timer.java │ │ ├── LoggingCommandBus.java │ │ ├── ValidatingCommandBus.java │ │ ├── PrometheusMetricsCountingCommandBus.java │ │ ├── PrometheusMetricsTimingCommandBus.java │ │ ├── MicrometerCountingCommandBus.java │ │ ├── MicrometerTimingCommandBus.java │ │ └── DurationFormatter.java └── pom.xml ├── command-bus-spring ├── src │ ├── test │ │ └── java │ │ │ └── com │ │ │ └── cloudogu │ │ │ └── cb │ │ │ ├── ByeCommand.java │ │ │ ├── HelloCommand.java │ │ │ ├── MessageCollector.java │ │ │ ├── ByeCommandHandler.java │ │ │ ├── spring │ │ │ ├── CommandBusFactory.java │ │ │ ├── SpringCommandBusTest.java │ │ │ ├── RegistryTest.java │ │ │ └── SpringITCase.java │ │ │ └── HelloCommandHandler.java │ └── main │ │ └── java │ │ └── com │ │ └── cloudogu │ │ └── cb │ │ └── spring │ │ ├── CommandProvider.java │ │ ├── SpringCommandBus.java │ │ └── Registry.java └── pom.xml ├── Jenkinsfile ├── mvnw.cmd ├── mvnw ├── README.md └── pom.xml /.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudogu/command-bus/HEAD/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /command-bus-cdi/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension: -------------------------------------------------------------------------------- 1 | com.cloudogu.cb.cdi.CDIExtension -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Maven template 3 | target/ 4 | pom.xml.tag 5 | pom.xml.releaseBackup 6 | pom.xml.versionsBackup 7 | pom.xml.next 8 | release.properties 9 | dependency-reduced-pom.xml 10 | buildNumber.properties 11 | .mvn/timing.properties 12 | 13 | # Avoid ignoring Maven wrapper jar file (.jar files are usually ignored) 14 | !/.mvn/wrapper/maven-wrapper.jar 15 | 16 | ### JetBrains 17 | /TestDataLoader.iml 18 | *.iml 19 | /.idea/ 20 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Cloudogu GmbH 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | # 2 | # MIT License 3 | # 4 | # Copyright (c) 2017 Cloudogu GmbH 5 | # 6 | # Permission is hereby granted, free of charge, to any person obtaining a copy 7 | # of this software and associated documentation files (the "Software"), to deal 8 | # in the Software without restriction, including without limitation the rights 9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | # copies of the Software, and to permit persons to whom the Software is 11 | # furnished to do so, subject to the following conditions: 12 | # 13 | # The above copyright notice and this permission notice shall be included in all 14 | # copies or substantial portions of the Software. 15 | # 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | # SOFTWARE. 23 | # 24 | 25 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.2/apache-maven-3.5.2-bin.zip -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # 2 | # MIT License 3 | # 4 | # Copyright (c) 2017 Cloudogu GmbH 5 | # 6 | # Permission is hereby granted, free of charge, to any person obtaining a copy 7 | # of this software and associated documentation files (the "Software"), to deal 8 | # in the Software without restriction, including without limitation the rights 9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | # copies of the Software, and to permit persons to whom the Software is 11 | # furnished to do so, subject to the following conditions: 12 | # 13 | # The above copyright notice and this permission notice shall be included in all 14 | # copies or substantial portions of the Software. 15 | # 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | # SOFTWARE. 23 | # 24 | 25 | # top-most EditorConfig file 26 | root = true 27 | 28 | # Unix-style newlines with a newline ending every file 29 | [*] 30 | end_of_line = lf 31 | indent_style = space 32 | indent_size = 2 33 | -------------------------------------------------------------------------------- /command-bus-core/src/test/java/com/cloudogu/cb/EchoCommandHandler.java: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2017 Cloudogu GmbH 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package com.cloudogu.cb; 25 | 26 | 27 | public class EchoCommandHandler implements CommandHandler { 28 | 29 | @Override 30 | public String handle(EchoCommand command) { 31 | return command.getEcho(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /command-bus-core/src/main/java/com/cloudogu/cb/Command.java: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2017 Cloudogu GmbH 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package com.cloudogu.cb; 25 | 26 | /** 27 | * Marker interface for commands. 28 | * @param type of return value 29 | */ 30 | @SuppressWarnings({"unused", "squid:S2326" }) // Return value is used by CommandBus 31 | public interface Command { 32 | 33 | } 34 | -------------------------------------------------------------------------------- /command-bus-cdi/src/test/java/com/cloudogu/cb/ByeCommand.java: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2017 Cloudogu GmbH 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package com.cloudogu.cb; 25 | 26 | public class ByeCommand implements Command { 27 | 28 | private final String name; 29 | 30 | public ByeCommand(String name) { 31 | this.name = name; 32 | } 33 | 34 | public String getName() { 35 | return name; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /command-bus-spring/src/test/java/com/cloudogu/cb/ByeCommand.java: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2017 Cloudogu GmbH 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package com.cloudogu.cb; 25 | 26 | public class ByeCommand implements Command { 27 | 28 | private final String name; 29 | 30 | public ByeCommand(String name) { 31 | this.name = name; 32 | } 33 | 34 | public String getName() { 35 | return name; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /command-bus-cdi/src/test/java/com/cloudogu/cb/HelloCommand.java: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2017 Cloudogu GmbH 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package com.cloudogu.cb; 25 | 26 | public class HelloCommand implements Command { 27 | 28 | private final String name; 29 | 30 | public HelloCommand(String name) { 31 | this.name = name; 32 | } 33 | 34 | public String getName() { 35 | return name; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /command-bus-core/src/test/java/com/cloudogu/cb/EchoCommand.java: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2017 Cloudogu GmbH 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package com.cloudogu.cb; 25 | 26 | public class EchoCommand implements Command { 27 | 28 | private final String echo; 29 | 30 | public EchoCommand(String echo) { 31 | this.echo = echo; 32 | } 33 | 34 | public String getEcho() { 35 | return echo; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /command-bus-spring/src/test/java/com/cloudogu/cb/HelloCommand.java: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2017 Cloudogu GmbH 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package com.cloudogu.cb; 25 | 26 | public class HelloCommand implements Command { 27 | 28 | private final String name; 29 | 30 | public HelloCommand(String name) { 31 | this.name = name; 32 | } 33 | 34 | public String getName() { 35 | return name; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /command-bus-cdi/src/main/resources/META-INF/beans.xml: -------------------------------------------------------------------------------- 1 | 2 | 27 | 31 | -------------------------------------------------------------------------------- /command-bus-spring/src/test/java/com/cloudogu/cb/MessageCollector.java: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2017 Cloudogu GmbH 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package com.cloudogu.cb; 25 | 26 | import java.util.ArrayList; 27 | import java.util.List; 28 | 29 | public class MessageCollector { 30 | 31 | private List messages = new ArrayList<>(); 32 | 33 | void add(String message) { 34 | messages.add(message); 35 | } 36 | 37 | public List getMessages() { 38 | return messages; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /command-bus-cdi/src/test/java/com/cloudogu/cb/ByeCommandHandler.java: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2017 Cloudogu GmbH 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package com.cloudogu.cb; 25 | 26 | import javax.inject.Inject; 27 | 28 | public class ByeCommandHandler implements CommandHandler { 29 | 30 | @Inject 31 | private MessageCollector messageCollector; 32 | 33 | @Override 34 | public Void handle(ByeCommand command) { 35 | messageCollector.add("bye " + command.getName()); 36 | return null; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /command-bus-core/src/test/java/com/cloudogu/cb/decorator/TimerTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2017 Cloudogu GmbH 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package com.cloudogu.cb.decorator; 25 | 26 | import org.junit.Test; 27 | 28 | import static org.assertj.core.api.Assertions.assertThat; 29 | 30 | /** 31 | * Unit tests for {@link Timer}. 32 | */ 33 | public class TimerTest { 34 | 35 | @Test 36 | public void properToStringFormat() { 37 | assertThat(new Timer().toString()).matches("[0-9]+(\\.[0-9]+)?μs"); 38 | } 39 | 40 | } -------------------------------------------------------------------------------- /command-bus-core/src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 27 | 28 | 29 | 30 | 31 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /command-bus-cdi/src/test/java/com/cloudogu/cb/MessageCollector.java: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2017 Cloudogu GmbH 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package com.cloudogu.cb; 25 | 26 | import javax.inject.Singleton; 27 | import java.util.ArrayList; 28 | import java.util.List; 29 | 30 | @Singleton 31 | public class MessageCollector { 32 | 33 | private List messages = new ArrayList<>(); 34 | 35 | void add(String message) { 36 | messages.add(message); 37 | } 38 | 39 | public List getMessages() { 40 | return messages; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /command-bus-core/src/main/java/com/cloudogu/cb/CommandHandler.java: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2017 Cloudogu GmbH 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package com.cloudogu.cb; 25 | 26 | /** 27 | * A handler for a {@link Command}. 28 | * 29 | * @param type of return value 30 | * @param type of command 31 | */ 32 | public interface CommandHandler> { 33 | 34 | /** 35 | * Handles the command. 36 | * 37 | * @param command command to handle 38 | * @return an optional return value as specified in {@link Command} 39 | */ 40 | R handle(C command); 41 | 42 | } 43 | -------------------------------------------------------------------------------- /command-bus-core/src/main/java/com/cloudogu/cb/CommandBus.java: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2017 Cloudogu GmbH 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package com.cloudogu.cb; 25 | 26 | /** 27 | * The Command-Bus is able to execute commands, by passing the command object to its appropriate handler. 28 | */ 29 | public interface CommandBus { 30 | 31 | /** 32 | * Searches the handler and passes the command to it. 33 | * 34 | * @param command command object 35 | * @param type of return value 36 | * @param type of command 37 | */ 38 | > R execute(C command); 39 | 40 | } 41 | -------------------------------------------------------------------------------- /command-bus-cdi/src/test/java/com/cloudogu/cb/HelloCommandHandler.java: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2017 Cloudogu GmbH 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package com.cloudogu.cb; 25 | 26 | import javax.inject.Inject; 27 | 28 | public class HelloCommandHandler implements CommandHandler { 29 | 30 | @Inject 31 | private MessageCollector messageCollector; 32 | 33 | @Override 34 | public String handle(HelloCommand command) { 35 | String message = "hello " + command.getName(); 36 | if (messageCollector != null) { 37 | messageCollector.add(message); 38 | } 39 | return message; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /command-bus-spring/src/test/java/com/cloudogu/cb/ByeCommandHandler.java: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2017 Cloudogu GmbH 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package com.cloudogu.cb; 25 | 26 | import org.springframework.beans.factory.annotation.Autowired; 27 | 28 | public class ByeCommandHandler implements CommandHandler { 29 | 30 | private MessageCollector messageCollector; 31 | 32 | @Autowired 33 | public ByeCommandHandler(MessageCollector messageCollector) { 34 | this.messageCollector = messageCollector; 35 | } 36 | 37 | @Override 38 | public Void handle(ByeCommand command) { 39 | messageCollector.add("bye " + command.getName()); 40 | return null; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /command-bus-spring/src/test/java/com/cloudogu/cb/spring/CommandBusFactory.java: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2017 Cloudogu GmbH 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package com.cloudogu.cb.spring; 25 | 26 | import com.cloudogu.cb.CommandBus; 27 | import com.cloudogu.cb.decorator.LoggingCommandBus; 28 | import org.springframework.beans.factory.annotation.Autowired; 29 | import org.springframework.context.annotation.Bean; 30 | 31 | public class CommandBusFactory { 32 | 33 | private Registry registry; 34 | 35 | @Autowired 36 | public CommandBusFactory(Registry registry) { 37 | this.registry = registry; 38 | } 39 | 40 | @Bean 41 | public CommandBus create() { 42 | return new LoggingCommandBus( 43 | new SpringCommandBus(registry) 44 | ); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /command-bus-spring/src/test/java/com/cloudogu/cb/HelloCommandHandler.java: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2017 Cloudogu GmbH 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package com.cloudogu.cb; 25 | 26 | import org.springframework.beans.factory.annotation.Autowired; 27 | 28 | public class HelloCommandHandler implements CommandHandler { 29 | 30 | private MessageCollector messageCollector; 31 | 32 | @Autowired 33 | public HelloCommandHandler(MessageCollector messageCollector) { 34 | this.messageCollector = messageCollector; 35 | } 36 | 37 | @Override 38 | public String handle(HelloCommand command) { 39 | String message = "hello " + command.getName(); 40 | if (messageCollector != null) { 41 | messageCollector.add(message); 42 | } 43 | return message; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /command-bus-cdi/src/test/java/com/cloudogu/cb/cdi/CommandBusFactory.java: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2017 Cloudogu GmbH 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package com.cloudogu.cb.cdi; 25 | 26 | import com.cloudogu.cb.CommandBus; 27 | import com.cloudogu.cb.decorator.LoggingCommandBus; 28 | 29 | import javax.enterprise.inject.Any; 30 | import javax.enterprise.inject.Default; 31 | import javax.enterprise.inject.Produces; 32 | import javax.inject.Inject; 33 | 34 | public class CommandBusFactory { 35 | 36 | private Registry registry; 37 | 38 | @Inject 39 | public CommandBusFactory(Registry registry) { 40 | this.registry = registry; 41 | } 42 | 43 | @Any 44 | @Default 45 | @Produces 46 | public CommandBus create() { 47 | return new LoggingCommandBus( 48 | new CDICommandBus(registry) 49 | ); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /command-bus-spring/src/main/java/com/cloudogu/cb/spring/CommandProvider.java: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2017 Cloudogu GmbH 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package com.cloudogu.cb.spring; 25 | 26 | import com.cloudogu.cb.CommandHandler; 27 | import org.springframework.context.ApplicationContext; 28 | 29 | /** 30 | * CommandProvider creates a handler with enabled spring injection. 31 | * 32 | * @param type of handler 33 | */ 34 | @SuppressWarnings("unchecked") 35 | class CommandProvider> { 36 | 37 | private final ApplicationContext applicationContext; 38 | private final Class type; 39 | 40 | CommandProvider(ApplicationContext applicationContext, Class type) { 41 | this.applicationContext = applicationContext; 42 | this.type = type; 43 | } 44 | 45 | public H get() { 46 | return applicationContext.getBean(type); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /command-bus-cdi/src/main/java/com/cloudogu/cb/cdi/Registry.java: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2017 Cloudogu GmbH 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package com.cloudogu.cb.cdi; 25 | 26 | import com.cloudogu.cb.Command; 27 | import com.cloudogu.cb.CommandHandler; 28 | 29 | import javax.inject.Singleton; 30 | import java.util.HashMap; 31 | import java.util.Map; 32 | 33 | /** 34 | * Registry holds the mapping between a command and its handler. 35 | */ 36 | @Singleton 37 | public class Registry { 38 | 39 | private Map, CommandProvider> providerMap = new HashMap<>(); 40 | 41 | void register(Class commandClass, CommandProvider provider){ 42 | providerMap.put(commandClass, provider); 43 | } 44 | 45 | @SuppressWarnings("unchecked") 46 | > CommandHandler get(Class commandClass) { 47 | return providerMap.get(commandClass).get(); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /command-bus-core/src/main/java/de/triology/cb/decorator/Timer.java: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2017 Cloudogu GmbH 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package com.cloudogu.cb.decorator; 25 | 26 | import java.util.concurrent.TimeUnit; 27 | 28 | /** 29 | * Timer measures elapsed time in nanoseconds. The timer captures the time in nanoseconds during the creation. To print 30 | * the elapsed time use the toString method. 31 | */ 32 | class Timer { 33 | 34 | private long startedAt; 35 | 36 | /** 37 | * Creates a new timer and captures the start date. 38 | */ 39 | public Timer() { 40 | this.startedAt = System.nanoTime(); 41 | } 42 | 43 | /** 44 | * Returns the elapsed time in nanoseconds. 45 | * 46 | * @return elapsed time in nanoseconds 47 | */ 48 | public long elapsed() { 49 | return System.nanoTime() - startedAt; 50 | } 51 | 52 | @Override 53 | public String toString() { 54 | return DurationFormatter.format(elapsed(), TimeUnit.NANOSECONDS); 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /command-bus-spring/src/main/java/com/cloudogu/cb/spring/SpringCommandBus.java: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2017 Cloudogu GmbH 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package com.cloudogu.cb.spring; 25 | 26 | import com.cloudogu.cb.Command; 27 | import com.cloudogu.cb.CommandBus; 28 | import com.cloudogu.cb.CommandHandler; 29 | import org.springframework.beans.factory.annotation.Autowired; 30 | 31 | /** 32 | * Spring backed Command-Bus. 33 | */ 34 | public class SpringCommandBus implements CommandBus { 35 | 36 | private final Registry registry; 37 | 38 | /** 39 | * Creates a new instance with the given registry. 40 | * 41 | * @param registry registry 42 | */ 43 | @Autowired 44 | public SpringCommandBus(Registry registry) { 45 | this.registry = registry; 46 | } 47 | 48 | @Override 49 | public > R execute(C command) { 50 | CommandHandler commandHandler = (CommandHandler) registry.get(command.getClass()); 51 | return commandHandler.handle(command); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /command-bus-cdi/src/main/java/com/cloudogu/cb/cdi/CDICommandBus.java: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2017 Cloudogu GmbH 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package com.cloudogu.cb.cdi; 25 | 26 | import com.cloudogu.cb.Command; 27 | import com.cloudogu.cb.CommandBus; 28 | import com.cloudogu.cb.CommandHandler; 29 | 30 | import javax.enterprise.inject.Alternative; 31 | import javax.inject.Inject; 32 | 33 | /** 34 | * CDI backed Command-Bus. 35 | */ 36 | @Alternative 37 | @SuppressWarnings("unchecked") 38 | public class CDICommandBus implements CommandBus { 39 | 40 | private final Registry registry; 41 | 42 | /** 43 | * Creates a new instance with the given registry. 44 | * 45 | * @param registry registry 46 | */ 47 | @Inject 48 | public CDICommandBus(Registry registry) { 49 | this.registry = registry; 50 | } 51 | 52 | @Override 53 | public > R execute(C command) { 54 | CommandHandler commandHandler = (CommandHandler) registry.get(command.getClass()); 55 | return commandHandler.handle(command); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /command-bus-spring/src/test/java/com/cloudogu/cb/spring/SpringCommandBusTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2017 Cloudogu GmbH 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package com.cloudogu.cb.spring; 25 | 26 | import com.cloudogu.cb.CommandHandler; 27 | import com.cloudogu.cb.HelloCommand; 28 | import org.junit.Test; 29 | import org.junit.runner.RunWith; 30 | import org.mockito.InjectMocks; 31 | import org.mockito.Mock; 32 | import org.mockito.junit.MockitoJUnitRunner; 33 | 34 | import static org.mockito.Mockito.verify; 35 | import static org.mockito.Mockito.when; 36 | 37 | @RunWith(MockitoJUnitRunner.class) 38 | public class SpringCommandBusTest { 39 | 40 | @Mock 41 | private Registry registry; 42 | 43 | @Mock 44 | private CommandHandler handler; 45 | 46 | @InjectMocks 47 | private SpringCommandBus commandBus; 48 | 49 | @Test 50 | public void execute() { 51 | when(registry.get(HelloCommand.class)).thenReturn(handler); 52 | 53 | HelloCommand command = new HelloCommand("bob"); 54 | commandBus.execute(command); 55 | 56 | verify(handler).handle(command); 57 | } 58 | 59 | 60 | } -------------------------------------------------------------------------------- /command-bus-cdi/src/test/java/com/cloudogu/cb/cdi/CDICommandBusTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2017 Cloudogu GmbH 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package com.cloudogu.cb.cdi; 25 | 26 | import com.cloudogu.cb.CommandHandler; 27 | import com.cloudogu.cb.HelloCommand; 28 | import org.junit.Test; 29 | import org.junit.runner.RunWith; 30 | import org.mockito.InjectMocks; 31 | import org.mockito.Mock; 32 | import org.mockito.junit.MockitoJUnitRunner; 33 | 34 | import static org.mockito.Mockito.verify; 35 | import static org.mockito.Mockito.when; 36 | 37 | /** 38 | * Tests {@link CDICommandBus}. 39 | */ 40 | @RunWith(MockitoJUnitRunner.class) 41 | public class CDICommandBusTest { 42 | 43 | @Mock 44 | private Registry registry; 45 | 46 | @Mock 47 | private CommandHandler handler; 48 | 49 | @InjectMocks 50 | private CDICommandBus commandBus; 51 | 52 | @Test 53 | public void execute() { 54 | when(registry.get(HelloCommand.class)).thenReturn(handler); 55 | 56 | HelloCommand command = new HelloCommand("joe"); 57 | commandBus.execute(command); 58 | 59 | verify(handler).handle(command); 60 | } 61 | 62 | } -------------------------------------------------------------------------------- /command-bus-core/src/main/java/de/triology/cb/decorator/LoggingCommandBus.java: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2017 Cloudogu GmbH 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package com.cloudogu.cb.decorator; 25 | 26 | import com.cloudogu.cb.Command; 27 | import com.cloudogu.cb.CommandBus; 28 | import org.slf4j.Logger; 29 | import org.slf4j.LoggerFactory; 30 | 31 | /** 32 | * Command bus decorator which logs every execution of a command with its elapsed time. 33 | */ 34 | public class LoggingCommandBus implements CommandBus { 35 | 36 | static final Logger LOG = LoggerFactory.getLogger(LoggingCommandBus.class); 37 | 38 | private CommandBus decorated; 39 | 40 | /** 41 | * Creates a new command bus and delegates the execution to the given command. 42 | * 43 | * @param decorated command bus to decorate 44 | */ 45 | public LoggingCommandBus(CommandBus decorated) { 46 | this.decorated = decorated; 47 | } 48 | 49 | @Override 50 | public > R execute(C command) { 51 | LOG.info("start command {}", command.getClass().getSimpleName()); 52 | 53 | Timer timer = new Timer(); 54 | try { 55 | return decorated.execute(command); 56 | } finally { 57 | LOG.info("finished command {} in {}", command.getClass().getSimpleName(), timer); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /command-bus-cdi/src/main/java/com/cloudogu/cb/cdi/CommandProvider.java: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2017 Cloudogu GmbH 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package com.cloudogu.cb.cdi; 25 | 26 | import com.cloudogu.cb.CommandHandler; 27 | 28 | import javax.enterprise.context.spi.CreationalContext; 29 | import javax.enterprise.inject.spi.Bean; 30 | import javax.enterprise.inject.spi.BeanManager; 31 | import javax.inject.Provider; 32 | 33 | /** 34 | * CommandProvider creates a handler with enabled cdi injection. 35 | * 36 | * @param type of handler 37 | */ 38 | @SuppressWarnings("unchecked") 39 | public class CommandProvider> implements Provider { 40 | 41 | private final BeanManager beanManager; 42 | private final Class handlerClass; 43 | 44 | CommandProvider(BeanManager beanManager, Class> handlerClass) { 45 | this.beanManager = beanManager; 46 | this.handlerClass = handlerClass; 47 | } 48 | 49 | @Override 50 | public H get() { 51 | Bean handlerBean = (Bean) beanManager.getBeans(handlerClass).iterator().next(); 52 | CreationalContext context = beanManager.createCreationalContext(handlerBean); 53 | return (H) beanManager.getReference(handlerBean, handlerClass, context); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /command-bus-core/src/main/java/de/triology/cb/decorator/ValidatingCommandBus.java: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2017 Cloudogu GmbH 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package com.cloudogu.cb.decorator; 25 | 26 | import com.cloudogu.cb.Command; 27 | import com.cloudogu.cb.CommandBus; 28 | 29 | import javax.validation.ConstraintViolation; 30 | import javax.validation.ConstraintViolationException; 31 | import javax.validation.Validator; 32 | import java.util.Set; 33 | 34 | /** 35 | * Command bus decorator which validates the command before execution. 36 | */ 37 | public class ValidatingCommandBus implements CommandBus { 38 | 39 | private final CommandBus decorated; 40 | private final Validator validator; 41 | 42 | /** 43 | * Creates a new ValidatingCommandBus 44 | * 45 | * @param decorated command bus to decorate 46 | * @param validator validator 47 | */ 48 | public ValidatingCommandBus(CommandBus decorated, Validator validator) { 49 | this.decorated = decorated; 50 | this.validator = validator; 51 | } 52 | 53 | @Override 54 | public > R execute(C command) { 55 | Set> violations = validator.validate(command); 56 | if (!violations.isEmpty()) { 57 | throw new ConstraintViolationException(violations); 58 | } 59 | return decorated.execute(command); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /command-bus-core/src/test/java/com/cloudogu/cb/decorator/PrometheusMetricsCountingCommandBusTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2017 Cloudogu GmbH 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package com.cloudogu.cb.decorator; 25 | 26 | import com.cloudogu.cb.CommandBus; 27 | import com.cloudogu.cb.EchoCommand; 28 | import io.prometheus.client.Counter; 29 | import org.junit.Before; 30 | import org.junit.Test; 31 | import org.junit.runner.RunWith; 32 | import org.mockito.Mock; 33 | import org.mockito.junit.MockitoJUnitRunner; 34 | 35 | import static org.mockito.Mockito.verify; 36 | import static org.mockito.Mockito.when; 37 | 38 | @RunWith(MockitoJUnitRunner.class) 39 | public class PrometheusMetricsCountingCommandBusTest { 40 | 41 | @Mock 42 | private CommandBus commandBus; 43 | 44 | @Mock 45 | private Counter counter; 46 | 47 | @Mock 48 | private Counter.Child child; 49 | 50 | private PrometheusMetricsCountingCommandBus decoratedCommandBus; 51 | 52 | @Before 53 | public void setUp() { 54 | when(counter.labels(EchoCommand.class.getSimpleName())).thenReturn(child); 55 | this.decoratedCommandBus = new PrometheusMetricsCountingCommandBus(commandBus, counter); 56 | } 57 | 58 | @Test 59 | public void execute() { 60 | EchoCommand hello = new EchoCommand("joe"); 61 | decoratedCommandBus.execute(hello); 62 | verify(commandBus).execute(hello); 63 | verify(counter).labels(hello.getClass().getSimpleName()); 64 | verify(child).inc(); 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /command-bus-core/src/main/java/de/triology/cb/decorator/PrometheusMetricsCountingCommandBus.java: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2017 Cloudogu GmbH 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package com.cloudogu.cb.decorator; 25 | 26 | import com.cloudogu.cb.Command; 27 | import com.cloudogu.cb.CommandBus; 28 | import io.prometheus.client.Counter; 29 | 30 | /** 31 | * Command bus decorator counting the executed commands using a Prometheus {@link Counter} 32 | */ 33 | public class PrometheusMetricsCountingCommandBus implements CommandBus { 34 | 35 | private CommandBus decorated; 36 | private Counter counter; 37 | 38 | /** 39 | * Creates a new PrometheusMetricsCountingCommandBus 40 | * 41 | * @param decorated command bus to decorate 42 | * @param counter counter to increment on executing commands 43 | */ 44 | public PrometheusMetricsCountingCommandBus(CommandBus decorated, Counter counter) { 45 | this.decorated = decorated; 46 | this.counter = counter; 47 | } 48 | 49 | /** 50 | * Delegates the provided command to the decorated command bus and increases the given counter using the command's 51 | * classname as a label 52 | * 53 | * @param command command object 54 | * @param type of return value 55 | * @param type of command 56 | */ 57 | @Override 58 | public > R execute(C command) { 59 | R result = decorated.execute(command); 60 | counter.labels(command.getClass().getSimpleName()).inc(); 61 | return result; 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /command-bus-spring/src/test/java/com/cloudogu/cb/spring/RegistryTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2017 Cloudogu GmbH 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package com.cloudogu.cb.spring; 25 | 26 | import com.cloudogu.cb.CommandHandler; 27 | import com.cloudogu.cb.HelloCommand; 28 | import com.cloudogu.cb.HelloCommandHandler; 29 | import org.junit.Test; 30 | import org.junit.runner.RunWith; 31 | import org.mockito.Mock; 32 | import org.mockito.junit.MockitoJUnitRunner; 33 | import org.springframework.context.ApplicationContext; 34 | 35 | import static org.assertj.core.api.Assertions.assertThat; 36 | import static org.mockito.Mockito.when; 37 | 38 | @RunWith(MockitoJUnitRunner.class) 39 | public class RegistryTest { 40 | 41 | @Mock 42 | private ApplicationContext applicationContext; 43 | 44 | @Mock 45 | private HelloCommandHandler helloCommandHandler; 46 | 47 | @Test 48 | public void testRegistration() { 49 | String[] commandHandlers = new String[]{"helloCommandHandler"}; 50 | when(applicationContext.getBeanNamesForType(CommandHandler.class)).thenReturn(commandHandlers); 51 | 52 | Class type = HelloCommandHandler.class; 53 | when(applicationContext.getType("helloCommandHandler")).thenReturn(type); 54 | 55 | when(applicationContext.getBean(HelloCommandHandler.class)).thenReturn(helloCommandHandler); 56 | 57 | Registry registry = new Registry(applicationContext); 58 | CommandHandler handler = registry.get(HelloCommand.class); 59 | 60 | assertThat(handler).isInstanceOf(HelloCommandHandler.class); 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /command-bus-core/src/main/java/de/triology/cb/decorator/PrometheusMetricsTimingCommandBus.java: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2017 Cloudogu GmbH 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package com.cloudogu.cb.decorator; 25 | 26 | import com.cloudogu.cb.Command; 27 | import com.cloudogu.cb.CommandBus; 28 | import io.prometheus.client.Histogram; 29 | 30 | /** 31 | * Command bus decorator counting the executed commands using a Prometheus {@link Histogram} 32 | */ 33 | public class PrometheusMetricsTimingCommandBus implements CommandBus { 34 | private CommandBus decorated; 35 | private Histogram histogram; 36 | 37 | 38 | /** 39 | * Creates a new PrometheusMetricsCountingCommandBus 40 | * 41 | * @param decorated command bus to decorate 42 | * @param histogram histogram to be used for timing 43 | */ 44 | public PrometheusMetricsTimingCommandBus(CommandBus decorated, Histogram histogram) { 45 | this.decorated = decorated; 46 | this.histogram = histogram; 47 | } 48 | 49 | /** 50 | * Delegates the provided command to the decorated command bus and times the command's execution using it's 51 | * classname as a label 52 | * 53 | * @param command command object 54 | * @param type of return value 55 | * @param type of command 56 | */ 57 | @Override 58 | public > R execute(C command) { 59 | Histogram.Timer commandTimer = histogram.labels(command.getClass().getSimpleName()).startTimer(); 60 | R result = decorated.execute(command); 61 | commandTimer.observeDuration(); 62 | return result; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /command-bus-core/src/test/java/com/cloudogu/cb/decorator/PrometheusMetricsTimingCommandBusTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2017 Cloudogu GmbH 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package com.cloudogu.cb.decorator; 25 | 26 | import com.cloudogu.cb.CommandBus; 27 | import com.cloudogu.cb.EchoCommand; 28 | import io.prometheus.client.Histogram; 29 | import org.junit.Before; 30 | import org.junit.Test; 31 | import org.junit.runner.RunWith; 32 | import org.mockito.Mock; 33 | import org.mockito.junit.MockitoJUnitRunner; 34 | 35 | import static org.mockito.Mockito.verify; 36 | import static org.mockito.Mockito.when; 37 | 38 | @RunWith(MockitoJUnitRunner.class) 39 | public class PrometheusMetricsTimingCommandBusTest { 40 | @Mock 41 | private CommandBus commandBus; 42 | 43 | @Mock 44 | private Histogram histogram; 45 | 46 | @Mock 47 | private Histogram.Child child; 48 | 49 | @Mock 50 | private Histogram.Timer timer; 51 | 52 | private PrometheusMetricsTimingCommandBus decoratedCommandBus; 53 | 54 | @Before 55 | public void setUp() { 56 | when(histogram.labels(EchoCommand.class.getSimpleName())).thenReturn(child); 57 | when(child.startTimer()).thenReturn(timer); 58 | decoratedCommandBus = new PrometheusMetricsTimingCommandBus(commandBus, histogram); 59 | } 60 | 61 | @Test 62 | public void execute() { 63 | EchoCommand echoCommand = new EchoCommand("July"); 64 | decoratedCommandBus.execute(echoCommand); 65 | verify(histogram).labels(EchoCommand.class.getSimpleName()); 66 | verify(commandBus).execute(echoCommand); 67 | verify(timer).observeDuration(); 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /command-bus-core/src/test/java/com/cloudogu/cb/decorator/DurationFormatterTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2017 Cloudogu GmbH 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package com.cloudogu.cb.decorator; 25 | 26 | import org.junit.Test; 27 | 28 | import java.util.concurrent.TimeUnit; 29 | 30 | import static org.assertj.core.api.Assertions.assertThat; 31 | 32 | /** 33 | * Unit tests for {@link DurationFormatter}. 34 | */ 35 | public class DurationFormatterTest { 36 | 37 | @Test 38 | public void format() { 39 | assertThat(com.cloudogu.cb.decorator.DurationFormatter.format(1000, TimeUnit.NANOSECONDS)).isEqualTo("1μs"); 40 | assertThat(com.cloudogu.cb.decorator.DurationFormatter.format(1000, TimeUnit.MICROSECONDS)).isEqualTo("1ms"); 41 | assertThat(com.cloudogu.cb.decorator.DurationFormatter.format(1000, TimeUnit.MILLISECONDS)).isEqualTo("1s"); 42 | assertThat(com.cloudogu.cb.decorator.DurationFormatter.format(60, TimeUnit.SECONDS)).isEqualTo("1min"); 43 | assertThat(com.cloudogu.cb.decorator.DurationFormatter.format(60, TimeUnit.MINUTES)).isEqualTo("1h"); 44 | assertThat(com.cloudogu.cb.decorator.DurationFormatter.format(24, TimeUnit.HOURS)).isEqualTo("1d"); 45 | 46 | assertThat(com.cloudogu.cb.decorator.DurationFormatter.format(12, TimeUnit.MINUTES)).isEqualTo("12min"); 47 | assertThat(com.cloudogu.cb.decorator.DurationFormatter.format(2, TimeUnit.SECONDS)).isEqualTo("2s"); 48 | assertThat(com.cloudogu.cb.decorator.DurationFormatter.format(120, TimeUnit.SECONDS)).isEqualTo("2min"); 49 | assertThat(com.cloudogu.cb.decorator.DurationFormatter.format(360, TimeUnit.MINUTES)).isEqualTo("6h"); 50 | } 51 | 52 | } -------------------------------------------------------------------------------- /command-bus-spring/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 27 | 30 | 31 | command-bus-parent 32 | com.cloudogu.cb 33 | 2.0.1-SNAPSHOT 34 | 35 | 4.0.0 36 | 37 | command-bus-spring 38 | 2.0.1-SNAPSHOT 39 | 40 | 41 | 42 | 43 | 44 | 45 | org.springframework 46 | spring-framework-bom 47 | 4.3.29.RELEASE 48 | pom 49 | import 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | ${project.groupId} 60 | command-bus-core 61 | 62 | 63 | 64 | org.springframework 65 | spring-context 66 | provided 67 | 68 | 69 | 70 | org.springframework 71 | spring-test 72 | test 73 | 74 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /command-bus-spring/src/test/java/com/cloudogu/cb/spring/SpringITCase.java: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2017 Cloudogu GmbH 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package com.cloudogu.cb.spring; 25 | 26 | import com.cloudogu.cb.ByeCommand; 27 | import com.cloudogu.cb.ByeCommandHandler; 28 | import com.cloudogu.cb.CommandBus; 29 | import com.cloudogu.cb.HelloCommand; 30 | import com.cloudogu.cb.HelloCommandHandler; 31 | import com.cloudogu.cb.MessageCollector; 32 | import org.assertj.core.api.Assertions; 33 | import org.junit.Test; 34 | import org.junit.runner.RunWith; 35 | import org.springframework.beans.factory.annotation.Autowired; 36 | import org.springframework.test.context.ContextConfiguration; 37 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 38 | 39 | import static org.assertj.core.api.Assertions.assertThat; 40 | 41 | @ContextConfiguration(classes = { 42 | HelloCommandHandler.class, 43 | ByeCommandHandler.class, 44 | MessageCollector.class, 45 | Registry.class, 46 | CommandBusFactory.class 47 | }) 48 | @RunWith(SpringJUnit4ClassRunner.class) 49 | public class SpringITCase { 50 | 51 | @Autowired 52 | private CommandBus commandBus; 53 | 54 | 55 | @Autowired 56 | private MessageCollector messageCollector; 57 | 58 | @Test 59 | public void execute() { 60 | String actualStringReturnValue = commandBus.execute(new HelloCommand("hans")); 61 | Void actualVoidReturnValue = commandBus.execute(new ByeCommand("hans")); 62 | 63 | Assertions.assertThat(messageCollector.getMessages()).contains("hello hans", "bye hans"); 64 | 65 | assertThat(actualStringReturnValue).isEqualTo("hello hans"); 66 | assertThat(actualVoidReturnValue).isNull(); 67 | } 68 | 69 | } -------------------------------------------------------------------------------- /command-bus-spring/src/main/java/com/cloudogu/cb/spring/Registry.java: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2017 Cloudogu GmbH 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package com.cloudogu.cb.spring; 25 | 26 | import com.cloudogu.cb.Command; 27 | import com.cloudogu.cb.CommandHandler; 28 | import org.springframework.beans.factory.annotation.Autowired; 29 | import org.springframework.context.ApplicationContext; 30 | import org.springframework.core.GenericTypeResolver; 31 | 32 | import java.util.HashMap; 33 | import java.util.Map; 34 | 35 | /** 36 | * Registry holds the mapping between a command and its handler. The registry should always be injected, by the spring 37 | * framework. 38 | */ 39 | public class Registry { 40 | 41 | private Map, CommandProvider> providerMap = new HashMap<>(); 42 | 43 | @Autowired 44 | public Registry(ApplicationContext applicationContext) { 45 | String[] names = applicationContext.getBeanNamesForType(CommandHandler.class); 46 | for (String name : names) { 47 | register(applicationContext, name); 48 | } 49 | } 50 | 51 | private void register( ApplicationContext applicationContext, String name ){ 52 | Class> handlerClass = (Class>) applicationContext.getType(name); 53 | Class[] generics = GenericTypeResolver.resolveTypeArguments(handlerClass, CommandHandler.class); 54 | Class commandType = (Class) generics[1]; 55 | providerMap.put(commandType, new CommandProvider(applicationContext, handlerClass)); 56 | } 57 | 58 | @SuppressWarnings("unchecked") 59 | > CommandHandler get(Class commandClass) { 60 | return providerMap.get(commandClass).get(); 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /command-bus-core/src/test/java/com/cloudogu/cb/decorator/MicrometerCountingCommandBusTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2017 Cloudogu GmbH 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package com.cloudogu.cb.decorator; 25 | 26 | import com.cloudogu.cb.Command; 27 | import com.cloudogu.cb.CommandBus; 28 | import com.cloudogu.cb.EchoCommand; 29 | import io.micrometer.core.instrument.Counter; 30 | import org.junit.Before; 31 | import org.junit.Test; 32 | import org.junit.runner.RunWith; 33 | import org.mockito.Mock; 34 | import org.mockito.junit.MockitoJUnitRunner; 35 | 36 | import static org.mockito.Mockito.times; 37 | import static org.mockito.Mockito.verify; 38 | 39 | @RunWith(MockitoJUnitRunner.class) 40 | public class MicrometerCountingCommandBusTest { 41 | 42 | @Mock 43 | private CommandBus commandBus; 44 | 45 | @Mock 46 | private Counter counterOne; 47 | 48 | @Mock 49 | private Counter counterTwo; 50 | 51 | private MicrometerCountingCommandBus decoratedCommandBus; 52 | 53 | @Before 54 | public void setUp() { 55 | decoratedCommandBus = new MicrometerCountingCommandBus(commandBus, command -> { 56 | if (EchoCommand.class.isAssignableFrom(command)) { 57 | return counterOne; 58 | } 59 | return counterTwo; 60 | }); 61 | } 62 | 63 | @Test 64 | public void execute() { 65 | decoratedCommandBus.execute(new EchoCommand("hello")); 66 | decoratedCommandBus.execute(new EchoCommand("hello 2")); 67 | decoratedCommandBus.execute(new OtherCommand()); 68 | decoratedCommandBus.execute(new OtherCommand()); 69 | 70 | verify(counterOne, times(2)).increment(); 71 | verify(counterTwo, times(2)).increment(); 72 | } 73 | 74 | public static class OtherCommand implements Command { 75 | 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /command-bus-core/src/test/java/com/cloudogu/cb/decorator/ValidatingCommandBusTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2017 Cloudogu GmbH 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package com.cloudogu.cb.decorator; 25 | 26 | import com.cloudogu.cb.Command; 27 | import com.cloudogu.cb.CommandBus; 28 | import org.junit.Before; 29 | import org.junit.Test; 30 | import org.junit.runner.RunWith; 31 | import org.mockito.Mock; 32 | import org.mockito.junit.MockitoJUnitRunner; 33 | 34 | import javax.validation.ConstraintViolationException; 35 | import javax.validation.Validation; 36 | import javax.validation.ValidatorFactory; 37 | import javax.validation.constraints.NotNull; 38 | 39 | import static org.mockito.Mockito.verify; 40 | 41 | @RunWith(MockitoJUnitRunner.class) 42 | public class ValidatingCommandBusTest { 43 | 44 | @Mock 45 | private CommandBus commandBus; 46 | 47 | private ValidatingCommandBus decoratedCommandBus; 48 | 49 | @Before 50 | public void setUpCommandBus() { 51 | ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); 52 | decoratedCommandBus = new ValidatingCommandBus(commandBus, factory.getValidator()); 53 | } 54 | 55 | @Test(expected = ConstraintViolationException.class) 56 | public void shouldThrowValidationException() { 57 | decoratedCommandBus.execute(new SampleCommand(null)); 58 | } 59 | 60 | @Test 61 | public void shouldCallDecorated() { 62 | SampleCommand command = new SampleCommand("valid"); 63 | decoratedCommandBus.execute(command); 64 | verify(commandBus).execute(command); 65 | } 66 | 67 | public static class SampleCommand implements Command { 68 | 69 | @NotNull 70 | private String value; 71 | 72 | public SampleCommand(@NotNull String value) { 73 | this.value = value; 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /command-bus-core/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 27 | 30 | 31 | command-bus-parent 32 | com.cloudogu.cb 33 | 2.0.1-SNAPSHOT 34 | 35 | 4.0.0 36 | 37 | command-bus-core 38 | 39 | 40 | 41 | 42 | io.prometheus 43 | simpleclient 44 | 0.1.0 45 | true 46 | 47 | 48 | 49 | io.micrometer 50 | micrometer-core 51 | 1.1.5 52 | true 53 | 54 | 55 | 56 | javax.validation 57 | validation-api 58 | 2.0.1.Final 59 | true 60 | 61 | 62 | 63 | org.hibernate 64 | hibernate-validator 65 | 6.0.17.Final 66 | test 67 | 68 | 69 | 70 | org.glassfish 71 | javax.el 72 | 3.0.1-b11 73 | test 74 | 75 | 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /command-bus-core/src/main/java/de/triology/cb/decorator/MicrometerCountingCommandBus.java: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2017 Cloudogu GmbH 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package com.cloudogu.cb.decorator; 25 | 26 | import com.cloudogu.cb.Command; 27 | import com.cloudogu.cb.CommandBus; 28 | import io.micrometer.core.instrument.Counter; 29 | 30 | import java.util.Map; 31 | import java.util.concurrent.ConcurrentHashMap; 32 | 33 | /** 34 | * Command bus decorator counting the executed commands using a Micrometer {@link Counter} 35 | */ 36 | public class MicrometerCountingCommandBus implements CommandBus { 37 | 38 | /** 39 | * Factory for creating Micrometer counters for the given command class. 40 | */ 41 | @FunctionalInterface 42 | public interface CounterFactory { 43 | /** 44 | * Create counter for given command class. 45 | * 46 | * @param command class of command 47 | * @return Micrometer counter 48 | */ 49 | Counter create(Class command); 50 | } 51 | 52 | private final CommandBus decorated; 53 | private final CounterFactory counterFactory; 54 | private final Map,Counter> counters = new ConcurrentHashMap<>(); 55 | 56 | /** 57 | * Creates a new {@link MicrometerCountingCommandBus}. 58 | * 59 | * @param decorated command bus to decorate 60 | * @param counterFactory factory to create a Micrometer counter 61 | */ 62 | public MicrometerCountingCommandBus(CommandBus decorated, CounterFactory counterFactory) { 63 | this.decorated = decorated; 64 | this.counterFactory = counterFactory; 65 | } 66 | 67 | @Override 68 | public > R execute(C command) { 69 | counters.computeIfAbsent(command.getClass(), counterFactory::create).increment(); 70 | return decorated.execute(command); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /command-bus-cdi/src/test/java/com/cloudogu/cb/cdi/CDIITCase.java: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2017 Cloudogu GmbH 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package com.cloudogu.cb.cdi; 25 | 26 | import com.cloudogu.cb.ByeCommand; 27 | import com.cloudogu.cb.CommandBus; 28 | import com.cloudogu.cb.HelloCommand; 29 | import com.cloudogu.cb.MessageCollector; 30 | import org.assertj.core.api.Assertions; 31 | import org.jboss.arquillian.container.test.api.Deployment; 32 | import org.jboss.arquillian.junit.Arquillian; 33 | import org.jboss.shrinkwrap.api.ShrinkWrap; 34 | import org.jboss.shrinkwrap.api.spec.JavaArchive; 35 | import org.junit.Test; 36 | import org.junit.runner.RunWith; 37 | 38 | import javax.inject.Inject; 39 | import java.io.File; 40 | 41 | import static org.assertj.core.api.Assertions.assertThat; 42 | 43 | @RunWith(Arquillian.class) 44 | public class CDIITCase { 45 | 46 | @Deployment 47 | public static JavaArchive createDeployment() { 48 | JavaArchive archive = ShrinkWrap.create(JavaArchive.class) 49 | .addPackage(CommandBus.class.getPackage()) 50 | .addPackage(CDIExtension.class.getPackage()); 51 | 52 | for (File file : new File("src/main/resources/META-INF").listFiles() ) { 53 | archive.addAsManifestResource(file); 54 | } 55 | 56 | return archive; 57 | } 58 | 59 | @Inject 60 | private CommandBus commandBus; 61 | 62 | @Inject 63 | private MessageCollector messageCollector; 64 | 65 | @Test 66 | public void execute() { 67 | String actualStringReturnValue = commandBus.execute(new HelloCommand("hans")); 68 | Void actualVoidReturnValue = commandBus.execute(new ByeCommand("hans")); 69 | 70 | Assertions.assertThat(messageCollector.getMessages()).contains("hello hans", "bye hans"); 71 | 72 | assertThat(actualStringReturnValue).isEqualTo("hello hans"); 73 | assertThat(actualVoidReturnValue).isNull(); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /Jenkinsfile: -------------------------------------------------------------------------------- 1 | #!groovy 2 | @Library('github.com/cloudogu/ces-build-lib@1.63.0') 3 | import com.cloudogu.ces.cesbuildlib.* 4 | 5 | properties([ 6 | // Keep only the most recent builds in order to preserve space 7 | buildDiscarder(logRotator(numToKeepStr: '20')), 8 | // Don't run concurrent builds for a branch, because they use the same workspace directory 9 | disableConcurrentBuilds() 10 | ]) 11 | 12 | node { 13 | Maven mvn = new MavenWrapper(this) 14 | // Sonar stopped support for JRE8 for its client, so for now we run the analysis in a separate container. 15 | // Once the lib is upgraded to JDK11 this can be removed 16 | String SonarJreImage = 'adoptopenjdk/openjdk11:jre-11.0.11_9-alpine' 17 | Git git = new Git(this) 18 | 19 | catchError { 20 | 21 | stage('Checkout') { 22 | checkout scm 23 | git.clean('') 24 | } 25 | 26 | initMaven(mvn) 27 | 28 | stage('Build') { 29 | mvn 'clean install -DskipTests' 30 | archive '**/target/*.jar' 31 | } 32 | 33 | stage('Unit Test') { 34 | mvn 'test' 35 | } 36 | 37 | stage('Integration Test') { 38 | mvn 'verify -DskipUnitTests' 39 | } 40 | 41 | stage('Static Code Analysis') { 42 | def sonarQube = new SonarCloud(this, [sonarQubeEnv: 'sonarcloud.io-cloudogu']) 43 | 44 | sonarQube.analyzeWith(new MavenWrapperInDocker(this, SonarJreImage)) 45 | sonarQube.timeoutInMinutes = 5 46 | 47 | if (!sonarQube.waitForQualityGateWebhookToBeCalled()) { 48 | currentBuild.result ='UNSTABLE' 49 | } 50 | } 51 | 52 | stage('Deploy') { 53 | if (preconditionsForDeploymentFulfilled()) { 54 | 55 | mvn.useDeploymentRepository([id: 'ossrh', url: 'https://oss.sonatype.org/', 56 | credentialsId: 'mavenCentral-acccessToken', type: 'Nexus2']) 57 | 58 | mvn.setSignatureCredentials('mavenCentral-secretKey-asc-file', 59 | 'mavenCentral-secretKey-Passphrase') 60 | 61 | mvn.deployToNexusRepositoryWithStaging() 62 | } 63 | } 64 | } 65 | 66 | // Archive Unit and integration test results, if any 67 | junit allowEmptyResults: true, 68 | testResults: '**/target/surefire-reports/TEST-*.xml, **/target/failsafe-reports/*.xml' 69 | 70 | mailIfStatusChanged(git.commitAuthorEmail) 71 | } 72 | 73 | boolean preconditionsForDeploymentFulfilled() { 74 | if (isBuildSuccessful() && 75 | !isPullRequest() && 76 | shouldBranchBeDeployed()) { 77 | return true 78 | } else { 79 | echo "Skipping deployment because of branch or build result: currentResult=${currentBuild.currentResult}, " + 80 | "result=${currentBuild.result}, branch=${env.BRANCH_NAME}." 81 | return false 82 | } 83 | } 84 | 85 | private boolean shouldBranchBeDeployed() { 86 | return env.BRANCH_NAME == 'master' || env.BRANCH_NAME == 'develop' 87 | } 88 | 89 | void initMaven(Maven mvn) { 90 | 91 | if ("master".equals(env.BRANCH_NAME)) { 92 | 93 | echo "Building master branch" 94 | mvn.additionalArgs = "-DperformRelease" 95 | currentBuild.description = mvn.getVersion() 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /command-bus-core/src/test/java/com/cloudogu/cb/decorator/MicrometerTimingCommandBusTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2017 Cloudogu GmbH 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package com.cloudogu.cb.decorator; 25 | 26 | import com.cloudogu.cb.Command; 27 | import com.cloudogu.cb.CommandBus; 28 | import com.cloudogu.cb.EchoCommand; 29 | import io.micrometer.core.instrument.Timer; 30 | import org.junit.Before; 31 | import org.junit.Test; 32 | import org.junit.runner.RunWith; 33 | import org.mockito.Mock; 34 | import org.mockito.junit.MockitoJUnitRunner; 35 | 36 | import java.time.Clock; 37 | import java.time.Duration; 38 | import java.time.Instant; 39 | import java.time.temporal.ChronoUnit; 40 | 41 | import static org.mockito.Mockito.verify; 42 | import static org.mockito.Mockito.when; 43 | 44 | @RunWith(MockitoJUnitRunner.class) 45 | public class MicrometerTimingCommandBusTest { 46 | 47 | @Mock 48 | private CommandBus commandBus; 49 | 50 | @Mock 51 | private Timer timerOne; 52 | 53 | @Mock 54 | private Timer timerTwo; 55 | 56 | @Mock 57 | private Clock clock; 58 | 59 | private MicrometerTimingCommandBus decoratedCommandBus; 60 | 61 | private final Instant start = Instant.now(); 62 | private Instant current = start; 63 | 64 | @Before 65 | public void setUp() { 66 | decoratedCommandBus = new MicrometerTimingCommandBus(commandBus, command -> { 67 | if (EchoCommand.class.isAssignableFrom(command)) { 68 | return timerOne; 69 | } 70 | return timerTwo; 71 | }, clock); 72 | 73 | when(clock.instant()).then(ic -> { 74 | current = current.plusSeconds(1L); 75 | return current; 76 | }); 77 | } 78 | 79 | @Test 80 | public void execute() { 81 | decoratedCommandBus.execute(new EchoCommand("hello")); 82 | verify(timerOne).record(Duration.of(1L, ChronoUnit.SECONDS)); 83 | 84 | decoratedCommandBus.execute(new OtherCommand()); 85 | verify(timerTwo).record(Duration.of(1L, ChronoUnit.SECONDS)); 86 | } 87 | 88 | public static class OtherCommand implements Command { 89 | 90 | } 91 | 92 | } 93 | -------------------------------------------------------------------------------- /command-bus-core/src/test/java/com/cloudogu/cb/decorator/LoggingCommandBusTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2017 Cloudogu GmbH 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package com.cloudogu.cb.decorator; 25 | 26 | import com.thekua.spikes.LogbackCapturingAppender; 27 | import com.cloudogu.cb.CommandBus; 28 | import com.cloudogu.cb.EchoCommand; 29 | import org.junit.After; 30 | import org.junit.Test; 31 | import org.junit.runner.RunWith; 32 | import org.mockito.InjectMocks; 33 | import org.mockito.Mock; 34 | import org.mockito.junit.MockitoJUnitRunner; 35 | 36 | import java.util.List; 37 | 38 | import static org.assertj.core.api.Assertions.assertThat; 39 | import static org.mockito.ArgumentMatchers.any; 40 | import static org.mockito.Mockito.verify; 41 | import static org.mockito.Mockito.when; 42 | 43 | /** 44 | * Unit tests for {@link LoggingCommandBus}. 45 | */ 46 | @RunWith(MockitoJUnitRunner.class) 47 | public class LoggingCommandBusTest { 48 | 49 | @Mock 50 | private CommandBus commandBus; 51 | 52 | @InjectMocks 53 | private LoggingCommandBus decoratedCommandBus; 54 | 55 | @After 56 | public void cleanUp() { 57 | LogbackCapturingAppender.cleanUpAll(); 58 | } 59 | 60 | @Test 61 | public void execute() { 62 | LogbackCapturingAppender capturing = LogbackCapturingAppender.weaveInto(LoggingCommandBus.LOG); 63 | 64 | EchoCommand echoCommand = new EchoCommand("joe"); 65 | decoratedCommandBus.execute(echoCommand); 66 | verify(commandBus).execute(echoCommand); 67 | 68 | List messages = capturing.getCapturedLogMessages(); 69 | assertThat(messages.get(0)).contains("start").contains("EchoCommand"); 70 | assertThat(messages.get(1)).contains("finish").contains("EchoCommand"); 71 | } 72 | 73 | @Test 74 | public void shouldLogFinishEvenWithException() { 75 | LogbackCapturingAppender capturing = LogbackCapturingAppender.weaveInto(LoggingCommandBus.LOG); 76 | 77 | when(commandBus.execute(any())).thenThrow(new IllegalStateException("failed")); 78 | 79 | EchoCommand echoCommand = new EchoCommand("joe"); 80 | try { 81 | decoratedCommandBus.execute(echoCommand); 82 | } catch (IllegalStateException ex) { 83 | // expected 84 | } 85 | 86 | List messages = capturing.getCapturedLogMessages(); 87 | assertThat(messages.get(0)).contains("start").contains("EchoCommand"); 88 | assertThat(messages.get(1)).contains("finish").contains("EchoCommand"); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /command-bus-core/src/main/java/de/triology/cb/decorator/MicrometerTimingCommandBus.java: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2017 Cloudogu GmbH 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package com.cloudogu.cb.decorator; 25 | 26 | import com.cloudogu.cb.Command; 27 | import com.cloudogu.cb.CommandBus; 28 | import io.micrometer.core.instrument.Timer; 29 | 30 | import java.time.Clock; 31 | import java.time.Duration; 32 | import java.time.Instant; 33 | import java.util.Map; 34 | import java.util.concurrent.ConcurrentHashMap; 35 | 36 | /** 37 | * Command bus decorator which measures the elapsed time for a command execution by using a Micrometer {@link Timer}. 38 | */ 39 | public class MicrometerTimingCommandBus implements CommandBus { 40 | 41 | /** 42 | * Factory for creating Micrometer timers for the given command class. 43 | */ 44 | @FunctionalInterface 45 | public interface TimerFactory { 46 | /** 47 | * Create timer for given command class. 48 | * 49 | * @param command class of command 50 | * @return Micrometer timer 51 | */ 52 | Timer create(Class command); 53 | } 54 | 55 | private final CommandBus decorated; 56 | private final TimerFactory timerFactory; 57 | private final Clock clock; 58 | 59 | private final Map, Timer> timers = new ConcurrentHashMap<>(); 60 | 61 | /** 62 | * Creates a new {@link MicrometerTimingCommandBus}. 63 | * 64 | * @param decorated command bus to decorate 65 | * @param timerFactory factory to create a Micrometer counter 66 | */ 67 | public MicrometerTimingCommandBus(CommandBus decorated, TimerFactory timerFactory) { 68 | this(decorated, timerFactory, Clock.systemDefaultZone()); 69 | } 70 | 71 | /** 72 | * Creates a new {@link MicrometerTimingCommandBus}. This constructor should only be used for testing. 73 | * 74 | * @param decorated command bus to decorate 75 | * @param timerFactory factory to create a Micrometer counter 76 | * @param clock clock for calculating elapsed time 77 | */ 78 | MicrometerTimingCommandBus(CommandBus decorated, TimerFactory timerFactory, Clock clock) { 79 | this.decorated = decorated; 80 | this.timerFactory = timerFactory; 81 | this.clock = clock; 82 | } 83 | 84 | @Override 85 | public > R execute(C command) { 86 | Timer timer = timers.computeIfAbsent(command.getClass(), timerFactory::create); 87 | 88 | Instant now = Instant.now(clock); 89 | R result = decorated.execute(command); 90 | timer.record(Duration.between(now, Instant.now(clock))); 91 | 92 | return result; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /command-bus-cdi/src/main/java/com/cloudogu/cb/cdi/CDIExtension.java: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2017 Cloudogu GmbH 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package com.cloudogu.cb.cdi; 25 | 26 | import com.cloudogu.cb.Command; 27 | import com.cloudogu.cb.CommandHandler; 28 | 29 | import javax.enterprise.context.spi.CreationalContext; 30 | import javax.enterprise.event.Observes; 31 | import javax.enterprise.inject.spi.*; 32 | import java.lang.reflect.ParameterizedType; 33 | import java.lang.reflect.Type; 34 | import java.util.HashMap; 35 | import java.util.Map; 36 | 37 | /** 38 | * CDI Extension to find and register all available commands. 39 | */ 40 | @SuppressWarnings("unchecked") 41 | public class CDIExtension implements Extension { 42 | 43 | private Map, Class>> commandHandlers = new HashMap<>(); 44 | 45 | /** 46 | * Captures all command handlers. 47 | * 48 | * @param target cdi event 49 | * @param handler type 50 | */ 51 | public > void captureCommandHandlers(@Observes ProcessInjectionTarget target) { 52 | Class handler = target.getAnnotatedType().getJavaClass(); 53 | for ( Type type : target.getAnnotatedType().getTypeClosure() ) { 54 | if (type instanceof ParameterizedType) { 55 | ParameterizedType parameterizedType = (ParameterizedType) type; 56 | Type genericParameterType = parameterizedType.getActualTypeArguments()[1]; 57 | if (genericParameterType instanceof Class) { 58 | register((Class>) genericParameterType, handler); 59 | } 60 | } 61 | } 62 | } 63 | 64 | /** 65 | * Registers all captured handlers on the {@link Registry}. 66 | * @param event cdi event 67 | * @param beanManager cdi bean manager 68 | */ 69 | public void register(@Observes AfterDeploymentValidation event, final BeanManager beanManager) { 70 | Registry registry = getRegistry(beanManager); 71 | commandHandlers.forEach((commandClass, handlerClass) -> 72 | registry.register(commandClass, new CommandProvider(beanManager, handlerClass))); 73 | } 74 | 75 | private void register(Class> command, Class> handler) { 76 | commandHandlers.put(command, handler); 77 | } 78 | 79 | private Registry getRegistry(BeanManager beanManager) { 80 | Bean registryBean = (Bean) beanManager.getBeans(Registry.class).iterator().next(); 81 | CreationalContext context = beanManager.createCreationalContext(registryBean); 82 | return (Registry) beanManager.getReference(registryBean, Registry.class, context); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /command-bus-cdi/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 27 | 30 | 31 | command-bus-parent 32 | com.cloudogu.cb 33 | 2.0.1-SNAPSHOT 34 | 35 | 4.0.0 36 | 37 | command-bus-cdi 38 | 39 | 40 | 41 | 42 | 43 | 44 | org.jboss.spec 45 | jboss-javaee-7.0 46 | 1.0.3.Final 47 | pom 48 | provided 49 | 50 | 51 | 52 | org.jboss.arquillian 53 | arquillian-bom 54 | 1.1.13.Final 55 | import 56 | pom 57 | 58 | 59 | 60 | org.jboss.weld 61 | weld-core-bom 62 | 2.2.8.Final 63 | pom 64 | import 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | ${project.groupId} 74 | command-bus-core 75 | 76 | 77 | 78 | org.jboss.spec 79 | jboss-javaee-7.0 80 | pom 81 | provided 82 | 83 | 84 | 85 | org.jboss.arquillian.container 86 | arquillian-weld-ee-embedded-1.1 87 | 1.0.0.Final 88 | test 89 | 90 | 91 | 92 | org.jboss.weld 93 | weld-core 94 | test 95 | 96 | 97 | 98 | org.jboss.arquillian.junit 99 | arquillian-junit-container 100 | test 101 | 102 | 103 | 104 | 105 | 106 | 107 | -------------------------------------------------------------------------------- /command-bus-core/src/main/java/de/triology/cb/decorator/DurationFormatter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * MIT License 3 | * 4 | * Copyright (c) 2017 Cloudogu GmbH 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all 14 | * copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | package com.cloudogu.cb.decorator; 25 | 26 | import java.text.NumberFormat; 27 | import java.util.Locale; 28 | import java.util.concurrent.TimeUnit; 29 | 30 | import static java.util.concurrent.TimeUnit.*; 31 | 32 | /** 33 | * DurationFormatter formats duration with its abbreviate time unit. 34 | */ 35 | final class DurationFormatter { 36 | 37 | private DurationFormatter(){} 38 | 39 | /** 40 | * Returns the formatted duration with the abbreviate time unit. 41 | * 42 | * @param duration duration 43 | * @param sourceUnit unit of duration 44 | * 45 | * @return formatted duration 46 | */ 47 | public static String format(long duration, TimeUnit sourceUnit) { 48 | long durationInNanoSeconds = convertToNanoSeconds(duration, sourceUnit); 49 | return formatNanoSeconds(durationInNanoSeconds); 50 | } 51 | 52 | private static long convertToNanoSeconds(long duration, TimeUnit sourceUnit) { 53 | return TimeUnit.NANOSECONDS.convert(duration, sourceUnit); 54 | } 55 | 56 | private static String formatNanoSeconds(long durationInNanoSeconds) { 57 | TimeUnit targetUnit = chooseUnit(durationInNanoSeconds); 58 | double value = (double) durationInNanoSeconds / NANOSECONDS.convert(1, targetUnit); 59 | 60 | NumberFormat formatter = NumberFormat.getInstance(Locale.ENGLISH); 61 | return formatter.format(value) + abbreviate(targetUnit); 62 | } 63 | 64 | private static TimeUnit chooseUnit(long nanos) { 65 | if (DAYS.convert(nanos, NANOSECONDS) > 0) { 66 | return DAYS; 67 | } 68 | if (HOURS.convert(nanos, NANOSECONDS) > 0) { 69 | return HOURS; 70 | } 71 | if (MINUTES.convert(nanos, NANOSECONDS) > 0) { 72 | return MINUTES; 73 | } 74 | if (SECONDS.convert(nanos, NANOSECONDS) > 0) { 75 | return SECONDS; 76 | } 77 | if (MILLISECONDS.convert(nanos, NANOSECONDS) > 0) { 78 | return MILLISECONDS; 79 | } 80 | if (MICROSECONDS.convert(nanos, NANOSECONDS) > 0) { 81 | return MICROSECONDS; 82 | } 83 | return NANOSECONDS; 84 | } 85 | 86 | private static String abbreviate(TimeUnit unit) { 87 | switch (unit) { 88 | case NANOSECONDS: 89 | return "ns"; 90 | case MICROSECONDS: 91 | return "\u03bcs"; // μs 92 | case MILLISECONDS: 93 | return "ms"; 94 | case SECONDS: 95 | return "s"; 96 | case MINUTES: 97 | return "min"; 98 | case HOURS: 99 | return "h"; 100 | case DAYS: 101 | return "d"; 102 | default: 103 | throw new AssertionError(); 104 | } 105 | } 106 | 107 | } 108 | -------------------------------------------------------------------------------- /mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM 2 | @REM MIT License 3 | @REM 4 | @REM Copyright (c) 2017 Cloudogu GmbH 5 | @REM 6 | @REM Permission is hereby granted, free of charge, to any person obtaining a copy 7 | @REM of this software and associated documentation files (the "Software"), to deal 8 | @REM in the Software without restriction, including without limitation the rights 9 | @REM to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | @REM copies of the Software, and to permit persons to whom the Software is 11 | @REM furnished to do so, subject to the following conditions: 12 | @REM 13 | @REM The above copyright notice and this permission notice shall be included in all 14 | @REM copies or substantial portions of the Software. 15 | @REM 16 | @REM THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | @REM IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | @REM FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | @REM AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | @REM LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | @REM OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | @REM SOFTWARE. 23 | @REM 24 | 25 | @REM ---------------------------------------------------------------------------- 26 | @REM Maven2 Start Up Batch script 27 | @REM 28 | @REM Required ENV vars: 29 | @REM JAVA_HOME - location of a JDK home dir 30 | @REM 31 | @REM Optional ENV vars 32 | @REM M2_HOME - location of maven2's installed home dir 33 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 34 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending 35 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 36 | @REM e.g. to debug Maven itself, use 37 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 38 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 39 | @REM ---------------------------------------------------------------------------- 40 | 41 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 42 | @echo off 43 | @REM set title of command window 44 | title %0 45 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' 46 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 47 | 48 | @REM set %HOME% to equivalent of $HOME 49 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 50 | 51 | @REM Execute a user defined script before this one 52 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 53 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 54 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" 55 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" 56 | :skipRcPre 57 | 58 | @setlocal 59 | 60 | set ERROR_CODE=0 61 | 62 | @REM To isolate internal variables from possible post scripts, we use another setlocal 63 | @setlocal 64 | 65 | @REM ==== START VALIDATION ==== 66 | if not "%JAVA_HOME%" == "" goto OkJHome 67 | 68 | echo. 69 | echo Error: JAVA_HOME not found in your environment. >&2 70 | echo Please set the JAVA_HOME variable in your environment to match the >&2 71 | echo location of your Java installation. >&2 72 | echo. 73 | goto error 74 | 75 | :OkJHome 76 | if exist "%JAVA_HOME%\bin\java.exe" goto init 77 | 78 | echo. 79 | echo Error: JAVA_HOME is set to an invalid directory. >&2 80 | echo JAVA_HOME = "%JAVA_HOME%" >&2 81 | echo Please set the JAVA_HOME variable in your environment to match the >&2 82 | echo location of your Java installation. >&2 83 | echo. 84 | goto error 85 | 86 | @REM ==== END VALIDATION ==== 87 | 88 | :init 89 | 90 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 91 | @REM Fallback to current working directory if not found. 92 | 93 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 94 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 95 | 96 | set EXEC_DIR=%CD% 97 | set WDIR=%EXEC_DIR% 98 | :findBaseDir 99 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 100 | cd .. 101 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 102 | set WDIR=%CD% 103 | goto findBaseDir 104 | 105 | :baseDirFound 106 | set MAVEN_PROJECTBASEDIR=%WDIR% 107 | cd "%EXEC_DIR%" 108 | goto endDetectBaseDir 109 | 110 | :baseDirNotFound 111 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 112 | cd "%EXEC_DIR%" 113 | 114 | :endDetectBaseDir 115 | 116 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 117 | 118 | @setlocal EnableExtensions EnableDelayedExpansion 119 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 120 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 121 | 122 | :endReadAdditionalConfig 123 | 124 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 125 | 126 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" 127 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 128 | 129 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* 130 | if ERRORLEVEL 1 goto error 131 | goto end 132 | 133 | :error 134 | set ERROR_CODE=1 135 | 136 | :end 137 | @endlocal & set ERROR_CODE=%ERROR_CODE% 138 | 139 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost 140 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 141 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" 142 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" 143 | :skipRcPost 144 | 145 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 146 | if "%MAVEN_BATCH_PAUSE%" == "on" pause 147 | 148 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% 149 | 150 | exit /B %ERROR_CODE% 151 | -------------------------------------------------------------------------------- /mvnw: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # ---------------------------------------------------------------------------- 3 | # Licensed to the Apache Software Foundation (ASF) under one 4 | # or more contributor license agreements. See the NOTICE file 5 | # distributed with this work for additional information 6 | # regarding copyright ownership. The ASF licenses this file 7 | # to you under the Apache License, Version 2.0 (the 8 | # "License"); you may not use this file except in compliance 9 | # with the License. You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, 14 | # software distributed under the License is distributed on an 15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | # KIND, either express or implied. See the License for the 17 | # specific language governing permissions and limitations 18 | # under the License. 19 | # ---------------------------------------------------------------------------- 20 | 21 | # ---------------------------------------------------------------------------- 22 | # Maven2 Start Up Batch script 23 | # 24 | # Required ENV vars: 25 | # ------------------ 26 | # JAVA_HOME - location of a JDK home dir 27 | # 28 | # Optional ENV vars 29 | # ----------------- 30 | # M2_HOME - location of maven2's installed home dir 31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven 32 | # e.g. to debug Maven itself, use 33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files 35 | # ---------------------------------------------------------------------------- 36 | 37 | if [ -z "$MAVEN_SKIP_RC" ] ; then 38 | 39 | if [ -f /etc/mavenrc ] ; then 40 | . /etc/mavenrc 41 | fi 42 | 43 | if [ -f "$HOME/.mavenrc" ] ; then 44 | . "$HOME/.mavenrc" 45 | fi 46 | 47 | fi 48 | 49 | # OS specific support. $var _must_ be set to either true or false. 50 | cygwin=false; 51 | darwin=false; 52 | mingw=false 53 | case "`uname`" in 54 | CYGWIN*) cygwin=true ;; 55 | MINGW*) mingw=true;; 56 | Darwin*) darwin=true 57 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home 58 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html 59 | if [ -z "$JAVA_HOME" ]; then 60 | if [ -x "/usr/libexec/java_home" ]; then 61 | export JAVA_HOME="`/usr/libexec/java_home`" 62 | else 63 | export JAVA_HOME="/Library/Java/Home" 64 | fi 65 | fi 66 | ;; 67 | esac 68 | 69 | if [ -z "$JAVA_HOME" ] ; then 70 | if [ -r /etc/gentoo-release ] ; then 71 | JAVA_HOME=`java-config --jre-home` 72 | fi 73 | fi 74 | 75 | if [ -z "$M2_HOME" ] ; then 76 | ## resolve links - $0 may be a link to maven's home 77 | PRG="$0" 78 | 79 | # need this for relative symlinks 80 | while [ -h "$PRG" ] ; do 81 | ls=`ls -ld "$PRG"` 82 | link=`expr "$ls" : '.*-> \(.*\)$'` 83 | if expr "$link" : '/.*' > /dev/null; then 84 | PRG="$link" 85 | else 86 | PRG="`dirname "$PRG"`/$link" 87 | fi 88 | done 89 | 90 | saveddir=`pwd` 91 | 92 | M2_HOME=`dirname "$PRG"`/.. 93 | 94 | # make it fully qualified 95 | M2_HOME=`cd "$M2_HOME" && pwd` 96 | 97 | cd "$saveddir" 98 | # echo Using m2 at $M2_HOME 99 | fi 100 | 101 | # For Cygwin, ensure paths are in UNIX format before anything is touched 102 | if $cygwin ; then 103 | [ -n "$M2_HOME" ] && 104 | M2_HOME=`cygpath --unix "$M2_HOME"` 105 | [ -n "$JAVA_HOME" ] && 106 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 107 | [ -n "$CLASSPATH" ] && 108 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"` 109 | fi 110 | 111 | # For Mingw, ensure paths are in UNIX format before anything is touched 112 | if $mingw ; then 113 | [ -n "$M2_HOME" ] && 114 | M2_HOME="`(cd "$M2_HOME"; pwd)`" 115 | [ -n "$JAVA_HOME" ] && 116 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" 117 | # TODO classpath? 118 | fi 119 | 120 | if [ -z "$JAVA_HOME" ]; then 121 | javaExecutable="`which javac`" 122 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then 123 | # readlink(1) is not available as standard on Solaris 10. 124 | readLink=`which readlink` 125 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then 126 | if $darwin ; then 127 | javaHome="`dirname \"$javaExecutable\"`" 128 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" 129 | else 130 | javaExecutable="`readlink -f \"$javaExecutable\"`" 131 | fi 132 | javaHome="`dirname \"$javaExecutable\"`" 133 | javaHome=`expr "$javaHome" : '\(.*\)/bin'` 134 | JAVA_HOME="$javaHome" 135 | export JAVA_HOME 136 | fi 137 | fi 138 | fi 139 | 140 | if [ -z "$JAVACMD" ] ; then 141 | if [ -n "$JAVA_HOME" ] ; then 142 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 143 | # IBM's JDK on AIX uses strange locations for the executables 144 | JAVACMD="$JAVA_HOME/jre/sh/java" 145 | else 146 | JAVACMD="$JAVA_HOME/bin/java" 147 | fi 148 | else 149 | JAVACMD="`which java`" 150 | fi 151 | fi 152 | 153 | if [ ! -x "$JAVACMD" ] ; then 154 | echo "Error: JAVA_HOME is not defined correctly." >&2 155 | echo " We cannot execute $JAVACMD" >&2 156 | exit 1 157 | fi 158 | 159 | if [ -z "$JAVA_HOME" ] ; then 160 | echo "Warning: JAVA_HOME environment variable is not set." 161 | fi 162 | 163 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher 164 | 165 | # traverses directory structure from process work directory to filesystem root 166 | # first directory with .mvn subdirectory is considered project base directory 167 | find_maven_basedir() { 168 | 169 | if [ -z "$1" ] 170 | then 171 | echo "Path not specified to find_maven_basedir" 172 | return 1 173 | fi 174 | 175 | basedir="$1" 176 | wdir="$1" 177 | while [ "$wdir" != '/' ] ; do 178 | if [ -d "$wdir"/.mvn ] ; then 179 | basedir=$wdir 180 | break 181 | fi 182 | # workaround for JBEAP-8937 (on Solaris 10/Sparc) 183 | if [ -d "${wdir}" ]; then 184 | wdir=`cd "$wdir/.."; pwd` 185 | fi 186 | # end of workaround 187 | done 188 | echo "${basedir}" 189 | } 190 | 191 | # concatenates all lines of a file 192 | concat_lines() { 193 | if [ -f "$1" ]; then 194 | echo "$(tr -s '\n' ' ' < "$1")" 195 | fi 196 | } 197 | 198 | BASE_DIR=`find_maven_basedir "$(pwd)"` 199 | if [ -z "$BASE_DIR" ]; then 200 | exit 1; 201 | fi 202 | 203 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} 204 | if [ "$MVNW_VERBOSE" = true ]; then 205 | echo $MAVEN_PROJECTBASEDIR 206 | fi 207 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" 208 | 209 | # For Cygwin, switch paths to Windows format before running java 210 | if $cygwin; then 211 | [ -n "$M2_HOME" ] && 212 | M2_HOME=`cygpath --path --windows "$M2_HOME"` 213 | [ -n "$JAVA_HOME" ] && 214 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` 215 | [ -n "$CLASSPATH" ] && 216 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"` 217 | [ -n "$MAVEN_PROJECTBASEDIR" ] && 218 | MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` 219 | fi 220 | 221 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 222 | 223 | exec "$JAVACMD" \ 224 | $MAVEN_OPTS \ 225 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ 226 | "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ 227 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" 228 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # command-bus 2 | [![Build Status](https://oss.cloudogu.com/jenkins/buildStatus/icon?job=cloudogu-github/command-bus/master)](https://oss.cloudogu.com/jenkins/blue/organizations/jenkins/cloudogu-github%2Fcommand-bus/branches/) 3 | [![Quality Gates](https://sonarcloud.io/api/project_badges/measure?project=com.cloudogu.cb%3Acommand-bus-parent&metric=alert_status)](https://sonarcloud.io/dashboard?id=com.cloudogu.cb%3Acommand-bus-parent) 4 | [![Coverage](https://sonarcloud.io/api/project_badges/measure?project=com.cloudogu.cb%3Acommand-bus-parent&metric=coverage)](https://sonarcloud.io/dashboard?id=com.cloudogu.cb%3Acommand-bus-parent) 5 | [![Technical Debt](https://sonarcloud.io/api/project_badges/measure?project=com.cloudogu.cb%3Acommand-bus-parent&metric=sqale_index)](https://sonarcloud.io/dashboard?id=com.cloudogu.cb%3Acommand-bus-parent) 6 | 7 | CDI/Spring enabled Java Command-Bus 8 | 9 | # Table of contents 10 | 11 | 12 | 13 | 14 | 15 | - [Concepts](#concepts) 16 | - [Usage](#usage) 17 | - [Dependency for CDI](#dependency-for-cdi) 18 | - [Dependency for Spring](#dependency-for-spring) 19 | - [API](#api) 20 | - [Internals](#internals) 21 | - [Command Bus Decorators](#command-bus-decorators) 22 | - [Prometheus metric decorators](#prometheus-metric-decorators) 23 | - [PrometheusMetricsCountingCommandBus](#prometheusmetricscountingcommandbus) 24 | - [PrometheusMetricsTimingCommandBus](#prometheusmetricstimingcommandbus) 25 | - [Micrometer metric decorators](#micrometer-metric-decorators) 26 | - [MicrometerCountingCommandBus](#micrometercountingcommandbus) 27 | - [MicrometerTimingCommandBus](#micrometertimingcommandbus) 28 | - [Validating command bus](#validating-command-bus) 29 | - [Return values](#return-values) 30 | - [Examples](#examples) 31 | - [Spring](#spring) 32 | 33 | 34 | 35 | ## Concepts 36 | 37 | * [`Command`](command-bus-core/src/main/java/com/cloudogu/cb/Command.java) - Marker Interface 38 | * [`CommandHandler`](command-bus-core/src/main/java/com/cloudogu/cb/CommandHandler.java) - One Implementation per `Command`. Provides `handle(CommandImplementation)` Method. 39 | * [`CommandBus`](command-bus-core/src/main/java/com/cloudogu/cb/CommandBus.java) - Finds and calls the `CommandHandler` for each `Command`. 40 | * `CommandBus` can be decorated, in order to implement cross-cutting concerns, such as logging, transaction handling, validation, autorization, metrics etc. 41 | 42 | ## Usage 43 | 44 | Add the [latest stable version of command-bus](http://search.maven.org/#search|gav|1|g%3A%22com.cloudogu.cb%22%20AND%20a%3A%22command-bus-cdi%22) to the dependency management tool of your choice. 45 | You can also get snapshot versions from our [snapshot repository](https://oss.sonatype.org/content/repositories/snapshots/com/cloudogu/cb/) (for the most recent commit on develop branch). 46 | To do so, add the following repo to your `pom.xml` or `settings.xml`: 47 | ```xml 48 | 49 | snapshots-repo 50 | https://oss.sonatype.org/content/repositories/snapshots 51 | false 52 | true 53 | 54 | ``` 55 | 56 | There are different versions of command-bus for either CDI or spring. 57 | 58 | ### Dependency for CDI 59 | 60 | ```XML 61 | 62 | com.cloudogu.cb 63 | command-bus-cdi 64 | 1.0.1 65 | 66 | ``` 67 | 68 | [![Maven Central](https://img.shields.io/maven-central/v/com.cloudogu.cb/command-bus-cdi.svg)](https://search.maven.org/#search%7Cga%7C1%7Cg%3A%22com.cloudogu.cb%22%20AND%20a%3A%22command-bus-cdi%22) 69 | 70 | 71 | ### Dependency for Spring 72 | 73 | ```XML 74 | 75 | com.cloudogu.cb 76 | command-bus-spring 77 | 1.0.1 78 | 79 | ``` 80 | 81 | [![Maven Central](https://img.shields.io/maven-central/v/com.cloudogu.cb/command-bus-spring.svg)](https://search.maven.org/#search%7Cga%7C1%7Cg%3A%22com.cloudogu.cb%22%20AND%20a%3A%22command-bus-spring%22) 82 | 83 | ### API 84 | 85 | * Bootstrapping 86 | * CDI: Having the `command-bus-cdi` dependency on the classpath triggers the CDI extension 87 | * Spring: All CommandHandlers must be within the application context (e.g. `@Component` in spring boot) 88 | * Implement your [`Command`](command-bus-core/src/main/java/com/cloudogu/cb/Command.java)s and the logic in appropriate 89 | [`CommandHandler`](command-bus-core/src/main/java/com/cloudogu/cb/CommandHandler.java)s. 90 | * You can now just inject the [`CommandBus`](command-bus-core/src/main/java/com/cloudogu/cb/CommandBus.java) and pass your 91 | `Commands` to its `execute()` method. It will automatically pass it to the appropriate handler. 92 | * Examples: 93 | * [`CDIITCase`](command-bus-cdi/src/test/java/com/cloudogu/cb/cdi/CDIITCase.java) 94 | * [`SpringITCase`](command-bus-spring/src/test/java/com/cloudogu/cb/spring/SpringITCase.java) 95 | * If you want to decorate your command bus (for logging, metrics, etc.), a factory/producer for the `CommandBus` is the 96 | central place where decorators can be instantiated. 97 | It brings together your `CommandBus` (e.g. [`CDICommandBus`](command-bus-cdi/src/main/java/com/cloudogu/cb/cdi/CDICommandBus.java), 98 | [`SpringCommandBus`](command-bus-spring/src/main/java/com/cloudogu/cb/spring/SpringCommandBus.java)) with decorators 99 | (see [bellow](#command-bus-decorators)). 100 | Example `CommandBusFactory`s: 101 | * [CDI](command-bus-cdi/src/test/java/com/cloudogu/cb/cdi/CommandBusFactory.java) 102 | * [Spring](command-bus-spring/src/test/java/com/cloudogu/cb/spring/CommandBusFactory.java) 103 | 104 | ### Internals 105 | 106 | The `CommandHandler`s for CDI and Spring both use a `Registry` ([CDI](command-bus-cdi/src/main/java/com/cloudogu/cb/cdi/Registry.java) / 107 | [Spring](command-bus-spring/src/main/java/com/cloudogu/cb/spring/Registry.java)) to store `Command`s and 108 | `CommandHandler`s. Difference: 109 | * CDI: The [`CDIExtension`](command-bus-cdi/src/main/java/com/cloudogu/cb/cdi/CDIExtension.java) finds all `Command`s 110 | and `CommandHandler`s and puts them on the `Registry`. 111 | * Spring: The `Registry` itself gets all `Command`s and `CommandHandler`s from the application context. 112 | 113 | ## Command Bus Decorators 114 | 115 | First example is the logging decorator ([`LoggingCommandBus`](command-bus-core/src/main/java/com/cloudogu/cb/decorator/LoggingCommandBus.java)) that logs entering and leaving (including time of execution) of `CommandHandler`s. 116 | 117 | ### Prometheus metric decorators 118 | The Command Bus provides two Prometheus metrics decorators. More information on Prometheus can be found on the 119 | project's [website](https://prometheus.io). 120 | In order to use them, make sure to provide the `io.prometheus:simpleclient` dependency on the classpath. 121 | 122 | #### PrometheusMetricsCountingCommandBus 123 | The `PrometheusMetricsCountingCommandBus` counts every executed command, using a Prometheus Counter. 124 | The counter to be used must be provided as a constructor parameter. For each type of command (i.e. it's class name) a 125 | label is created automatically. 126 | 127 | #### PrometheusMetricsTimingCommandBus 128 | The `PrometheusMetricsTimingCommandBus` captures the time a command's execution takes and provides the metric as a 129 | Prometheus Histogram. Similarly to the `PrometheusMetricsCountingCommandBus`, the Histogram needs to be provided as a 130 | constructor parameter. 131 | 132 | ### Micrometer metric decorators 133 | The Command Bus provides two Micrometer metrics decorators. More information on Micrometer can be found on the 134 | project's [website](https://micrometer.io). 135 | In order to use them, make sure to provide a micrometer registry implementation such as prometheus `io.micrometer:micrometer-registry-prometheus`. 136 | 137 | See [cloudogu/springboot-micrometer-demo-command-bus](cloudogu/springboot-micrometer-demo-command-bus) for a complete example. 138 | 139 | #### MicrometerCountingCommandBus 140 | 141 | The `MicrometerCountingCommandBus` counts every executed command, using a Micrometer Counter e.g.: 142 | 143 | ```java 144 | CommandBus commandBusImpl = ...; 145 | MicrometerCountingCommandBus commandBus = new MicrometerCountingCommandBus(commandBusImpl, 146 | commandClass -> Counter.builder("command.counter") 147 | .description("command execution counter") 148 | .tags("command", commandClass.getSimpleName()) 149 | .register(Metrics.globalRegistry) 150 | ); 151 | ``` 152 | 153 | #### MicrometerTimingCommandBus 154 | 155 | The `MicrometerTimingCommandBus` measures the elapsed time for every command execution by using a Micrometer a Micrometer Counter e.g.: 156 | 157 | ```java 158 | CommandBus commandBusImpl = ...; 159 | MicrometerTimingCommandBus commandBus = new MicrometerTimingCommandBus(commandBusImpl, 160 | commandClass -> Timer.builder("command.timer") 161 | .description("command execution timer") 162 | .tags("command", commandClass.getSimpleName()) 163 | .register(Metrics.globalRegistry) 164 | ); 165 | ``` 166 | 167 | ### Validating command bus 168 | The `ValidatingCommandBus` uses the `javax.validation` API to validate the command, before execution. 169 | The `CommandBus` will throw an `ConstraintViolationException`, if the command violates validation rules. 170 | Make sure to provide `javax.validation` implementation at runtime, such as `org.hibernate:hibernate-validator`. 171 | 172 | ```java 173 | public class NotifyCommand implements Command { 174 | @Email 175 | private String email; 176 | 177 | public SampleCommand(String email) { 178 | this.email = email; 179 | } 180 | } 181 | 182 | CommandBus commandBusImpl = ...; 183 | ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); 184 | ValidatingCommandBus commandBus = new ValidatingCommandBus(commandBusImpl, factory.getValidator()); 185 | NotifyCommand command = createNotifyCommand(); 186 | commandBus.execute(command); 187 | ``` 188 | 189 | ## Return values 190 | 191 | * `Command`s can specify return values. See [`HelloCommand`](command-bus-cdi/src/test/java/com/cloudogu/cb/HelloCommand.java) and [`com.cloudogu.cb.EchoCommandHandler`](command-bus-cdi/src/test/java/com/cloudogu/cb/HelloCommandHandler.java) for example. 192 | * If you don't want a return value, use `Void`. See [`ByeCommand`](command-bus-cdi/src/test/java/com/cloudogu/cb/ByeCommand.java) and [`ByeCommandHandler`](command-bus-cdi/src/test/java/com/cloudogu/cb/ByeCommandHandler.java) for example. 193 | 194 | # Examples 195 | 196 | ## Spring 197 | 198 | * [cloudogu/smeagol](https://github.com/cloudogu/smeagol) 199 | * [cloudogu/springboot-micrometer-demo-command-bus](https://github.com/cloudogu/springboot-micrometer-demo-command-bus) 200 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 27 | 28 | 29 | 4.0.0 30 | 31 | com.cloudogu.cb 32 | command-bus-parent 33 | 2.0.1-SNAPSHOT 34 | 35 | command-bus 36 | CDI enabled Java Command-Bus 37 | 38 | 39 | command-bus-core 40 | command-bus-spring 41 | command-bus-cdi 42 | 43 | 44 | pom 45 | 46 | https://github.com/cloudogu/command-bus 47 | 48 | 49 | 50 | MIT License 51 | https://github.com/cloudogu/command-bus/blob/master/LICENSE 52 | 53 | 54 | 55 | 2017 56 | 57 | 58 | Cloudogu GmbH 59 | https://cloudogu.com/ 60 | 61 | 62 | 63 | 64 | 65 | Sebastian Sdorra 66 | sebastian.sdorra@cloudogu.com 67 | Cloudogu GmbH 68 | https://cloudogu.com/ 69 | Europe/Berlin 70 | 71 | 72 | 73 | Philipp Czora 74 | philipp.czora@cloudogu.com 75 | Cloudogu GmbH 76 | https://cloudogu.com/ 77 | Europe/Berlin 78 | 79 | 80 | 81 | Johannes Schnatterer 82 | johannes.schnatterer@cloudogu.com 83 | Cloudogu GmbH 84 | https://cloudogu.com/ 85 | Europe/Berlin 86 | 87 | 88 | 89 | 90 | 91 | scm:git:https://github.com/cloudogu/command-bus 92 | scm:git:https://github.com/cloudogu/command-bus 93 | https://github.com/cloudogu/command-bus.git 94 | HEAD 95 | 96 | 97 | 98 | GitHub 99 | https://github.com/cloudogu/command-bus/issues 100 | 101 | 102 | 103 | 104 | ossrh 105 | https://oss.sonatype.org/content/repositories/snapshots 106 | 107 | 108 | ossrh 109 | https://oss.sonatype.org/service/local/staging/deploy/maven2/ 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | org.slf4j 118 | slf4j-api 119 | 1.7.25 120 | 121 | 122 | 123 | junit 124 | junit 125 | 4.13.1 126 | test 127 | 128 | 129 | 130 | org.mockito 131 | mockito-core 132 | 2.28.2 133 | test 134 | 135 | 136 | 137 | org.assertj 138 | assertj-core 139 | 3.8.0 140 | test 141 | 142 | 143 | 144 | com.github.schnatterer 145 | logback-spike 146 | 1.0.0 147 | test 148 | 149 | 150 | 151 | org.slf4j 152 | slf4j-ext 153 | 1.7.26 154 | test 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | ${project.groupId} 165 | command-bus-core 166 | ${project.version} 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | org.apache.maven.plugins 178 | maven-compiler-plugin 179 | 3.6.1 180 | 181 | 182 | 183 | org.apache.maven.plugins 184 | maven-release-plugin 185 | 2.5.3 186 | 187 | 188 | @{project.version} 189 | 190 | release 191 | 192 | 193 | 194 | 195 | org.apache.maven.plugins 196 | maven-deploy-plugin 197 | 2.8.2 198 | 199 | 200 | 201 | maven-surefire-plugin 202 | 3.0.0-M3 203 | 204 | 206 | ${skipUnitTests} 207 | 3 208 | true 209 | -Xmx1024m -XX:MaxPermSize=256m 210 | 211 | 212 | 213 | 214 | 215 | com.mycila 216 | license-maven-plugin 217 | 3.0 218 | 219 |
LICENSE
220 | 221 | LICENSE 222 | Jenkinsfile 223 | 224 |
225 | 226 | 227 | 228 | 229 | check 230 | 231 | 232 | 233 |
234 | 235 | 236 | org.apache.maven.plugins 237 | maven-failsafe-plugin 238 | 2.17 239 | 240 | 241 | 242 | integration-test 243 | verify 244 | 245 | 246 | 247 | 248 | -Xmx1024m -XX:MaxPermSize=256m 249 | 250 | 251 | 252 |
253 |
254 | 255 | 256 | 257 | jitpack.io 258 | https://jitpack.io 259 | 260 | 261 | 262 | 263 | UTF-8 264 | UTF-8 265 | 266 | 1.8 267 | 1.8 268 | 269 | 271 | ${skipTests} 272 | 273 | 274 | 275 | 276 | 277 | jenkins 278 | 279 | 280 | 281 | env.BUILD_URL 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | org.jacoco 291 | jacoco-maven-plugin 292 | 0.7.9 293 | 294 | 295 | initialize 296 | 297 | prepare-agent 298 | 299 | 300 | 301 | agent-for-it 302 | 303 | prepare-agent-integration 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | release 314 | 315 | 316 | 317 | 318 | org.apache.maven.plugins 319 | maven-source-plugin 320 | 3.0.1 321 | 322 | 323 | attach-sources 324 | 325 | jar-no-fork 326 | 327 | 328 | 329 | 330 | 331 | 332 | org.apache.maven.plugins 333 | maven-javadoc-plugin 334 | 2.10.4 335 | 336 | 337 | attach-javadocs 338 | 339 | jar 340 | 341 | 342 | 343 | 344 | 345 | 346 | org.sonatype.plugins 347 | nexus-staging-maven-plugin 348 | 1.6.8 349 | true 350 | 351 | ossrh 352 | https://oss.sonatype.org/ 353 | true 354 | 355 | 356 | 357 | 358 | org.apache.maven.plugins 359 | maven-gpg-plugin 360 | 1.6 361 | 362 | 363 | sign-artifacts 364 | verify 365 | 366 | sign 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 |
--------------------------------------------------------------------------------