/* * Copyright (c) 2008-2017, Hazelcast, Inc. All Rights Reserved. * * Licensed 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 com.hazelcast.collection.impl.queue; import com.hazelcast.collection.impl.queue.operations.AddAllOperation; import com.hazelcast.collection.impl.queue.operations.ClearOperation; import com.hazelcast.collection.impl.queue.operations.CompareAndRemoveOperation; import com.hazelcast.collection.impl.queue.operations.ContainsOperation; import com.hazelcast.collection.impl.queue.operations.DrainOperation; import com.hazelcast.collection.impl.queue.operations.IsEmptyOperation; import com.hazelcast.collection.impl.queue.operations.IteratorOperation; import com.hazelcast.collection.impl.queue.operations.OfferOperation; import com.hazelcast.collection.impl.queue.operations.PeekOperation; import com.hazelcast.collection.impl.queue.operations.PollOperation; import com.hazelcast.collection.impl.queue.operations.QueueOperation; import com.hazelcast.collection.impl.queue.operations.RemainingCapacityOperation; import com.hazelcast.collection.impl.queue.operations.RemoveOperation; import com.hazelcast.collection.impl.queue.operations.SizeOperation; import com.hazelcast.config.ItemListenerConfig; import com.hazelcast.config.QueueConfig; import com.hazelcast.core.HazelcastInstanceAware; import com.hazelcast.core.ItemListener; import com.hazelcast.nio.ClassLoaderUtil; import com.hazelcast.nio.serialization.Data; import com.hazelcast.spi.AbstractDistributedObject; import com.hazelcast.spi.InitializingObject; import com.hazelcast.spi.InternalCompletableFuture; import com.hazelcast.spi.NodeEngine; import com.hazelcast.spi.Operation; import com.hazelcast.spi.OperationService; import com.hazelcast.spi.impl.SerializableList; import com.hazelcast.util.ExceptionUtil; import java.util.Collection; import java.util.List; import java.util.concurrent.Future; import static com.hazelcast.util.Preconditions.checkNotNull; abstract class QueueProxySupport extends AbstractDistributedObject<QueueService> implements InitializingObject { final String name; final int partitionId; final QueueConfig config; QueueProxySupport(final String name, final QueueService queueService, NodeEngine nodeEngine) { super(nodeEngine, queueService); this.name = name; this.partitionId = nodeEngine.getPartitionService().getPartitionId(getNameAsPartitionAwareData()); this.config = nodeEngine.getConfig().findQueueConfig(name); } @Override public void initialize() { final NodeEngine nodeEngine = getNodeEngine(); final List<ItemListenerConfig> itemListenerConfigs = config.getItemListenerConfigs(); for (ItemListenerConfig itemListenerConfig : itemListenerConfigs) { ItemListener listener = itemListenerConfig.getImplementation(); if (listener == null && itemListenerConfig.getClassName() != null) { try { listener = ClassLoaderUtil.newInstance(nodeEngine.getConfigClassLoader(), itemListenerConfig.getClassName()); } catch (Exception e) { throw ExceptionUtil.rethrow(e); } } if (listener != null) { if (listener instanceof HazelcastInstanceAware) { ((HazelcastInstanceAware) listener).setHazelcastInstance(nodeEngine.getHazelcastInstance()); } addItemListener(listener, itemListenerConfig.isIncludeValue()); } } } boolean offerInternal(Data data, long timeout) throws InterruptedException { checkObjectNotNull(data); OfferOperation operation = new OfferOperation(name, timeout, data); return (Boolean) invokeAndGet(operation, InterruptedException.class); } public boolean isEmpty() { IsEmptyOperation operation = new IsEmptyOperation(name); return (Boolean) invokeAndGet(operation); } public int size() { SizeOperation operation = new SizeOperation(name); return (Integer) invokeAndGet(operation); } public int remainingCapacity() { RemainingCapacityOperation operation = new RemainingCapacityOperation(name); return (Integer) invokeAndGet(operation); } public void clear() { ClearOperation operation = new ClearOperation(name); invokeAndGet(operation); } Object peekInternal() { PeekOperation operation = new PeekOperation(name); return invokeAndGetData(operation); } Object pollInternal(long timeout) throws InterruptedException { PollOperation operation = new PollOperation(name, timeout); return invokeAndGet(operation, InterruptedException.class); } boolean removeInternal(Data data) { checkObjectNotNull(data); RemoveOperation operation = new RemoveOperation(name, data); return (Boolean) invokeAndGet(operation); } boolean containsInternal(Collection<Data> dataList) { ContainsOperation operation = new ContainsOperation(name, dataList); return (Boolean) invokeAndGet(operation); } List<Data> listInternal() { IteratorOperation operation = new IteratorOperation(name); SerializableList collectionContainer = invokeAndGet(operation); return (List<Data>) collectionContainer.getCollection(); } Collection<Data> drainInternal(int maxSize) { DrainOperation operation = new DrainOperation(name, maxSize); SerializableList collectionContainer = invokeAndGet(operation); return collectionContainer.getCollection(); } boolean addAllInternal(Collection<Data> dataList) { AddAllOperation operation = new AddAllOperation(name, dataList); return (Boolean) invokeAndGet(operation); } boolean compareAndRemove(Collection<Data> dataList, boolean retain) { CompareAndRemoveOperation operation = new CompareAndRemoveOperation(name, dataList, retain); return (Boolean) invokeAndGet(operation); } private int getPartitionId() { return partitionId; } protected void checkObjectNotNull(Object o) { checkNotNull(o, "Object is null"); } private <T> T invokeAndGet(QueueOperation operation) { return invokeAndGet(operation, RuntimeException.class); } private <T, E extends Throwable> T invokeAndGet(QueueOperation operation, Class<E> allowedException) throws E { final NodeEngine nodeEngine = getNodeEngine(); try { Future f = invoke(operation); return (T) nodeEngine.toObject(f.get()); } catch (Throwable throwable) { throw ExceptionUtil.rethrow(throwable, allowedException); } } private InternalCompletableFuture invoke(Operation operation) { final NodeEngine nodeEngine = getNodeEngine(); OperationService operationService = nodeEngine.getOperationService(); return operationService.invokeOnPartition(QueueService.SERVICE_NAME, operation, getPartitionId()); } private Object invokeAndGetData(QueueOperation operation) { final NodeEngine nodeEngine = getNodeEngine(); try { OperationService operationService = nodeEngine.getOperationService(); Future f = operationService.invokeOnPartition(QueueService.SERVICE_NAME, operation, partitionId); return f.get(); } catch (Throwable throwable) { throw ExceptionUtil.rethrow(throwable); } } @Override public final String getServiceName() { return QueueService.SERVICE_NAME; } @Override public final String getName() { return name; } public String addItemListener(ItemListener listener, boolean includeValue) { return getService().addItemListener(name, listener, includeValue, false); } public boolean removeItemListener(String registrationId) { return getService().removeItemListener(name, registrationId); } }