/** * 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. */ /** * Copyright (c) 2016, Salesforce Developers * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the copyright holder nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. **/ package org.apache.camel.component.salesforce.internal.streaming; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.atomic.AtomicBoolean; import org.cometd.bayeux.Channel; import org.cometd.bayeux.Message; import org.cometd.bayeux.client.ClientSession; import org.cometd.bayeux.client.ClientSession.Extension.Adapter; /** * CometDReplayExtension, typical usages are the following: * {@code client.addExtension(new CometDReplayExtension<>(replayMap));} * * @author yzhao * @since 198 (Winter '16) */ public class CometDReplayExtension extends Adapter { private static final String EXTENSION_NAME = "replay"; private final ConcurrentMap<String, Long> dataMap = new ConcurrentHashMap<>(); private final AtomicBoolean supported = new AtomicBoolean(); public void addChannelReplayId(final String channelName, final long replayId) { dataMap.put(channelName, replayId); } @Override public boolean rcv(ClientSession session, Message.Mutable message) { final Object value = message.get(EXTENSION_NAME); final Long replayId; if (value instanceof Long) { replayId = (Long)value; } else if (value instanceof Number) { replayId = ((Number)value).longValue(); } else { replayId = null; } if (this.supported.get() && replayId != null) { try { dataMap.put(message.getChannel(), replayId); } catch (ClassCastException e) { return false; } } return true; } @Override public boolean rcvMeta(ClientSession session, Message.Mutable message) { switch (message.getChannel()) { case Channel.META_HANDSHAKE: Map<String, Object> ext = message.getExt(false); this.supported.set(ext != null && Boolean.TRUE.equals(ext.get(EXTENSION_NAME))); break; default: break; } return true; } @Override public boolean sendMeta(ClientSession session, Message.Mutable message) { switch (message.getChannel()) { case Channel.META_HANDSHAKE: message.getExt(true).put(EXTENSION_NAME, Boolean.TRUE); break; case Channel.META_SUBSCRIBE: if (supported.get()) { message.getExt(true).put(EXTENSION_NAME, dataMap); } break; default: break; } return true; } }