{"id":2526,"date":"2025-12-23T10:00:11","date_gmt":"2025-12-23T15:00:11","guid":{"rendered":"http:\/\/www.mymiller.name\/wordpress\/?p=2526"},"modified":"2025-12-23T10:00:11","modified_gmt":"2025-12-23T15:00:11","slug":"pipeline-switches","status":"publish","type":"post","link":"https:\/\/www.mymiller.name\/wordpress\/pipelines\/pipeline-switches\/","title":{"rendered":"Pipeline Switches"},"content":{"rendered":"\n<p>One of the things that make pipelines attract is the ability to create switches.  Now my question to you is what if it isn&#8217;t the data your processing that should determine if a switch pushes the data down an alternate pipeline?  We have several methods that perform this task<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li> filter() filter out objects based on the Predicate(). <\/li><li> switchIf() switch the data to different Pipeline if the Predicate indicates it should. <\/li><\/ul>\n\n\n\n<p>These methods on the pipeline allow a predicate to control their behavior.  Typically the predicate would take in the data being processed and make a determination based on the data.  However since we want a remote entity to control the decision, the data is passed in and ignored.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">RemoteSwitch<\/h2>\n\n\n\n<p>RemoteSwitch is a simple class that implements the Predicate() function.  However it maintains an internal boolean to indicate whether to allow the object to pass. A simple switch or entire another block of code can have a reference to this object and be able to effect the processing of the data in the pipeline.  Calling the setEnabled() method on the switch with a boolean parameter will turn on\/off switch.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package name.mymiller.extensions.utils.pipelines.switches;\n\nimport java.util.function.Predicate;\n\n\/**\n * @author jmiller Class used to remote enable\/disable the predicate for use in\n *         pipeline switches.\n *\/\npublic class RemoteSwitch implements Predicate {\n\n\tprivate boolean enabled = false;\n\n\t\/**\n\t * Default Constructor specifying the switch is disabled.\n\t *\/\n\tpublic RemoteSwitch() {\n\t\tthis(false);\n\t}\n\n\t\/**\n\t * Constructor to specify initial setting for the switch\n\t *\n\t * @param enabled\n\t *            boolean indicating if the swithc is enabled or disabled.\n\t *\/\n\tpublic RemoteSwitch(boolean enabled) {\n\t\tsuper();\n\t\tthis.enabled = enabled;\n\t}\n\n\t\/**\n\t * @return the enabled\n\t *\/\n\tpublic synchronized boolean isEnabled() {\n\t\treturn this.enabled;\n\t}\n\n\t\/**\n\t * @param enabled\n\t *            the enabled to set\n\t *\/\n\tpublic synchronized void setEnabled(boolean enabled) {\n\t\tthis.enabled = enabled;\n\t}\n\n\t@Override\n\tpublic boolean test(Object t) {\n\t\treturn this.isEnabled();\n\t}\n\n}\n<\/code><\/pre>\n\n\n\n<p>This is a simple instance, that could be used in Java code base.   This could be extended easily based on your needs.  The ability to pass in your own Predicate gives you the ability to construct a wide range of abilities into your code.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">AbstractPropertyChangeListenerSwitch<\/h2>\n\n\n\n<p>First thing I just love long descriptive names for my classes, don&#8217;t you?  Now then sometimes we want to automate our switch even a bit more.  Why not tie in a PropertyChangeListner into our switch?  Now I made this one abstract to give you a bit of flexibility here to make this work the way you want.  Maybe this is a simple boolean flag on a listener, or maybe it&#8217;s more complete based on the value passed in and processing the incoming pipeline data against that value to determine to switch or not.  Really this is more to show you the wide range of things you can do here.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>package name.mymiller.extensions.utils.pipelines.switches;\n\nimport java.beans.PropertyChangeEvent;\nimport java.beans.PropertyChangeListener;\nimport java.util.function.Predicate;\n\n\/**\n * @author jmiller\n *\n *\/\npublic abstract class AbstractPropertyChangeListenerSwitch&lt;T> implements Predicate&lt;T>, PropertyChangeListener {\n\n\tprivate String propertyName;\n\n\tprivate Object\tnewValue;\n\tprivate Object\tsource;\n\tprivate Object\toldValue;\n\n\t\/**\n\t * @param propertyName\n\t * @param newValue\n\t * @param source\n\t * @param oldValue\n\t *\/\n\tpublic AbstractPropertyChangeListenerSwitch(String propertyName, Object newValue, Object source, Object oldValue) {\n\t\tsuper();\n\t\tthis.propertyName = propertyName;\n\t\tthis.newValue = newValue;\n\t\tthis.source = source;\n\t\tthis.oldValue = oldValue;\n\t}\n\n\t\/**\n\t * @return the newValue\n\t *\/\n\tprotected synchronized Object getNewValue() {\n\t\treturn this.newValue;\n\t}\n\n\t\/**\n\t * @return the oldValue\n\t *\/\n\tprotected synchronized Object getOldValue() {\n\t\treturn this.oldValue;\n\t}\n\n\t\/**\n\t * @return the propertyName\n\t *\/\n\tprotected synchronized String getPropertyName() {\n\t\treturn this.propertyName;\n\t}\n\n\t\/**\n\t * @return the source\n\t *\/\n\tprotected synchronized Object getSource() {\n\t\treturn this.source;\n\t}\n\n\t\/*\n\t * (non-Javadoc)\n\t *\n\t * @see java.beans.PropertyChangeListener#propertyChange(java.beans.\n\t * PropertyChangeEvent)\n\t *\/\n\t@Override\n\tpublic void propertyChange(PropertyChangeEvent evt) {\n\t\tthis.propertyName = evt.getPropertyName();\n\t\tthis.newValue = evt.getNewValue();\n\t\tthis.source = evt.getSource();\n\t\tthis.oldValue = evt.getOldValue();\n\t}\n\n}\n<\/code><\/pre>\n\n\n\n<p>The entire point here is to try to persuade you to think outside of the box.  The flexibility here is only as great as your imagination.  I believe you will find the pipeline tools here to be extremely flexible and a great development tool for you to use.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>One of the things that make pipelines attract is the ability to create switches. Now my question to you is what if it isn&#8217;t the data your processing that should determine if a switch pushes the data down an alternate pipeline? We have several methods that perform this task filter() filter out objects based on [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":2529,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_coblocks_attr":"","_coblocks_dimensions":"","_coblocks_responsive_height":"","_coblocks_accordion_ie_support":"","jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[453],"tags":[69],"series":[271],"class_list":["post-2526","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-pipelines","tag-java-2","series-pipelines"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2019\/03\/railway-station-1270893_640.jpg?fit=640%2C384&ssl=1","jetpack-related-posts":[{"id":2473,"url":"https:\/\/www.mymiller.name\/wordpress\/pipelines\/java-pipelines\/","url_meta":{"origin":2526,"position":0},"title":"Java Pipelines","author":"Jeffery Miller","date":"December 23, 2025","format":false,"excerpt":"Java streams introduced a new way to program for developers. Have a dataset and build a stream to filter, it maps it, and then collect it in the new form. This gave developers a powerful tool to use in development and data processing. I can't even begin to say how\u2026","rel":"","context":"In &quot;Pipelines&quot;","block_context":{"text":"Pipelines","link":"https:\/\/www.mymiller.name\/wordpress\/category\/pipelines\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2019\/03\/machine-495376_640.jpg?fit=640%2C426&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2019\/03\/machine-495376_640.jpg?fit=640%2C426&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2019\/03\/machine-495376_640.jpg?fit=640%2C426&ssl=1&resize=525%2C300 1.5x"},"classes":[]},{"id":3671,"url":"https:\/\/www.mymiller.name\/wordpress\/spring_ai\/spring-cloud-data-flow-orchestrating-machine-learning-pipelines\/","url_meta":{"origin":2526,"position":1},"title":"Spring Cloud Data Flow: Orchestrating Machine Learning Pipelines","author":"Jeffery Miller","date":"December 24, 2025","format":false,"excerpt":"In the dynamic world of machine learning, the journey from raw data to a deployed model involves a series of intricate steps. Spring Cloud Data Flow (SCDF) emerges as a powerful ally, offering a comprehensive platform to streamline and manage these complex data pipelines. In this guide, we\u2019ll delve into\u2026","rel":"","context":"In &quot;Spring AI&quot;","block_context":{"text":"Spring AI","link":"https:\/\/www.mymiller.name\/wordpress\/category\/spring_ai\/"},"img":{"alt_text":"","src":"https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/09\/ai-generated-8411275_1280-jpg.avif","width":350,"height":200,"srcset":"https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/09\/ai-generated-8411275_1280-jpg.avif 1x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/09\/ai-generated-8411275_1280-jpg.avif 1.5x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/09\/ai-generated-8411275_1280-jpg.avif 2x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2024\/09\/ai-generated-8411275_1280-jpg.avif 3x"},"classes":[]},{"id":3951,"url":"https:\/\/www.mymiller.name\/wordpress\/java\/scaling-streams-mastering-virtual-threads-in-spring-boot-4-and-java-25\/","url_meta":{"origin":2526,"position":2},"title":"Scaling Streams: Mastering Virtual Threads in Spring Boot 4 and Java 25","author":"Jeffery Miller","date":"December 22, 2025","format":false,"excerpt":"As a software architect, I\u2019ve seen the industry shift from heavy platform threads to reactive streams, and finally to the \"best of both worlds\": Virtual Threads. With the recent release of Spring Boot 4.0 and Java 25 (LTS), Project Loom's innovations have officially become the bedrock of high-concurrency enterprise Java.\u2026","rel":"","context":"In &quot;JAVA&quot;","block_context":{"text":"JAVA","link":"https:\/\/www.mymiller.name\/wordpress\/category\/java\/"},"img":{"alt_text":"","src":"https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/12\/Gemini_Generated_Image_wqijejwqijejwqij-scaled.avif","width":350,"height":200,"srcset":"https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/12\/Gemini_Generated_Image_wqijejwqijejwqij-scaled.avif 1x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/12\/Gemini_Generated_Image_wqijejwqijejwqij-scaled.avif 1.5x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/12\/Gemini_Generated_Image_wqijejwqijejwqij-scaled.avif 2x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/12\/Gemini_Generated_Image_wqijejwqijejwqij-scaled.avif 3x"},"classes":[]},{"id":3890,"url":"https:\/\/www.mymiller.name\/wordpress\/spring_messaging\/spring-cloud-stream\/","url_meta":{"origin":2526,"position":3},"title":"Spring Cloud Stream","author":"Jeffery Miller","date":"December 24, 2025","format":false,"excerpt":"Spring Cloud Stream is a framework for building highly scalable, event-driven microservices that are connected by a shared messaging system. In simple terms, it's a powerful tool that takes away the complexity of communicating with message brokers like RabbitMQ or Apache Kafka, allowing you to focus purely on your application's\u2026","rel":"","context":"In &quot;Spring Messaging&quot;","block_context":{"text":"Spring Messaging","link":"https:\/\/www.mymiller.name\/wordpress\/category\/spring_messaging\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2023\/11\/network-3152677_640.jpg?fit=640%2C427&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2023\/11\/network-3152677_640.jpg?fit=640%2C427&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2023\/11\/network-3152677_640.jpg?fit=640%2C427&ssl=1&resize=525%2C300 1.5x"},"classes":[]},{"id":3340,"url":"https:\/\/www.mymiller.name\/wordpress\/lambda_stream\/java-collectors\/","url_meta":{"origin":2526,"position":4},"title":"Java Collectors","author":"Jeffery Miller","date":"December 24, 2025","format":false,"excerpt":"Java 8 introduced the Collectors class, which provides a variety of collectors for use with streams. Collectors are used to accumulate the elements of a stream into a single result, such as a list or a map. In this article, we'll take a closer look at the Collectors class and\u2026","rel":"","context":"In &quot;Lambda's and Streams&quot;","block_context":{"text":"Lambda's and Streams","link":"https:\/\/www.mymiller.name\/wordpress\/category\/lambda_stream\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2023\/06\/data-g271bb8554_640.jpg?fit=640%2C285&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2023\/06\/data-g271bb8554_640.jpg?fit=640%2C285&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2023\/06\/data-g271bb8554_640.jpg?fit=640%2C285&ssl=1&resize=525%2C300 1.5x"},"classes":[]},{"id":3893,"url":"https:\/\/www.mymiller.name\/wordpress\/spring_ai\/building-intelligent-apps-with-spring-ai\/","url_meta":{"origin":2526,"position":5},"title":"Building Intelligent Apps with Spring AI","author":"Jeffery Miller","date":"December 24, 2025","format":false,"excerpt":"In today's fast-paced world of software development, integrating artificial intelligence into applications is no longer just a trend\u2014it's a necessity. At the heart of this revolution is Generative AI, a type of artificial intelligence that can create new content, such as text, images, and code, in response to prompts. It's\u2026","rel":"","context":"In &quot;Spring AI&quot;","block_context":{"text":"Spring AI","link":"https:\/\/www.mymiller.name\/wordpress\/category\/spring_ai\/"},"img":{"alt_text":"","src":"https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/08\/ai-generated-8273796_1280.avif","width":350,"height":200,"srcset":"https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/08\/ai-generated-8273796_1280.avif 1x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/08\/ai-generated-8273796_1280.avif 1.5x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/08\/ai-generated-8273796_1280.avif 2x, https:\/\/www.mymiller.name\/wordpress\/wp-content\/uploads\/2025\/08\/ai-generated-8273796_1280.avif 3x"},"classes":[]}],"jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"_links":{"self":[{"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/posts\/2526","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/comments?post=2526"}],"version-history":[{"count":2,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/posts\/2526\/revisions"}],"predecessor-version":[{"id":2528,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/posts\/2526\/revisions\/2528"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/media\/2529"}],"wp:attachment":[{"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/media?parent=2526"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/categories?post=2526"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/tags?post=2526"},{"taxonomy":"series","embeddable":true,"href":"https:\/\/www.mymiller.name\/wordpress\/wp-json\/wp\/v2\/series?post=2526"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}