All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jsr107.tck.integration.CacheWriterClient Maven / Gradle / Ivy

Go to download

Tests for JSR107 compliant caches. These are tests from the JSR107 TCK that were published as Open Source. The artifact may also contain additional tests and improvements. For compliance testing use the original TCK as published via jcp.org.

The newest version!
/**
 *  Copyright 2011-2013 Terracotta, Inc.
 *  Copyright 2011-2013 Oracle, Inc.
 *
 *  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 org.jsr107.tck.integration;

import org.jsr107.tck.support.CacheClient;
import org.jsr107.tck.support.Operation;
import org.jsr107.tck.support.Server;

import javax.cache.Cache;
import javax.cache.integration.CacheWriter;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.InetAddress;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ExecutionException;

/**
 * A {@link CacheWriter} that delegates requests to a {@link CacheWriterServer}.
 *
 * @param  the type of keys
 * @param  the type of values
 * @author Brian Oliver
 * @author Joe Fialli
 */
public class CacheWriterClient extends CacheClient implements CacheWriter {

    private CacheWriterServer shortCircuitServer;

    /**
     * Constructs a {@link CacheWriterClient}.
     *
     * @param address the {@link InetAddress} on which to connect to the {@link CacheWriterServer}
     * @param port    the port to which to connect to the {@link CacheWriterServer}
     */
    public CacheWriterClient(InetAddress address, int port) {
        super(address, port);
    }

    @Override
    protected void checkDirectCallsPossible() {
        super.checkDirectCallsPossible();
        if (directServer != null) {
            shortCircuitServer = ((CacheWriterServer) directServer);
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void write(Cache.Entry entry) {
        if (isDirectCallable()) {
            shortCircuitServer.getCacheWriter().write(entry);
            return;
        }
        getClient().invoke(new WriteOperation<>(entry));
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void writeAll(Collection> entries) {
        if (isDirectCallable()) {
            shortCircuitServer.getCacheWriter().writeAll(entries);
            return;
        }
        getClient().invoke(new WriteAllOperation<>(entries));
    }

    @Override
    public void delete(Object key) {
        if (isDirectCallable()) {
            shortCircuitServer.getCacheWriter().delete(key);
            return;
        }
        getClient().invoke(new DeleteOperation((K)key));

    }

    @Override
    public void deleteAll(Collection keys) {
        if (isDirectCallable()) {
            shortCircuitServer.getCacheWriter().deleteAll(keys);
            return;
        }
        getClient().invoke(new DeleteAllOperation((Collection) keys));
    }

    /**
     * The {@link DeleteAllOperation} representing a {@link CacheWriter#deleteAll(java.util.Collection)}
     * request.
     *
     * @param  the type of keys
     * @param  the type of values
     */
    private static class DeleteAllOperation implements Operation> {

        /**
         * The keys to Delete.
         */
        private Collection keys;

        /**
         * Constructs a {@link DeleteAllOperation}.
         *
         * @param keys the keys to Delete
         */
        public DeleteAllOperation(Collection keys) {
            this.keys = keys;
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public String getType() {
            return "deleteAll";
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public Map onInvoke(ObjectInputStream ois, ObjectOutputStream oos)
                throws IOException, ClassNotFoundException, ExecutionException {

            // send the keys to Delete
            for (K key : keys) {
                oos.writeObject(key);
            }

            oos.writeObject(null);

            // check for remote exceptions
            Object result = ois.readObject();
            Collection notDeletedKeys;

            if (result instanceof RuntimeException) {
                notDeletedKeys = (Collection) ois.readObject();

                // Partial Success processsing
                // returned keys were not able to be deleted.  remove from original keys list.
                Iterator iter = keys.iterator();
                while (iter.hasNext()) {
                    if (!notDeletedKeys.contains(iter.next())) {
                        iter.remove();
                    }
                }

                throw(RuntimeException) result;
            } else {

                // if no exception then all keys were deleted, remove all these keys to record that they were deleted.
                keys.clear();

                return null;
            }
        }
    }


    /**
     * The {@link DeleteOperation} representing a {@link CacheWriter#delete(Object)}
     * request.
     *
     * @param  the type of keys
     * @param  the type of values
     */
    private static class DeleteOperation implements Operation {

        /**
         * The key to Delete.
         */
        private K key;

        /**
         * Constructs a {@link DeleteOperation}.
         *
         * @param key the Key to Delete
         */
        public DeleteOperation(K key) {
            this.key = key;
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public String getType() {
            return "delete";
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public V onInvoke(ObjectInputStream ois, ObjectOutputStream oos) throws IOException, ClassNotFoundException {
            oos.writeObject(key);

            Object o = ois.readObject();

            if (o instanceof RuntimeException) {
                throw(RuntimeException) o;
            } else {
                return null;
            }
        }
    }


    /**
     * The {@link WriteAllOperation} representing a {@link Cache#putAll(java.util.Map)} )}
     * request.
     *
     * @param  the type of keys
     * @param  the type of values
     */
    private static class WriteAllOperation implements Operation> {

        /**
         * The entries to write.
         */
        private Collection> entries;

        /**
         * Constructs a {@link WriteAllOperation}.
         *
         * @param entries the entries to write
         */
        public WriteAllOperation(Collection> entries) {
            this.entries = entries;
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public String getType() {
            return "writeAll";
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public Map onInvoke(ObjectInputStream ois, ObjectOutputStream oos)
                throws IOException, ClassNotFoundException {

            // send the entries to write
            for (Cache.Entry entry : entries) {
                oos.writeObject(entry.getKey());
                oos.writeObject(entry.getValue());
            }

            oos.writeObject(null);
            Object o = ois.readObject();

            if (o instanceof RuntimeException) {

                // Partial Success processsing, read in keys that failed to be written
                HashSet failedToWriteKeys = new HashSet<>();
                K key = (K) ois.readObject();
                while (key != null) {
                    failedToWriteKeys.add(key);
                    key = (K) ois.readObject();
                }

                Iterator> iter = entries.iterator();
                while (iter.hasNext()) {
                    if (!failedToWriteKeys.contains(iter.next().getKey())) {
                        iter.remove();
                    }
                }

                throw(RuntimeException) o;
            } else {

                entries.clear();

                return null;
            }
        }
    }


    /**
     * The {@link WriteOperation} representing a {@link CacheWriter#write(javax.cache.Cache.Entry)}
     * request.
     *
     * @param  the type of keys
     * @param  the type of values
     */
    private static class WriteOperation implements Operation {

        /**
         * The key to load.
         */
        private Cache.Entry entry;

        /**
         * Constructs a {@link WriteOperation}.
         *
         * @param entry the entry to write
         */
        public WriteOperation(Cache.Entry entry) {
            this.entry = entry;
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public String getType() {
            return "write";
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public V onInvoke(ObjectInputStream ois, ObjectOutputStream oos) throws IOException, ClassNotFoundException {
            oos.writeObject(entry.getKey());
            oos.writeObject(entry.getValue());

            Object o = ois.readObject();

            if (o instanceof RuntimeException) {
                throw(RuntimeException) o;
            } else {
                return null;
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy