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());
46 return setAuth(queue.poll());
51 return setAuth(queue.element());
56 return setAuth(queue.peek());
65 public boolean isEmpty() {
66 return queue.isEmpty();
70 public Iterator<T> iterator() {
71 return new Iterator<T>() {
72 Iterator<SecureData<T>> it = queue.iterator();
75 public boolean hasNext() {
81 return it.next().data;
85 public void remove() {
92 public Object[] toArray() {
93 return toData().toArray();
96 @SuppressWarnings("hiding")
98 public <T> T[] toArray(T[] a) {
99 return toData().toArray(a);
103 public boolean containsAll(Collection<?> c) {
104 return toData().containsAll(c);
108 public boolean addAll(Collection<? extends T> c) {
109 return queue.addAll(fromData(c));
113 public boolean removeAll(Collection<?> c) {
114 return queue.removeAll(fromData(c));
118 public boolean retainAll(Collection<?> c) {
119 return queue.retainAll(fromData(c));
123 public void clear() {
128 public boolean add(T e) {
129 return queue.add(new SecureData<>(e));
133 public boolean offer(T e) {
134 return queue.offer(new SecureData<>(e));
138 public void put(T e) throws InterruptedException {
139 queue.put(new SecureData<T>(e));
143 public boolean offer(T e, long timeout, TimeUnit unit) throws InterruptedException {
144 return queue.offer(new SecureData<>(e), timeout, unit);
148 public T take() throws InterruptedException {
149 return setAuth(queue.take());
153 public T poll(long timeout, TimeUnit unit) throws InterruptedException {
154 return setAuth(queue.poll(timeout, unit));
158 public int remainingCapacity() {
159 return queue.remainingCapacity();
163 public boolean remove(Object o) {
164 Iterator<SecureData<T>> it = queue.iterator();
165 while (it.hasNext()) {
166 SecureData<T> sd = it.next();
167 if (sd.data.equals(o)) {
168 return queue.remove(sd);
175 public boolean contains(Object o) {
176 Iterator<SecureData<T>> it = queue.iterator();
177 while (it.hasNext()) {
178 SecureData<T> sd = it.next();
179 if (sd.data.equals(o)) {
187 public int drainTo(Collection<? super T> c) {
188 Collection<SecureData<T>> sd = new ArrayList<>();
189 int n = queue.drainTo(sd);
190 c.addAll(toData(sd));
195 public int drainTo(Collection<? super T> c, int maxElements) {
196 Collection<SecureData<T>> sd = new ArrayList<>();
197 int n = queue.drainTo(sd, maxElements);
198 c.addAll(toData(sd));
202 // Rehydrate security context
203 private T setAuth(SecureData<T> i) {
204 AuthenticationManager.instance().set(i.auth);
208 // Construct secure data collection from a plain old data collection
209 @SuppressWarnings("unchecked")
210 private Collection<SecureData<T>> fromData(Collection<?> c) {
211 Collection<SecureData<T>> sd = new ArrayList<>(c.size());
213 sd.add((SecureData<T>) new SecureData<>(d));
218 // Extract the data portion out from the secure data
219 @SuppressWarnings("unchecked")
220 private Collection<T> toData() {
221 return toData(Arrays.<SecureData<T>> asList(queue.toArray(new SecureData[0])));
224 // Extract the data portion out from the secure data
225 private Collection<T> toData(Collection<SecureData<T>> secureData) {
226 Collection<T> data = new ArrayList<>(secureData.size());
227 Iterator<SecureData<T>> it = secureData.iterator();
228 while (it.hasNext()) {
229 data.add(it.next().data);
234 // Inject security context
235 public static final class SecureData<T> {
236 private final T data;
237 private final Authentication auth;
239 private SecureData(T data) {
241 this.auth = AuthenticationManager.instance().get();
244 @SuppressWarnings("rawtypes")
246 public boolean equals(Object o) {
250 return (o instanceof SecureData) ? data.equals(((SecureData) o).data) : false;
254 public int hashCode() {
255 return data.hashCode();