2 * Copyright (c) 2014 Hewlett-Packard Development Company, L.P. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.aaa;
10 import java.util.ArrayList;
11 import java.util.Arrays;
12 import java.util.Collection;
13 import java.util.Iterator;
14 import java.util.concurrent.BlockingQueue;
15 import java.util.concurrent.TimeUnit;
16 import org.opendaylight.aaa.api.Authentication;
19 * A {@link BlockingQueue} decorator with injected security context.
26 public class SecureBlockingQueue<T> implements BlockingQueue<T> {
27 private final BlockingQueue<SecureData<T>> queue;
33 * blocking queue implementation to use
35 public SecureBlockingQueue(BlockingQueue<SecureData<T>> queue) {
41 return setAuth(queue.remove());
45 public boolean remove(Object object) {
46 Iterator<SecureData<T>> it = queue.iterator();
47 while (it.hasNext()) {
48 SecureData<T> sd = it.next();
49 if (sd.data.equals(object)) {
50 return queue.remove(sd);
59 return setAuth(queue.poll());
63 public T poll(long timeout, TimeUnit unit) throws InterruptedException {
64 return setAuth(queue.poll(timeout, unit));
69 return setAuth(queue.element());
74 return setAuth(queue.peek());
83 public boolean isEmpty() {
84 return queue.isEmpty();
88 public Iterator<T> iterator() {
89 return new Iterator<T>() {
90 Iterator<SecureData<T>> it = queue.iterator();
93 public boolean hasNext() {
99 return it.next().data;
103 public void remove() {
110 public Object[] toArray() {
111 return toData().toArray();
114 @SuppressWarnings("hiding")
116 public <T> T[] toArray(T[] array) {
117 return toData().toArray(array);
121 public boolean containsAll(Collection<?> collection) {
122 return toData().containsAll(collection);
126 public boolean addAll(Collection<? extends T> collection) {
127 return queue.addAll(fromData(collection));
131 public boolean removeAll(Collection<?> collection) {
132 return queue.removeAll(fromData(collection));
136 public boolean retainAll(Collection<?> collection) {
137 return queue.retainAll(fromData(collection));
141 public void clear() {
146 public boolean add(T element) {
147 return queue.add(new SecureData<>(element));
151 public boolean offer(T element) {
152 return queue.offer(new SecureData<>(element));
156 public boolean offer(T element, long timeout, TimeUnit unit) throws InterruptedException {
157 return queue.offer(new SecureData<>(element), timeout, unit);
161 public void put(T element) throws InterruptedException {
162 queue.put(new SecureData<>(element));
166 public T take() throws InterruptedException {
167 return setAuth(queue.take());
171 public int remainingCapacity() {
172 return queue.remainingCapacity();
176 public boolean contains(Object object) {
177 Iterator<SecureData<T>> it = queue.iterator();
178 while (it.hasNext()) {
179 SecureData<T> sd = it.next();
180 if (sd.data.equals(object)) {
188 public int drainTo(Collection<? super T> collection) {
189 Collection<SecureData<T>> sd = new ArrayList<>();
190 int number = queue.drainTo(sd);
191 collection.addAll(toData(sd));
196 public int drainTo(Collection<? super T> collection, int maxElements) {
197 Collection<SecureData<T>> sd = new ArrayList<>();
198 int number = queue.drainTo(sd, maxElements);
199 collection.addAll(toData(sd));
203 // Rehydrate security context
204 private T setAuth(SecureData<T> secureData) {
205 AuthenticationManager.instance().set(secureData.auth);
206 return secureData.data;
209 // Construct secure data collection from a plain old data collection
210 @SuppressWarnings("unchecked")
211 private Collection<SecureData<T>> fromData(Collection<?> collection) {
212 Collection<SecureData<T>> sd = new ArrayList<>(collection.size());
213 for (Object d : collection) {
214 sd.add((SecureData<T>) new SecureData<>(d));
219 // Extract the data portion out from the secure data
220 @SuppressWarnings("unchecked")
221 private Collection<T> toData() {
222 return toData(Arrays.<SecureData<T>>asList(queue.toArray(new SecureData[0])));
225 // Extract the data portion out from the secure data
226 private Collection<T> toData(Collection<SecureData<T>> secureData) {
227 Collection<T> data = new ArrayList<>(secureData.size());
228 Iterator<SecureData<T>> it = secureData.iterator();
229 while (it.hasNext()) {
230 data.add(it.next().data);
235 // Inject security context
236 public static final class SecureData<T> {
237 private final T data;
238 private final Authentication auth;
240 private SecureData(T data) {
242 this.auth = AuthenticationManager.instance().get();
245 @SuppressWarnings("rawtypes")
247 public boolean equals(Object object) {
248 if (object == null) {
251 return object instanceof SecureData ? data.equals(((SecureData) object).data) : false;
255 public int hashCode() {
256 return data.hashCode();