/** * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.camel.component.chronicle.engine; import java.util.Map; import net.openhft.chronicle.engine.api.map.MapView; import net.openhft.chronicle.engine.api.pubsub.Publisher; import net.openhft.chronicle.engine.api.pubsub.TopicPublisher; import net.openhft.chronicle.engine.api.tree.AssetTree; import net.openhft.chronicle.engine.tree.QueueView; import org.apache.camel.InvokeOnHeader; import org.apache.camel.Message; import org.apache.camel.impl.HeaderSelectorProducer; import org.apache.camel.util.ObjectHelper; import static org.apache.camel.component.chronicle.engine.ChronicleEngineHelper.WeakRef; import static org.apache.camel.component.chronicle.engine.ChronicleEngineHelper.mandatoryBody; import static org.apache.camel.component.chronicle.engine.ChronicleEngineHelper.mandatoryKey; public class ChronicleEngineProducer extends HeaderSelectorProducer { private final String uri; private WeakRef<TopicPublisher<Object, Object>> topicPublisher; private WeakRef<Publisher<Object>> publisher; private WeakRef<MapView<Object, Object>> mapView; private WeakRef<QueueView<Object, Object>> queueView; private AssetTree client; public ChronicleEngineProducer(ChronicleEngineEndpoint endpoint) { super(endpoint, ChronicleEngineConstants.ACTION, endpoint.getConfiguration().getAction()); this.uri = endpoint.getUri(); this.topicPublisher = WeakRef.create(() -> client.acquireTopicPublisher(uri, Object.class, Object.class)); this.publisher = WeakRef.create(() -> client.acquirePublisher(uri, Object.class)); this.mapView = WeakRef.create(() -> client.acquireMap(uri, Object.class, Object.class)); this.queueView = WeakRef.create(() -> client.acquireQueue(uri, Object.class, Object.class, endpoint.getConfiguration().getClusterName())); } // *************************** // AssetTree // *************************** @Override protected void doStart() throws Exception { super.doStart(); if (client != null) { throw new IllegalStateException("AssetTree already configured"); } client = ((ChronicleEngineEndpoint)getEndpoint()).createRemoteAssetTree(); } @Override protected void doStop() throws Exception { if (client != null) { client.close(); client = null; } super.doStop(); } // *************************** // Actions / Topic // *************************** @InvokeOnHeader(ChronicleEngineConstants.ACTION_PUBLISH) public void onPublish(Message message) { final Object key = message.getHeader(ChronicleEngineConstants.KEY); final Object val = mandatoryBody(message); if (key == null) { publisher.get().publish(val); } else { topicPublisher.get().publish(key, val); } } @InvokeOnHeader(ChronicleEngineConstants.ACTION_PUBLISH_AND_INDEX) public void onPublishAndIndex(Message message) { message.setHeader( ChronicleEngineConstants.QUEUE_INDEX, queueView.get().publishAndIndex(mandatoryKey(message), mandatoryBody(message)) ); } // *************************** // Actions / Map / Put // *************************** @InvokeOnHeader(ChronicleEngineConstants.ACTION_PUT) public void onPut(Message message) { message.setHeader( ChronicleEngineConstants.OLD_VALUE, mapView.get().put(mandatoryKey(message), mandatoryBody(message)) ); } @InvokeOnHeader(ChronicleEngineConstants.ACTION_GET_AND_PUT) public void onGetAndPut(Message message) { message.setBody( mapView.get().getAndPut(mandatoryKey(message), mandatoryBody(message)) ); } @InvokeOnHeader(ChronicleEngineConstants.ACTION_PUT_ALL) public void onPutAll(Message message) { mapView.get().putAll( ObjectHelper.notNull(message.getBody(Map.class), ChronicleEngineConstants.VALUE) ); } @InvokeOnHeader(ChronicleEngineConstants.ACTION_PUT_IF_ABSENT) public void onPutIfAbsent(Message message) { message.setHeader( ChronicleEngineConstants.RESULT, mapView.get().putIfAbsent(mandatoryKey(message), mandatoryBody(message)) ); } // *************************** // Actions / Map / Get // *************************** @InvokeOnHeader(ChronicleEngineConstants.ACTION_GET) public void onGet(Message message) { final Long index = message.getHeader(ChronicleEngineConstants.QUEUE_INDEX, Long.class); if (index == null) { message.setBody( mapView.get().getOrDefault( mandatoryKey(message), message.getHeader(ChronicleEngineConstants.DEFAULT_VALUE)) ); } else { QueueView.Excerpt<Object, Object> excerpt = queueView.get().getExcerpt(index.longValue()); message.setHeader(ChronicleEngineConstants.PATH, excerpt.topic()); message.setBody(excerpt.message()); } } @InvokeOnHeader(ChronicleEngineConstants.ACTION_GET_AND_REMOVE) public void onGetAndRemove(Message message) { message.setBody( mapView.get().getAndRemove(mandatoryKey(message)) ); } // *************************** // Actions / Map // *************************** @InvokeOnHeader(ChronicleEngineConstants.ACTION_REMOVE) public void onRemove(Message message) { Object oldValue = message.getHeader(ChronicleEngineConstants.OLD_VALUE); if (oldValue != null) { message.setHeader( ChronicleEngineConstants.RESULT, mapView.get().remove(mandatoryKey(message), oldValue) ); } else { message.setHeader( ChronicleEngineConstants.OLD_VALUE, mapView.get().remove(mandatoryKey(message)) ); } } @InvokeOnHeader(ChronicleEngineConstants.ACTION_IS_EMPTY) public void onIsEmpty(Message message) { message.setHeader( ChronicleEngineConstants.RESULT, mapView.get().isEmpty() ); } @InvokeOnHeader(ChronicleEngineConstants.ACTION_IS_SIZE) public void onSize(Message message) { message.setHeader( ChronicleEngineConstants.RESULT, mapView.get().size() ); } }