2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2019-2021 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.pap.main.comm;
23 import java.util.concurrent.BlockingQueue;
24 import java.util.concurrent.LinkedBlockingQueue;
25 import org.onap.policy.common.endpoints.event.comm.client.TopicSinkClient;
26 import org.onap.policy.common.endpoints.event.comm.client.TopicSinkClientException;
27 import org.onap.policy.common.utils.coder.StandardCoder;
28 import org.onap.policy.pap.main.PolicyPapException;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
33 * Publishes messages to a topic. Maintains a queue of references to data that is to be
34 * published. Once the publisher removes a reference from a queue, it sets it to
35 * {@link null} to indicate that it is being processed. Until it has been set to
36 * {@link null}, clients are free to atomically update the reference to new values, thus
37 * maintaining their place in the queue.
39 * <p>This class has not been tested for multiple threads invoking {@link #run()}
42 * @param <T> type of message published by this publisher
44 public class Publisher<T> implements Runnable {
45 private static final Logger logger = LoggerFactory.getLogger(Publisher.class);
48 * Used to send to the topic.
50 private final TopicSinkClient client;
53 * Request queue. The references may contain {@code null}.
55 private final BlockingQueue<QueueToken<T>> queue = new LinkedBlockingQueue<>();
58 * Set to {@code true} to cause the publisher to stop running.
60 private volatile boolean stopNow = false;
63 * Constructs the object.
65 * @param topic name of the topic to which to publish
66 * @throws PolicyPapException if the topic sink does not exist
68 public Publisher(String topic) throws PolicyPapException {
70 this.client = new TopicSinkClient(topic);
71 } catch (TopicSinkClientException e) {
72 throw new PolicyPapException(e);
77 * Stops the publisher, if it's running.
82 // add an empty reference so the thread doesn't block on the queue
83 queue.add(new QueueToken<>(null));
87 * Adds an item to the queue. The referenced objects are assumed to be POJOs and will
88 * be converted to JSON via the {@link StandardCoder} prior to publishing.
90 * @param ref reference to the message to be published
92 public void enqueue(QueueToken<T> ref) {
97 * Continuously publishes items in the queue until {@link #stop()} is invoked.
102 QueueToken<T> token = getNext();
105 // unblock any other publisher threads
106 queue.add(new QueueToken<>(null));
110 var data = token.replaceItem(null);
118 * Gets the next item from the queue. If the thread is interrupted, then it sets
121 * @return the next item, or a reference containing {@code null} if this is
124 private QueueToken<T> getNext() {
128 } catch (InterruptedException e) {
129 logger.warn("Publisher stopping due to interrupt");
131 Thread.currentThread().interrupt();
132 return new QueueToken<>(null);