2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2019-2020 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.onap.policy.drools.controller.internal;
23 import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
24 import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
25 import static org.junit.Assert.assertEquals;
26 import static org.junit.Assert.assertFalse;
27 import static org.junit.Assert.assertNotNull;
28 import static org.junit.Assert.assertSame;
29 import static org.junit.Assert.assertTrue;
30 import static org.mockito.ArgumentMatchers.any;
31 import static org.mockito.Mockito.doThrow;
32 import static org.mockito.Mockito.mock;
33 import static org.mockito.Mockito.never;
34 import static org.mockito.Mockito.times;
35 import static org.mockito.Mockito.verify;
36 import static org.mockito.Mockito.when;
38 import java.util.Arrays;
39 import java.util.Collections;
40 import java.util.List;
42 import java.util.TreeMap;
43 import org.junit.Before;
44 import org.junit.Test;
45 import org.kie.api.KieBase;
46 import org.kie.api.definition.KiePackage;
47 import org.kie.api.definition.rule.Query;
48 import org.kie.api.runtime.KieContainer;
49 import org.kie.api.runtime.KieSession;
50 import org.kie.api.runtime.rule.FactHandle;
51 import org.kie.api.runtime.rule.QueryResults;
52 import org.kie.api.runtime.rule.QueryResultsRow;
53 import org.mockito.ArgumentCaptor;
54 import org.mockito.Mock;
55 import org.mockito.MockitoAnnotations;
56 import org.onap.policy.common.endpoints.event.comm.TopicSink;
57 import org.onap.policy.common.utils.services.OrderedServiceImpl;
58 import org.onap.policy.drools.core.PolicyContainer;
59 import org.onap.policy.drools.core.PolicySession;
60 import org.onap.policy.drools.features.DroolsControllerFeatureApi;
61 import org.onap.policy.drools.features.DroolsControllerFeatureApiConstants;
62 import org.onap.policy.drools.protocol.coders.EventProtocolCoder;
63 import org.onap.policy.drools.protocol.coders.EventProtocolCoderConstants;
64 import org.onap.policy.drools.protocol.coders.EventProtocolParams;
65 import org.onap.policy.drools.protocol.coders.JsonProtocolFilter;
66 import org.onap.policy.drools.protocol.coders.TopicCoderFilterConfiguration;
67 import org.onap.policy.drools.protocol.coders.TopicCoderFilterConfiguration.CustomGsonCoder;
68 import org.onap.policy.drools.protocol.coders.TopicCoderFilterConfiguration.PotentialCoderFilter;
70 public class MavenDroolsController2Test {
71 private static final int FACT1_OBJECT = 1000;
72 private static final int FACT3_OBJECT = 1001;
74 private static final long FACT_COUNT = 200L;
76 private static final String EXPECTED_EXCEPTION = "expected exception";
77 private static final RuntimeException RUNTIME_EX = new RuntimeException(EXPECTED_EXCEPTION);
78 private static final IllegalArgumentException ARG_EX = new IllegalArgumentException(EXPECTED_EXCEPTION);
80 private static final String UNKNOWN_CLASS = "unknown class";
82 private static final String GROUP = "my-group";
83 private static final String ARTIFACT = "my-artifact";
84 private static final String VERSION = "my-version";
86 private static final String GROUP2 = "my-groupB";
87 private static final String ARTIFACT2 = "my-artifactB";
88 private static final String VERSION2 = "my-versionB";
90 private static final String TOPIC = "my-topic";
91 private static final String TOPIC2 = "my-topic";
93 private static final ClassLoader CLASS_LOADER = MavenDroolsController2Test.class.getClassLoader();
94 private static final int CLASS_LOADER_HASHCODE = CLASS_LOADER.hashCode();
96 private static final String SESSION1 = "session-A";
97 private static final String SESSION2 = "session-B";
98 private static final String FULL_SESSION1 = "full-A";
99 private static final String FULL_SESSION2 = "full-B";
101 private static final String EVENT_TEXT = "my-event-text";
102 private static final Object EVENT = new Object();
104 private static final String QUERY = "my-query";
105 private static final String QUERY2 = "my-query-B";
106 private static final String ENTITY = "my-entity";
107 private static final Object PARM1 = "parmA";
108 private static final Object PARM2 = "parmB";
111 private EventProtocolCoder coderMgr;
113 private DroolsControllerFeatureApi prov1;
115 private DroolsControllerFeatureApi prov2;
117 private OrderedServiceImpl<DroolsControllerFeatureApi> droolsProviders;
119 private TopicCoderFilterConfiguration decoder1;
121 private TopicCoderFilterConfiguration decoder2;
123 private TopicCoderFilterConfiguration encoder1;
125 private TopicCoderFilterConfiguration encoder2;
127 private PolicyContainer container;
129 private CustomGsonCoder gson1;
131 private CustomGsonCoder gson2;
133 private PotentialCoderFilter filter1a;
135 private JsonProtocolFilter jsonFilter1a;
137 private PotentialCoderFilter filter1b;
139 private JsonProtocolFilter jsonFilter1b;
141 private PotentialCoderFilter filter2;
143 private JsonProtocolFilter jsonFilter2;
145 private PolicySession sess1;
147 private PolicySession sess2;
149 private KieSession kieSess;
151 private KieSession kieSess2;
153 private TopicSink sink;
155 private FactHandle fact1;
157 private FactHandle fact2;
159 private FactHandle fact3;
161 private FactHandle factex;
163 private KieBase kieBase;
165 private KiePackage pkg1;
167 private KiePackage pkg2;
169 private Query query1;
171 private Query query2;
173 private Query query3;
175 private QueryResults queryResults;
177 private QueryResultsRow row1;
179 private QueryResultsRow row2;
181 private List<TopicCoderFilterConfiguration> decoders;
182 private List<TopicCoderFilterConfiguration> encoders;
184 private MavenDroolsController drools;
187 * Initializes objects, including the drools controller.
190 public void setUp() {
191 MockitoAnnotations.initMocks(this);
193 when(droolsProviders.getList()).thenReturn(Arrays.asList(prov1, prov2));
195 when(coderMgr.isDecodingSupported(GROUP, ARTIFACT, TOPIC)).thenReturn(true);
196 when(coderMgr.decode(GROUP, ARTIFACT, TOPIC, EVENT_TEXT)).thenReturn(EVENT);
198 when(kieSess.getFactCount()).thenReturn(FACT_COUNT);
199 when(kieSess.getFactHandles()).thenReturn(Arrays.asList(fact1, fact2, factex, fact3));
200 when(kieSess.getFactHandles(any())).thenReturn(Arrays.asList(fact1, fact3));
201 when(kieSess.getKieBase()).thenReturn(kieBase);
202 when(kieSess.getQueryResults(QUERY, PARM1, PARM2)).thenReturn(queryResults);
204 when(kieSess.getObject(fact1)).thenReturn(FACT1_OBJECT);
205 when(kieSess.getObject(fact2)).thenReturn("");
206 when(kieSess.getObject(fact3)).thenReturn(FACT3_OBJECT);
207 when(kieSess.getObject(factex)).thenThrow(RUNTIME_EX);
209 when(kieSess2.getFactHandles()).thenReturn(Collections.emptyList());
211 when(kieBase.getKiePackages()).thenReturn(Arrays.asList(pkg1, pkg2));
213 when(pkg1.getQueries()).thenReturn(Arrays.asList(query3));
214 when(pkg2.getQueries()).thenReturn(Arrays.asList(query2, query1));
216 when(query1.getName()).thenReturn(QUERY);
217 when(query2.getName()).thenReturn(QUERY2);
219 when(queryResults.iterator()).thenReturn(Arrays.asList(row1, row2).iterator());
221 when(row1.get(ENTITY)).thenReturn(FACT1_OBJECT);
222 when(row2.get(ENTITY)).thenReturn(FACT3_OBJECT);
224 when(row1.getFactHandle(ENTITY)).thenReturn(fact1);
225 when(row2.getFactHandle(ENTITY)).thenReturn(fact3);
227 when(sess1.getKieSession()).thenReturn(kieSess);
228 when(sess2.getKieSession()).thenReturn(kieSess2);
230 when(sess1.getName()).thenReturn(SESSION1);
231 when(sess2.getName()).thenReturn(SESSION2);
233 when(sess1.getFullName()).thenReturn(FULL_SESSION1);
234 when(sess2.getFullName()).thenReturn(FULL_SESSION2);
236 when(container.getClassLoader()).thenReturn(CLASS_LOADER);
237 when(container.getPolicySessions()).thenReturn(Arrays.asList(sess1, sess2));
238 when(container.insertAll(EVENT)).thenReturn(true);
240 when(decoder1.getTopic()).thenReturn(TOPIC);
241 when(decoder2.getTopic()).thenReturn(TOPIC2);
243 when(encoder1.getTopic()).thenReturn(TOPIC);
244 when(encoder2.getTopic()).thenReturn(TOPIC2);
246 decoders = Arrays.asList(decoder1, decoder2);
247 encoders = Arrays.asList(encoder1, encoder2);
249 when(decoder1.getCustomGsonCoder()).thenReturn(gson1);
250 when(encoder2.getCustomGsonCoder()).thenReturn(gson2);
252 when(filter1a.getCodedClass()).thenReturn(Object.class.getName());
253 when(filter1a.getFilter()).thenReturn(jsonFilter1a);
255 when(filter1b.getCodedClass()).thenReturn(String.class.getName());
256 when(filter1b.getFilter()).thenReturn(jsonFilter1b);
258 when(filter2.getCodedClass()).thenReturn(Integer.class.getName());
259 when(filter2.getFilter()).thenReturn(jsonFilter2);
261 when(decoder1.getCoderFilters()).thenReturn(Arrays.asList(filter1a, filter1b));
262 when(decoder2.getCoderFilters()).thenReturn(Collections.emptyList());
264 when(encoder1.getCoderFilters()).thenReturn(Collections.emptyList());
265 when(encoder2.getCoderFilters()).thenReturn(Arrays.asList(filter2));
267 when(sink.getTopic()).thenReturn(TOPIC);
268 when(sink.send(EVENT_TEXT)).thenReturn(true);
270 drools = new MyDrools(GROUP, ARTIFACT, VERSION, null, null);
272 when(coderMgr.encode(TOPIC, EVENT, drools)).thenReturn(EVENT_TEXT);
276 public void testMavenDroolsController_InvalidArgs() {
277 assertThatIllegalArgumentException().isThrownBy(() -> new MyDrools(null, ARTIFACT, VERSION, null, null))
278 .withMessageContaining("group");
279 assertThatIllegalArgumentException().isThrownBy(() -> new MyDrools("", ARTIFACT, VERSION, null, null))
280 .withMessageContaining("group");
282 assertThatIllegalArgumentException().isThrownBy(() -> new MyDrools(GROUP, null, VERSION, null, null))
283 .withMessageContaining("artifact");
284 assertThatIllegalArgumentException().isThrownBy(() -> new MyDrools(GROUP, "", VERSION, null, null))
285 .withMessageContaining("artifact");
287 assertThatIllegalArgumentException().isThrownBy(() -> new MyDrools(GROUP, ARTIFACT, null, null, null))
288 .withMessageContaining("version");
289 assertThatIllegalArgumentException().isThrownBy(() -> new MyDrools(GROUP, ARTIFACT, "", null, null))
290 .withMessageContaining("version");
294 public void testUpdateToVersion() {
296 drools.updateToVersion(GROUP, ARTIFACT, VERSION2, decoders, encoders);
298 verify(container).updateToVersion(VERSION2);
300 // nothing removed the first time
301 verify(coderMgr, never()).removeDecoders(GROUP, ARTIFACT, TOPIC2);
302 verify(coderMgr, never()).removeEncoders(GROUP, ARTIFACT, TOPIC);
304 verify(coderMgr, times(2)).addDecoder(any());
305 verify(coderMgr, times(1)).addEncoder(any());
308 when(container.getVersion()).thenReturn(VERSION2);
309 drools.updateToVersion(GROUP, ARTIFACT, VERSION, null, null);
311 verify(container).updateToVersion(VERSION);
313 verify(coderMgr, times(2)).removeDecoders(GROUP, ARTIFACT, TOPIC2);
314 verify(coderMgr, times(2)).removeEncoders(GROUP, ARTIFACT, TOPIC);
317 verify(coderMgr, times(2)).addDecoder(any());
318 verify(coderMgr, times(1)).addEncoder(any());
322 public void testUpdateToVersion_Unchanged() {
323 drools.updateToVersion(GROUP, ARTIFACT, VERSION, decoders, encoders);
325 verify(coderMgr, never()).addDecoder(any());
326 verify(coderMgr, never()).addEncoder(any());
330 public void testUpdateToVersion_InvalidArgs() {
331 assertThatIllegalArgumentException()
332 .isThrownBy(() -> drools.updateToVersion(null, ARTIFACT, VERSION, null, null))
333 .withMessageContaining("group");
334 assertThatIllegalArgumentException().isThrownBy(() -> drools.updateToVersion("", ARTIFACT, VERSION, null, null))
335 .withMessageContaining("group");
337 assertThatIllegalArgumentException().isThrownBy(() -> drools.updateToVersion(GROUP, null, VERSION, null, null))
338 .withMessageContaining("artifact");
339 assertThatIllegalArgumentException().isThrownBy(() -> drools.updateToVersion(GROUP, "", VERSION, null, null))
340 .withMessageContaining("artifact");
342 assertThatIllegalArgumentException().isThrownBy(() -> drools.updateToVersion(GROUP, ARTIFACT, null, null, null))
343 .withMessageContaining("version");
344 assertThatIllegalArgumentException().isThrownBy(() -> drools.updateToVersion(GROUP, ARTIFACT, "", null, null))
345 .withMessageContaining("version");
347 assertThatIllegalArgumentException()
348 .isThrownBy(() -> drools.updateToVersion("no-group-id", ARTIFACT, VERSION, null, null))
349 .withMessageContaining("BRAINLESS");
351 assertThatIllegalArgumentException()
352 .isThrownBy(() -> drools.updateToVersion(GROUP, "no-artifact-id", VERSION, null, null))
353 .withMessageContaining("BRAINLESS");
355 assertThatIllegalArgumentException()
356 .isThrownBy(() -> drools.updateToVersion(GROUP, ARTIFACT, "no-version", null, null))
357 .withMessageContaining("BRAINLESS");
359 assertThatIllegalArgumentException()
360 .isThrownBy(() -> drools.updateToVersion(GROUP2, ARTIFACT, VERSION, null, null))
361 .withMessageContaining("coordinates must be identical");
363 assertThatIllegalArgumentException()
364 .isThrownBy(() -> drools.updateToVersion(GROUP, ARTIFACT2, VERSION, null, null))
365 .withMessageContaining("coordinates must be identical");
369 public void testInitCoders_NullCoders() {
370 // already constructed with null coders
371 verify(coderMgr, never()).addDecoder(any());
372 verify(coderMgr, never()).addEncoder(any());
376 public void testInitCoders_NullOrEmptyFilters() {
377 when(decoder1.getCoderFilters()).thenReturn(Collections.emptyList());
378 when(decoder2.getCoderFilters()).thenReturn(null);
380 when(encoder1.getCoderFilters()).thenReturn(null);
381 when(encoder2.getCoderFilters()).thenReturn(Collections.emptyList());
383 drools = new MyDrools(GROUP, ARTIFACT, VERSION, decoders, encoders);
385 verify(coderMgr, never()).addDecoder(any());
386 verify(coderMgr, never()).addEncoder(any());
390 public void testInitCoders_GsonClass() {
391 when(gson1.getClassContainer()).thenReturn("");
392 when(gson2.getClassContainer()).thenReturn(Long.class.getName());
394 drools = new MyDrools(GROUP, ARTIFACT, VERSION, decoders, encoders);
396 // all should be added
397 verify(coderMgr, times(2)).addDecoder(any());
398 verify(coderMgr, times(1)).addEncoder(any());
402 public void testInitCoders_InvalidGsonClass() {
403 when(gson1.getClassContainer()).thenReturn(UNKNOWN_CLASS);
405 assertThatIllegalArgumentException()
406 .isThrownBy(() -> new MyDrools(GROUP, ARTIFACT, VERSION, decoders, encoders))
407 .withMessageContaining("cannot be retrieved");
411 public void testInitCoders_InvalidFilterClass() {
412 when(filter2.getCodedClass()).thenReturn(UNKNOWN_CLASS);
414 assertThatIllegalArgumentException()
415 .isThrownBy(() -> new MyDrools(GROUP, ARTIFACT, VERSION, decoders, encoders))
416 .withMessageContaining("cannot be retrieved");
420 public void testInitCoders_Filters() {
422 drools = new MyDrools(GROUP, ARTIFACT, VERSION, decoders, encoders);
424 ArgumentCaptor<EventProtocolParams> dec = ArgumentCaptor.forClass(EventProtocolParams.class);
425 verify(coderMgr, times(2)).addDecoder(dec.capture());
427 ArgumentCaptor<EventProtocolParams> enc = ArgumentCaptor.forClass(EventProtocolParams.class);
428 verify(coderMgr, times(1)).addEncoder(enc.capture());
430 // validate parameters
431 EventProtocolParams params = dec.getAllValues().get(0);
432 assertEquals(ARTIFACT, params.getArtifactId());
433 assertEquals(gson1, params.getCustomCoder());
434 assertEquals(Object.class.getName(), params.getEventClass());
435 assertEquals(GROUP, params.getGroupId());
436 assertEquals(CLASS_LOADER_HASHCODE, params.getModelClassLoaderHash());
437 assertEquals(jsonFilter1a, params.getProtocolFilter());
438 assertEquals(TOPIC, params.getTopic());
440 params = dec.getAllValues().get(1);
441 assertEquals(ARTIFACT, params.getArtifactId());
442 assertEquals(gson1, params.getCustomCoder());
443 assertEquals(String.class.getName(), params.getEventClass());
444 assertEquals(GROUP, params.getGroupId());
445 assertEquals(CLASS_LOADER_HASHCODE, params.getModelClassLoaderHash());
446 assertEquals(jsonFilter1b, params.getProtocolFilter());
447 assertEquals(TOPIC, params.getTopic());
449 params = enc.getAllValues().get(0);
450 assertEquals(ARTIFACT, params.getArtifactId());
451 assertEquals(gson2, params.getCustomCoder());
452 assertEquals(Integer.class.getName(), params.getEventClass());
453 assertEquals(GROUP, params.getGroupId());
454 assertEquals(CLASS_LOADER_HASHCODE, params.getModelClassLoaderHash());
455 assertEquals(jsonFilter2, params.getProtocolFilter());
456 assertEquals(TOPIC, params.getTopic());
460 public void testOwnsCoder() {
461 int hc = CLASS_LOADER_HASHCODE;
464 assertFalse(drools.ownsCoder(String.class, hc + 1));
467 assertTrue(drools.ownsCoder(String.class, hc));
470 drools = new MyDrools(GROUP, ARTIFACT, VERSION, null, null) {
472 protected boolean isClass(String className) {
476 assertFalse(drools.ownsCoder(String.class, hc));
480 public void testStart_testStop_testIsAlive() {
481 drools = new MyDrools(GROUP, ARTIFACT, VERSION, decoders, encoders);
483 when(container.start()).thenReturn(true);
484 when(container.stop()).thenReturn(true);
486 assertFalse(drools.isAlive());
489 assertTrue(drools.start());
490 verify(container).start();
491 assertTrue(drools.isAlive());
493 // repeat - no changes
494 assertTrue(drools.start());
495 verify(container).start();
496 assertTrue(drools.isAlive());
499 assertTrue(drools.stop());
500 verify(container).stop();
501 assertFalse(drools.isAlive());
503 // repeat - no changes
504 assertTrue(drools.stop());
505 verify(container).stop();
506 assertFalse(drools.isAlive());
508 // now check with container returning false - should still be invoked
509 when(container.start()).thenReturn(false);
510 when(container.stop()).thenReturn(false);
511 assertFalse(drools.start());
512 assertTrue(drools.isAlive());
513 assertFalse(drools.stop());
514 assertFalse(drools.isAlive());
515 verify(container, times(2)).start();
516 verify(container, times(2)).stop();
518 // coders should still be intact
519 verify(coderMgr, never()).removeDecoders(any(), any(), any());
520 verify(coderMgr, never()).removeEncoders(any(), any(), any());
522 verify(container, never()).shutdown();
523 verify(container, never()).destroy();
527 public void testShutdown() {
528 drools = new MyDrools(GROUP, ARTIFACT, VERSION, decoders, encoders);
536 verify(container).stop();
537 assertFalse(drools.isAlive());
539 // coders should have been removed
540 verify(coderMgr, times(2)).removeDecoders(any(), any(), any());
541 verify(coderMgr, times(2)).removeEncoders(any(), any(), any());
543 verify(container).shutdown();
544 verify(container, never()).destroy();
548 public void testShutdown_Ex() {
549 drools = new MyDrools(GROUP, ARTIFACT, VERSION, decoders, encoders);
554 when(container.stop()).thenThrow(RUNTIME_EX);
559 assertFalse(drools.isAlive());
561 verify(container).shutdown();
562 verify(container, never()).destroy();
566 public void testHalt() {
567 drools = new MyDrools(GROUP, ARTIFACT, VERSION, decoders, encoders);
575 verify(container).stop();
576 assertFalse(drools.isAlive());
578 // coders should have been removed
579 verify(coderMgr, times(2)).removeDecoders(any(), any(), any());
580 verify(coderMgr, times(2)).removeEncoders(any(), any(), any());
582 verify(container).destroy();
586 public void testHalt_Ex() {
587 drools = new MyDrools(GROUP, ARTIFACT, VERSION, decoders, encoders);
592 when(container.stop()).thenThrow(RUNTIME_EX);
597 assertFalse(drools.isAlive());
599 verify(container).destroy();
603 public void testRemoveCoders_Ex() {
604 drools = new MyDrools(GROUP, ARTIFACT, VERSION, decoders, encoders) {
606 protected void removeDecoders() {
611 protected void removeEncoders() {
616 drools.updateToVersion(GROUP, ARTIFACT, VERSION2, null, null);
620 public void testOfferStringString() {
622 assertTrue(drools.offer(TOPIC, EVENT_TEXT));
624 verify(container).insertAll(EVENT);
628 public void testOfferStringString_NoDecode() {
629 when(coderMgr.isDecodingSupported(GROUP, ARTIFACT, TOPIC)).thenReturn(false);
632 assertTrue(drools.offer(TOPIC, EVENT_TEXT));
634 verify(container, never()).insertAll(EVENT);
638 public void testOfferStringString_DecodeUnsupported() {
639 when(coderMgr.decode(GROUP, ARTIFACT, TOPIC, EVENT_TEXT))
640 .thenThrow(new UnsupportedOperationException(EXPECTED_EXCEPTION));
643 assertTrue(drools.offer(TOPIC, EVENT_TEXT));
645 verify(container, never()).insertAll(EVENT);
649 public void testOfferStringString_DecodeEx() {
650 when(coderMgr.decode(GROUP, ARTIFACT, TOPIC, EVENT_TEXT)).thenThrow(RUNTIME_EX);
653 assertTrue(drools.offer(TOPIC, EVENT_TEXT));
655 verify(container, never()).insertAll(EVENT);
659 public void testOfferStringString_Ignored() {
663 assertTrue(drools.offer(TOPIC, EVENT_TEXT));
664 assertEquals(0, drools.getRecentSourceEvents().length);
668 assertTrue(drools.offer(TOPIC, EVENT_TEXT));
669 assertEquals(0, drools.getRecentSourceEvents().length);
673 when(container.getPolicySessions()).thenReturn(Collections.emptyList());
674 assertTrue(drools.offer(TOPIC, EVENT_TEXT));
675 assertEquals(0, drools.getRecentSourceEvents().length);
679 public void testOfferT() {
681 assertTrue(drools.offer(EVENT));
682 assertEquals(1, drools.getRecentSourceEvents().length);
683 assertEquals(EVENT, drools.getRecentSourceEvents()[0]);
684 verify(container).insertAll(EVENT);
686 verify(prov1).beforeInsert(drools, EVENT);
687 verify(prov2).beforeInsert(drools, EVENT);
689 verify(prov1).afterInsert(drools, EVENT, true);
690 verify(prov2).afterInsert(drools, EVENT, true);
694 public void testOfferT_Ex() {
695 when(prov1.beforeInsert(drools, EVENT)).thenThrow(RUNTIME_EX);
696 when(prov1.afterInsert(drools, EVENT, true)).thenThrow(RUNTIME_EX);
699 assertTrue(drools.offer(EVENT));
700 assertEquals(1, drools.getRecentSourceEvents().length);
701 assertEquals(EVENT, drools.getRecentSourceEvents()[0]);
702 verify(container).insertAll(EVENT);
704 // should still invoke prov2
705 verify(prov2).beforeInsert(drools, EVENT);
707 verify(prov2).afterInsert(drools, EVENT, true);
711 public void testOfferT_NotInserted() {
712 when(container.insertAll(EVENT)).thenReturn(false);
715 assertTrue(drools.offer(EVENT));
716 assertEquals(1, drools.getRecentSourceEvents().length);
717 assertEquals(EVENT, drools.getRecentSourceEvents()[0]);
718 verify(container).insertAll(EVENT);
720 verify(prov1).beforeInsert(drools, EVENT);
721 verify(prov2).beforeInsert(drools, EVENT);
723 verify(prov1).afterInsert(drools, EVENT, false);
724 verify(prov2).afterInsert(drools, EVENT, false);
728 public void testOfferT_BeforeInsertIntercept() {
730 when(prov1.beforeInsert(drools, EVENT)).thenReturn(true);
732 assertTrue(drools.offer(EVENT));
733 assertEquals(1, drools.getRecentSourceEvents().length);
734 assertEquals(EVENT, drools.getRecentSourceEvents()[0]);
735 verify(container, never()).insertAll(EVENT);
737 verify(prov1).beforeInsert(drools, EVENT);
739 // nothing else invoked
740 verify(prov2, never()).beforeInsert(drools, EVENT);
741 verify(prov1, never()).afterInsert(drools, EVENT, true);
742 verify(prov2, never()).afterInsert(drools, EVENT, true);
746 public void testOfferT_AfterInsertIntercept() {
749 when(prov1.afterInsert(drools, EVENT, true)).thenReturn(true);
751 assertTrue(drools.offer(EVENT));
752 assertEquals(1, drools.getRecentSourceEvents().length);
753 assertEquals(EVENT, drools.getRecentSourceEvents()[0]);
754 verify(container).insertAll(EVENT);
756 verify(prov1).beforeInsert(drools, EVENT);
757 verify(prov2).beforeInsert(drools, EVENT);
759 verify(prov1).afterInsert(drools, EVENT, true);
761 // prov2 is never called
762 verify(prov2, never()).afterInsert(drools, EVENT, true);
766 public void testOfferT_Ignored() {
770 assertTrue(drools.offer(EVENT));
771 assertEquals(0, drools.getRecentSourceEvents().length);
775 assertTrue(drools.offer(EVENT));
776 assertEquals(0, drools.getRecentSourceEvents().length);
780 when(container.getPolicySessions()).thenReturn(Collections.emptyList());
781 assertTrue(drools.offer(EVENT));
782 assertEquals(0, drools.getRecentSourceEvents().length);
786 public void testDeliver() {
788 assertTrue(drools.deliver(sink, EVENT));
789 assertEquals(1, drools.getRecentSinkEvents().length);
790 assertEquals(EVENT_TEXT, drools.getRecentSinkEvents()[0]);
792 verify(sink).send(EVENT_TEXT);
794 verify(prov1).beforeDeliver(drools, sink, EVENT);
795 verify(prov2).beforeDeliver(drools, sink, EVENT);
797 verify(prov1).afterDeliver(drools, sink, EVENT, EVENT_TEXT, true);
798 verify(prov2).afterDeliver(drools, sink, EVENT, EVENT_TEXT, true);
802 public void testDeliver_InvalidArgs() {
805 assertThatIllegalArgumentException().isThrownBy(() -> drools.deliver(null, EVENT))
806 .withMessageContaining("sink");
808 assertThatIllegalArgumentException().isThrownBy(() -> drools.deliver(sink, null))
809 .withMessageContaining("event");
812 assertThatIllegalStateException().isThrownBy(() -> drools.deliver(sink, EVENT)).withMessageContaining("locked");
816 assertThatIllegalStateException().isThrownBy(() -> drools.deliver(sink, EVENT))
817 .withMessageContaining("stopped");
820 assertEquals(0, drools.getRecentSinkEvents().length);
824 public void testDeliver_BeforeIntercept() {
825 when(prov1.beforeDeliver(drools, sink, EVENT)).thenReturn(true);
828 assertTrue(drools.deliver(sink, EVENT));
829 assertEquals(0, drools.getRecentSinkEvents().length);
831 verify(prov1).beforeDeliver(drools, sink, EVENT);
833 // nothing else should have been invoked
834 verify(sink, never()).send(EVENT_TEXT);
835 verify(prov2, never()).beforeDeliver(drools, sink, EVENT);
836 verify(prov1, never()).afterDeliver(drools, sink, EVENT, EVENT_TEXT, true);
837 verify(prov2, never()).afterDeliver(drools, sink, EVENT, EVENT_TEXT, true);
841 public void testDeliver_AfterIntercept() {
842 when(prov1.afterDeliver(drools, sink, EVENT, EVENT_TEXT, true)).thenReturn(true);
845 assertTrue(drools.deliver(sink, EVENT));
846 assertEquals(1, drools.getRecentSinkEvents().length);
847 assertEquals(EVENT_TEXT, drools.getRecentSinkEvents()[0]);
849 verify(prov1).beforeDeliver(drools, sink, EVENT);
850 verify(prov2).beforeDeliver(drools, sink, EVENT);
852 verify(sink).send(EVENT_TEXT);
854 verify(prov1).afterDeliver(drools, sink, EVENT, EVENT_TEXT, true);
856 // nothing else should have been invoked
857 verify(prov2, never()).afterDeliver(drools, sink, EVENT, EVENT_TEXT, true);
861 public void testDeliver_InterceptEx() {
862 when(prov1.beforeDeliver(drools, sink, EVENT)).thenThrow(RUNTIME_EX);
863 when(prov1.afterDeliver(drools, sink, EVENT, EVENT_TEXT, true)).thenThrow(RUNTIME_EX);
866 assertTrue(drools.deliver(sink, EVENT));
868 verify(sink).send(EVENT_TEXT);
870 // should still invoke prov2
871 verify(prov2).beforeDeliver(drools, sink, EVENT);
872 verify(prov2).afterDeliver(drools, sink, EVENT, EVENT_TEXT, true);
876 public void testGetXxx() {
877 assertEquals(VERSION, drools.getVersion());
878 assertEquals(ARTIFACT, drools.getArtifactId());
879 assertEquals(GROUP, drools.getGroupId());
880 assertEquals(CLASS_LOADER_HASHCODE, drools.getModelClassLoaderHash());
881 assertSame(container, drools.getContainer());
882 assertEquals(Arrays.asList(sess1, sess2), drools.getSessions());
884 // test junit methods - need a controller with fewer overrides
885 drools = new MavenDroolsController(GROUP, ARTIFACT, VERSION, null, null) {
887 protected PolicyContainer makePolicyContainer(String groupId, String artifactId, String version) {
892 assertSame(EventProtocolCoderConstants.getManager(), drools.getCoderManager());
893 assertSame(DroolsControllerFeatureApiConstants.getProviders(), drools.getDroolsProviders());
897 public void testLock_testUnlock_testIsLocked() {
898 assertFalse(drools.isLocked());
900 assertTrue(drools.lock());
901 assertTrue(drools.isLocked());
903 assertTrue(drools.unlock());
904 assertFalse(drools.isLocked());
907 assertTrue(drools.lock());
908 assertTrue(drools.isLocked());
910 assertTrue(drools.unlock());
911 assertFalse(drools.isLocked());
915 public void testGetSessionNames_testGetCanonicalSessionNames() {
916 assertEquals("[session-A, session-B]", drools.getSessionNames(true).toString());
917 assertEquals("[full-A, full-B]", drools.getSessionNames(false).toString());
919 assertEquals("[session-A, session-B]", drools.getSessionNames().toString());
921 assertEquals("[full-A, full-B]", drools.getCanonicalSessionNames().toString());
924 when(container.getPolicySessions()).thenThrow(RUNTIME_EX);
925 assertEquals("[expected exception]", drools.getSessionNames().toString());
929 public void testGetBaseDomainNames() {
930 KieContainer kiecont = mock(KieContainer.class);
931 when(kiecont.getKieBaseNames()).thenReturn(Arrays.asList("kieA", "kieB"));
932 when(container.getKieContainer()).thenReturn(kiecont);
934 assertEquals("[kieA, kieB]", drools.getBaseDomainNames().toString());
938 public void testGetSession() {
939 assertThatIllegalArgumentException().isThrownBy(() -> drools.getSession(null))
940 .withMessageContaining("must be provided");
942 assertThatIllegalArgumentException().isThrownBy(() -> drools.getSession(""))
943 .withMessageContaining("must be provided");
945 assertSame(sess1, drools.getSession(SESSION1));
946 assertSame(sess1, drools.getSession(FULL_SESSION1));
948 assertSame(sess2, drools.getSession(SESSION2));
950 assertThatIllegalArgumentException().isThrownBy(() -> drools.getSession("unknown session"))
951 .withMessageContaining("Invalid Session Name");
955 public void testFactClassNames() {
956 // copy to a sorted map so the order remains unchanged
957 Map<String, Integer> map = new TreeMap<>(drools.factClassNames(SESSION1));
958 assertEquals("{java.lang.Integer=2, java.lang.String=1}", map.toString());
960 assertThatIllegalArgumentException().isThrownBy(() -> drools.factClassNames(null))
961 .withMessageContaining("Invalid Session Name");
963 assertThatIllegalArgumentException().isThrownBy(() -> drools.factClassNames(""))
964 .withMessageContaining("Invalid Session Name");
968 public void testFactCount() {
969 assertEquals(FACT_COUNT, drools.factCount(SESSION1));
971 assertThatIllegalArgumentException().isThrownBy(() -> drools.factCount(null))
972 .withMessageContaining("Invalid Session Name");
974 assertThatIllegalArgumentException().isThrownBy(() -> drools.factCount(""))
975 .withMessageContaining("Invalid Session Name");
979 public void testFactsStringStringBoolean() {
980 assertEquals("[1000, 1001]", drools.facts(SESSION1, Integer.class.getName(), false).toString());
981 verify(kieSess, never()).delete(fact1);
982 verify(kieSess, never()).delete(fact2);
983 verify(kieSess, never()).delete(fact3);
984 verify(kieSess, never()).delete(factex);
986 // now delete - but should only delete 1 & 3
987 assertEquals("[1000, 1001]", drools.facts(SESSION1, Integer.class.getName(), true).toString());
988 verify(kieSess).delete(fact1);
989 verify(kieSess, never()).delete(fact2);
990 verify(kieSess).delete(fact3);
991 verify(kieSess, never()).delete(factex);
993 assertThatIllegalArgumentException().isThrownBy(() -> drools.facts(null, Integer.class.getName(), false))
994 .withMessageContaining("Invalid Session Name");
996 assertThatIllegalArgumentException().isThrownBy(() -> drools.facts("", Integer.class.getName(), false))
997 .withMessageContaining("Invalid Session Name");
999 assertThatIllegalArgumentException().isThrownBy(() -> drools.facts(SESSION1, null, false))
1000 .withMessageContaining("Invalid Class Name");
1002 assertThatIllegalArgumentException().isThrownBy(() -> drools.facts(SESSION1, "", false))
1003 .withMessageContaining("Invalid Class Name");
1005 assertThatIllegalArgumentException().isThrownBy(() -> drools.facts(SESSION1, UNKNOWN_CLASS, false))
1006 .withMessageContaining("classloader");
1010 public void testFactsStringStringBoolean_DeleteEx() {
1011 doThrow(RUNTIME_EX).when(kieSess).delete(fact1);
1013 assertEquals("[1000, 1001]", drools.facts(SESSION1, Integer.class.getName(), true).toString());
1015 // should still have deleted #3
1016 verify(kieSess).delete(fact3);
1020 public void testFactsStringClassOfT() {
1021 assertEquals("[1000, 1001]", drools.facts(SESSION1, Integer.class).toString());
1025 public void testFactQuery() {
1026 assertEquals("[1000, 1001]", drools.factQuery(SESSION1, QUERY, ENTITY, false, PARM1, PARM2).toString());
1028 verify(kieSess, never()).delete(fact1);
1029 verify(kieSess, never()).delete(fact3);
1031 assertThatIllegalArgumentException()
1032 .isThrownBy(() -> drools.factQuery(null, QUERY, ENTITY, false, PARM1, PARM2))
1033 .withMessageContaining("Invalid Session Name");
1035 assertThatIllegalArgumentException().isThrownBy(() -> drools.factQuery("", QUERY, ENTITY, false, PARM1, PARM2))
1036 .withMessageContaining("Invalid Session Name");
1038 assertThatIllegalArgumentException()
1039 .isThrownBy(() -> drools.factQuery(SESSION1, null, ENTITY, false, PARM1, PARM2))
1040 .withMessageContaining("Invalid Query Name");
1042 assertThatIllegalArgumentException()
1043 .isThrownBy(() -> drools.factQuery(SESSION1, "", ENTITY, false, PARM1, PARM2))
1044 .withMessageContaining("Invalid Query Name");
1046 assertThatIllegalArgumentException()
1047 .isThrownBy(() -> drools.factQuery(SESSION1, QUERY, null, false, PARM1, PARM2))
1048 .withMessageContaining("Invalid Queried Entity");
1050 assertThatIllegalArgumentException()
1051 .isThrownBy(() -> drools.factQuery(SESSION1, QUERY, "", false, PARM1, PARM2))
1052 .withMessageContaining("Invalid Queried Entity");
1054 assertThatIllegalArgumentException().isThrownBy(
1055 () -> drools.factQuery(SESSION1, QUERY + "-unknown-query", ENTITY, false, PARM1, PARM2))
1056 .withMessageContaining("Invalid Query Name");
1060 public void testFactQuery_Delete() {
1061 doThrow(RUNTIME_EX).when(kieSess).delete(fact1);
1063 assertEquals("[1000, 1001]", drools.factQuery(SESSION1, QUERY, ENTITY, true, PARM1, PARM2).toString());
1065 // should still delete fact #3
1066 verify(kieSess).delete(fact3);
1070 public void testDeleteStringT() {
1071 assertTrue(drools.delete(SESSION1, FACT3_OBJECT));
1073 verify(kieSess, never()).delete(fact1);
1074 verify(kieSess).delete(fact3);
1077 assertFalse(drools.delete(SESSION1, "hello"));
1079 // repeat, but generate exception while getting the first object
1080 when(kieSess.getObject(fact1)).thenThrow(RUNTIME_EX);
1081 assertTrue(drools.delete(SESSION1, FACT3_OBJECT));
1083 verify(kieSess, never()).delete(fact1);
1085 // should still delete fact #3
1086 verify(kieSess, times(2)).delete(fact3);
1090 public void testDeleteT() {
1091 assertTrue(drools.delete(FACT3_OBJECT));
1093 verify(kieSess).delete(fact3);
1097 public void testDeleteStringClassOfT() {
1098 assertTrue(drools.delete(SESSION1, Integer.class));
1100 verify(kieSess).delete(fact1);
1101 verify(kieSess).delete(fact3);
1105 public void testDeleteStringClassOfT_Ex() {
1106 doThrow(RUNTIME_EX).when(kieSess).delete(fact1);
1108 assertFalse(drools.delete(SESSION1, Integer.class));
1110 // should still delete fact #3
1111 verify(kieSess).delete(fact3);
1115 public void testDeleteClassOfT() {
1116 assertTrue(drools.delete(Integer.class));
1118 verify(kieSess).delete(fact1);
1119 verify(kieSess).delete(fact3);
1123 public void testFetchModelClass() {
1124 assertSame(Long.class, drools.fetchModelClass(Long.class.getName()));
1128 public void testIsBrained() {
1129 assertTrue(drools.isBrained());
1133 public void testToString() {
1134 assertNotNull(drools.toString());
1137 private class MyDrools extends MavenDroolsController {
1139 public MyDrools(String groupId, String artifactId, String version,
1140 List<TopicCoderFilterConfiguration> decoderConfigurations,
1141 List<TopicCoderFilterConfiguration> encoderConfigurations) {
1143 super(groupId, artifactId, version, decoderConfigurations, encoderConfigurations);
1147 protected EventProtocolCoder getCoderManager() {
1152 protected OrderedServiceImpl<DroolsControllerFeatureApi> getDroolsProviders() {
1153 return droolsProviders;
1157 protected PolicyContainer makePolicyContainer(String groupId, String artifactId, String version) {
1158 when(container.getGroupId()).thenReturn(groupId);
1159 when(container.getArtifactId()).thenReturn(artifactId);
1160 when(container.getVersion()).thenReturn(version);