Search in sources :

Example 1 with WireAdapter

use of org.glassfish.contextpropagation.wireadapters.WireAdapter in project Payara by payara.

the class Utils method getScopeAwarePropagator.

/**
 * @return The in-scope instance of ContextMapPropagator so that
 * communication protocols can ask the ContextMapPropagator to handle
 * the context propagation bytes on the wire.
 */
public static ContextMapPropagator getScopeAwarePropagator() {
    return new ContextMapPropagator() {

        private WireAdapter wireAdapter = ContextBootstrap.getWireAdapter();

        private SimpleMap getMapIfItExists() {
            AccessControlledMap map = mapFinder.getMapIfItExists();
            return map == null ? null : map.simpleMap;
        }

        private SimpleMap getMapAndCreateIfNeeded() {
            return mapFinder.getMapAndCreateIfNeeded().simpleMap;
        }

        @Override
        public void sendRequest(OutputStream out, PropagationMode propagationMode) throws IOException {
            sendItems(propagationModeFilter, out, propagationMode, true);
        }

        @Override
        public void sendResponse(OutputStream out, PropagationMode propagationMode) throws IOException {
            sendItems(onewayPropagationModeFilter, out, propagationMode, false);
        }

        private void sendItems(Filter filter, OutputStream out, PropagationMode propagationMode, boolean sendLocation) throws IOException {
            ContextBootstrap.debug(MessageID.PROPAGATION_STARTED, "Outgoing");
            SimpleMap map = getMapIfItExists();
            if (map != null) {
                ContextBootstrap.debug(MessageID.USING_WIRE_ADAPTER, "Writing to", wireAdapter);
                wireAdapter.prepareToWriteTo(out);
                Iterator<Map.Entry<String, Entry>> items = map.iterator(filter, propagationMode);
                while (items.hasNext()) {
                    Map.Entry<String, Entry> mapEntry = items.next();
                    Entry entry = mapEntry.getValue();
                    Object value = entry.getValue();
                    if (value instanceof ContextLifecycle) {
                        ((ContextLifecycle) value).contextToPropagate();
                    }
                }
                items = map.iterator(filter, propagationMode);
                while (items.hasNext()) {
                    Map.Entry<String, Entry> mapEntry = items.next();
                    wireAdapter.write(mapEntry.getKey(), mapEntry.getValue());
                }
                wireAdapter.flush();
            }
            ContextBootstrap.debug(MessageID.PROPAGATION_COMPLETED, "Outgoing");
        }

        @Override
        public void receiveRequest(InputStream in) throws IOException {
            receive(in, new OriginatorFinder() {

                public boolean isOriginator(String key) {
                    return IS_NOT_ORIGINATOR;
                }
            });
        }

        private void receive(InputStream in, OriginatorFinder origFinder) throws IOException {
            ContextBootstrap.debug(MessageID.PROPAGATION_STARTED, "Ingoing");
            ContextAccessController accessController = ContextBootstrap.getContextAccessController();
            wireAdapter.prepareToReadFrom(in);
            SimpleMap map = getMapAndCreateIfNeeded();
            map.prepareToPropagate();
            for (String key = wireAdapter.readKey(); key != null; key = wireAdapter.readKey()) {
                try {
                    Entry entry = wireAdapter.readEntry();
                    if (entry == null) {
                        break;
                    } else {
                        entry.init(origFinder.isOriginator(key), accessController.isEveryoneAllowedToRead(key));
                        map.put(key, entry);
                    }
                } catch (ClassNotFoundException e) {
                    ContextBootstrap.getLoggerAdapter().log(Level.ERROR, e, MessageID.ERROR_UNABLE_TO_INSTANTIATE_CONTEXT_FROM_THE_WIRE);
                }
            }
            for (ContextLifecycle context : map.getAddedContextLifecycles()) {
                context.contextAdded();
            }
            ContextBootstrap.debug(MessageID.PROPAGATION_COMPLETED, "Ingoing");
        }

        @Override
        public void receiveResponse(InputStream in, PropagationMode mode) throws IOException {
            SimpleMap map = getMapAndCreateIfNeeded();
            final Set<String> keySet = clearPropagatedEntries(mode, map);
            ContextBootstrap.debug(MessageID.CLEARED_ENTRIES, keySet);
            receive(in, new OriginatorFinder() {

                @Override
                public boolean isOriginator(String key) {
                    return keySet.contains(key);
                }
            });
        }

        private Set<String> clearPropagatedEntries(PropagationMode mode, SimpleMap map) {
            Set<String> keySet = new HashSet<String>();
            Iterator<Map.Entry<String, Entry>> iterator = map.iterator(new Filter() {

                @Override
                public boolean keep(Map.Entry<String, Entry> mapEntry, PropagationMode mode) {
                    EnumSet<PropagationMode> modes = mapEntry.getValue().propagationModes;
                    return modes.contains(mode);
                }
            }, mode);
            while (iterator.hasNext()) {
                keySet.add(iterator.next().getKey());
                iterator.remove();
            }
            return keySet;
        }

        /**
         * Replaces the in-scope ContextMap entries with those in the srcContexts
         * that have the THREAD propagation mode.
         */
        @Override
        public void restoreThreadContexts(final AccessControlledMap srcContexts) {
            if (ContextBootstrap.IS_DEBUG) {
                ContextBootstrap.debug(MessageID.RESTORING_CONTEXTS, asList(srcContexts.entryIterator()));
            }
            if (srcContexts == null) {
                throw new IllegalArgumentException("You must specify a ContextMap.");
            }
            SimpleMap srcSimpleMap = srcContexts.simpleMap;
            if (!srcSimpleMap.map.isEmpty()) {
                SimpleMap destSimpleMap = mapFinder.getMapAndCreateIfNeeded().simpleMap;
                destSimpleMap.prepareToPropagate();
                if (destSimpleMap == srcSimpleMap) {
                    throw new IllegalArgumentException("Cannot restore a ContextMap on itself. The source and destination maps must not be the same.");
                }
                Iterator<Map.Entry<String, Entry>> iterator = srcSimpleMap.iterator(propagationModeFilter, PropagationMode.THREAD);
                while (iterator.hasNext()) {
                    Map.Entry<String, Entry> mapEntry = iterator.next();
                    destSimpleMap.put(mapEntry.getKey(), mapEntry.getValue());
                }
                for (ContextLifecycle context : destSimpleMap.getAddedContextLifecycles()) {
                    context.contextAdded();
                }
                if (ContextBootstrap.IS_DEBUG) {
                    ContextBootstrap.debug(MessageID.RESTORING_CONTEXTS, asList(mapFinder.getMapIfItExists().entryIterator()));
                }
            }
        }

        private LinkedList<String> asList(final Iterator<Map.Entry<String, Entry>> mapEntries) {
            LinkedList<String> list = new LinkedList<String>();
            while (mapEntries.hasNext()) {
                Map.Entry<String, Entry> mapEntry = mapEntries.next();
                list.add(mapEntry.getKey() + ": " + mapEntry.getValue());
            }
            return list;
        }

        @Override
        public void useWireAdapter(WireAdapter aWireAdapter) {
            wireAdapter = aWireAdapter;
        }
    };
}
Also used : ContextAccessController(org.glassfish.contextpropagation.bootstrap.ContextAccessController) OutputStream(java.io.OutputStream) Iterator(java.util.Iterator) HashSet(java.util.HashSet) ContextLifecycle(org.glassfish.contextpropagation.ContextLifecycle) InputStream(java.io.InputStream) WireAdapter(org.glassfish.contextpropagation.wireadapters.WireAdapter) EnumSet(java.util.EnumSet) LinkedList(java.util.LinkedList) ContextMapPropagator(org.glassfish.contextpropagation.spi.ContextMapPropagator) Filter(org.glassfish.contextpropagation.internal.SimpleMap.Filter) PropagationMode(org.glassfish.contextpropagation.PropagationMode) HashMap(java.util.HashMap) Map(java.util.Map) ContextMap(org.glassfish.contextpropagation.ContextMap)

Aggregations

InputStream (java.io.InputStream)1 OutputStream (java.io.OutputStream)1 EnumSet (java.util.EnumSet)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 Iterator (java.util.Iterator)1 LinkedList (java.util.LinkedList)1 Map (java.util.Map)1 ContextLifecycle (org.glassfish.contextpropagation.ContextLifecycle)1 ContextMap (org.glassfish.contextpropagation.ContextMap)1 PropagationMode (org.glassfish.contextpropagation.PropagationMode)1 ContextAccessController (org.glassfish.contextpropagation.bootstrap.ContextAccessController)1 Filter (org.glassfish.contextpropagation.internal.SimpleMap.Filter)1 ContextMapPropagator (org.glassfish.contextpropagation.spi.ContextMapPropagator)1 WireAdapter (org.glassfish.contextpropagation.wireadapters.WireAdapter)1