Search in sources :

Example 76 with AtomicReference

use of java.util.concurrent.atomic.AtomicReference in project jetty.project by eclipse.

the class FlowControlStrategyTest method testServerTwoDataFramesWithStalledStream.

// TODO
// Since we changed the API to disallow consecutive data() calls without waiting
// for the callback, it is now not possible to have DATA1, DATA2 in the queue for
// the same stream. Perhaps this test should just be deleted.
@Ignore
@Test
public void testServerTwoDataFramesWithStalledStream() throws Exception {
    // Frames in queue = DATA1, DATA2.
    // Server writes part of DATA1, then stalls.
    // A window update unstalls the session, verify that the data is correctly sent.
    Random random = new Random();
    final byte[] chunk1 = new byte[1024];
    random.nextBytes(chunk1);
    final byte[] chunk2 = new byte[2048];
    random.nextBytes(chunk2);
    // Two SETTINGS frames: the initial after the preface,
    // and the explicit where we set the stream window size to zero.
    final AtomicReference<CountDownLatch> settingsLatch = new AtomicReference<>(new CountDownLatch(2));
    final CountDownLatch dataLatch = new CountDownLatch(1);
    start(new ServerSessionListener.Adapter() {

        @Override
        public void onSettings(Session session, SettingsFrame frame) {
            settingsLatch.get().countDown();
        }

        @Override
        public Stream.Listener onNewStream(Stream stream, HeadersFrame frame) {
            stream.data(new DataFrame(stream.getId(), ByteBuffer.wrap(chunk1), false), Callback.NOOP);
            stream.data(new DataFrame(stream.getId(), ByteBuffer.wrap(chunk2), true), Callback.NOOP);
            dataLatch.countDown();
            return null;
        }
    });
    Session session = newClient(new Session.Listener.Adapter());
    Map<Integer, Integer> settings = new HashMap<>();
    settings.put(SettingsFrame.INITIAL_WINDOW_SIZE, 0);
    session.settings(new SettingsFrame(settings, false), Callback.NOOP);
    Assert.assertTrue(settingsLatch.get().await(5, TimeUnit.SECONDS));
    byte[] content = new byte[chunk1.length + chunk2.length];
    final ByteBuffer buffer = ByteBuffer.wrap(content);
    MetaData.Request metaData = newRequest("GET", new HttpFields());
    HeadersFrame requestFrame = new HeadersFrame(metaData, null, true);
    final CountDownLatch responseLatch = new CountDownLatch(1);
    session.newStream(requestFrame, new Promise.Adapter<>(), new Stream.Listener.Adapter() {

        @Override
        public void onData(Stream stream, DataFrame frame, Callback callback) {
            buffer.put(frame.getData());
            callback.succeeded();
            if (frame.isEndStream())
                responseLatch.countDown();
        }
    });
    Assert.assertTrue(dataLatch.await(5, TimeUnit.SECONDS));
    // Now we have the 2 DATA frames queued in the server.
    // Unstall the stream window.
    settingsLatch.set(new CountDownLatch(1));
    settings.clear();
    settings.put(SettingsFrame.INITIAL_WINDOW_SIZE, chunk1.length / 2);
    session.settings(new SettingsFrame(settings, false), Callback.NOOP);
    Assert.assertTrue(settingsLatch.get().await(5, TimeUnit.SECONDS));
    Assert.assertTrue(responseLatch.await(5, TimeUnit.SECONDS));
    // Check that the data is sent correctly.
    byte[] expected = new byte[content.length];
    System.arraycopy(chunk1, 0, expected, 0, chunk1.length);
    System.arraycopy(chunk2, 0, expected, chunk1.length, chunk2.length);
    Assert.assertArrayEquals(expected, content);
}
Also used : ServerSessionListener(org.eclipse.jetty.http2.api.server.ServerSessionListener) HashMap(java.util.HashMap) HeadersFrame(org.eclipse.jetty.http2.frames.HeadersFrame) SettingsFrame(org.eclipse.jetty.http2.frames.SettingsFrame) Random(java.util.Random) MetaData(org.eclipse.jetty.http.MetaData) HttpFields(org.eclipse.jetty.http.HttpFields) HTTP2Stream(org.eclipse.jetty.http2.HTTP2Stream) Stream(org.eclipse.jetty.http2.api.Stream) AtomicReference(java.util.concurrent.atomic.AtomicReference) DataFrame(org.eclipse.jetty.http2.frames.DataFrame) CountDownLatch(java.util.concurrent.CountDownLatch) ByteBuffer(java.nio.ByteBuffer) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) FuturePromise(org.eclipse.jetty.util.FuturePromise) Promise(org.eclipse.jetty.util.Promise) Callback(org.eclipse.jetty.util.Callback) FutureCallback(org.eclipse.jetty.util.FutureCallback) ServerSessionListener(org.eclipse.jetty.http2.api.server.ServerSessionListener) HTTP2Session(org.eclipse.jetty.http2.HTTP2Session) Session(org.eclipse.jetty.http2.api.Session) ISession(org.eclipse.jetty.http2.ISession) Ignore(org.junit.Ignore) Test(org.junit.Test)

Example 77 with AtomicReference

use of java.util.concurrent.atomic.AtomicReference in project jetty.project by eclipse.

the class PrefaceTest method testOnPrefaceNotifiedForStandardUpgrade.

@Test
public void testOnPrefaceNotifiedForStandardUpgrade() throws Exception {
    Integer maxConcurrentStreams = 128;
    AtomicReference<CountDownLatch> serverPrefaceLatch = new AtomicReference<>(new CountDownLatch(1));
    AtomicReference<CountDownLatch> serverSettingsLatch = new AtomicReference<>(new CountDownLatch(1));
    HttpConfiguration config = new HttpConfiguration();
    prepareServer(new HttpConnectionFactory(config), new HTTP2CServerConnectionFactory(config) {

        @Override
        protected ServerSessionListener newSessionListener(Connector connector, EndPoint endPoint) {
            return new ServerSessionListener.Adapter() {

                @Override
                public Map<Integer, Integer> onPreface(Session session) {
                    Map<Integer, Integer> serverSettings = new HashMap<>();
                    serverSettings.put(SettingsFrame.MAX_CONCURRENT_STREAMS, maxConcurrentStreams);
                    serverPrefaceLatch.get().countDown();
                    return serverSettings;
                }

                @Override
                public void onSettings(Session session, SettingsFrame frame) {
                    serverSettingsLatch.get().countDown();
                }

                @Override
                public Stream.Listener onNewStream(Stream stream, HeadersFrame frame) {
                    MetaData.Response response = new MetaData.Response(HttpVersion.HTTP_2, HttpStatus.OK_200, new HttpFields());
                    stream.headers(new HeadersFrame(stream.getId(), response, null, true), Callback.NOOP);
                    return null;
                }
            };
        }
    });
    server.start();
    ByteBufferPool byteBufferPool = new MappedByteBufferPool();
    try (SocketChannel socket = SocketChannel.open()) {
        socket.connect(new InetSocketAddress("localhost", connector.getLocalPort()));
        String upgradeRequest = "" + "GET /one HTTP/1.1\r\n" + "Host: localhost\r\n" + "Connection: Upgrade, HTTP2-Settings\r\n" + "Upgrade: h2c\r\n" + "HTTP2-Settings: \r\n" + "\r\n";
        ByteBuffer upgradeBuffer = ByteBuffer.wrap(upgradeRequest.getBytes(StandardCharsets.ISO_8859_1));
        socket.write(upgradeBuffer);
        // Make sure onPreface() is called on server.
        Assert.assertTrue(serverPrefaceLatch.get().await(5, TimeUnit.SECONDS));
        Assert.assertTrue(serverSettingsLatch.get().await(5, TimeUnit.SECONDS));
        // The 101 response is the reply to the client preface SETTINGS frame.
        ByteBuffer buffer = byteBufferPool.acquire(1024, true);
        http1: while (true) {
            BufferUtil.clearToFill(buffer);
            int read = socket.read(buffer);
            BufferUtil.flipToFlush(buffer, 0);
            if (read < 0)
                Assert.fail();
            int crlfs = 0;
            while (buffer.hasRemaining()) {
                byte b = buffer.get();
                if (b == '\r' || b == '\n')
                    ++crlfs;
                else
                    crlfs = 0;
                if (crlfs == 4)
                    break http1;
            }
        }
        // Reset the latches on server.
        serverPrefaceLatch.set(new CountDownLatch(1));
        serverSettingsLatch.set(new CountDownLatch(1));
        // After the 101, the client must send the connection preface.
        Generator generator = new Generator(byteBufferPool);
        ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
        generator.control(lease, new PrefaceFrame());
        Map<Integer, Integer> clientSettings = new HashMap<>();
        clientSettings.put(SettingsFrame.ENABLE_PUSH, 1);
        generator.control(lease, new SettingsFrame(clientSettings, false));
        List<ByteBuffer> buffers = lease.getByteBuffers();
        socket.write(buffers.toArray(new ByteBuffer[buffers.size()]));
        // However, we should not call onPreface() again.
        Assert.assertFalse(serverPrefaceLatch.get().await(1, TimeUnit.SECONDS));
        // Although we should notify of the SETTINGS frame.
        Assert.assertTrue(serverSettingsLatch.get().await(5, TimeUnit.SECONDS));
        CountDownLatch clientSettingsLatch = new CountDownLatch(1);
        AtomicBoolean responded = new AtomicBoolean();
        Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter() {

            @Override
            public void onSettings(SettingsFrame frame) {
                if (frame.isReply())
                    return;
                Assert.assertEquals(maxConcurrentStreams, frame.getSettings().get(SettingsFrame.MAX_CONCURRENT_STREAMS));
                clientSettingsLatch.countDown();
            }

            @Override
            public void onHeaders(HeadersFrame frame) {
                if (frame.isEndStream())
                    responded.set(true);
            }
        }, 4096, 8192);
        // HTTP/2 parsing.
        while (true) {
            parser.parse(buffer);
            if (responded.get())
                break;
            BufferUtil.clearToFill(buffer);
            int read = socket.read(buffer);
            BufferUtil.flipToFlush(buffer, 0);
            if (read < 0)
                Assert.fail();
        }
        Assert.assertTrue(clientSettingsLatch.await(5, TimeUnit.SECONDS));
    }
}
Also used : ByteBufferPool(org.eclipse.jetty.io.ByteBufferPool) MappedByteBufferPool(org.eclipse.jetty.io.MappedByteBufferPool) Connector(org.eclipse.jetty.server.Connector) SocketChannel(java.nio.channels.SocketChannel) ServerSessionListener(org.eclipse.jetty.http2.api.server.ServerSessionListener) HashMap(java.util.HashMap) InetSocketAddress(java.net.InetSocketAddress) HttpConfiguration(org.eclipse.jetty.server.HttpConfiguration) EndPoint(org.eclipse.jetty.io.EndPoint) HeadersFrame(org.eclipse.jetty.http2.frames.HeadersFrame) SettingsFrame(org.eclipse.jetty.http2.frames.SettingsFrame) HTTP2CServerConnectionFactory(org.eclipse.jetty.http2.server.HTTP2CServerConnectionFactory) MetaData(org.eclipse.jetty.http.MetaData) HttpFields(org.eclipse.jetty.http.HttpFields) Stream(org.eclipse.jetty.http2.api.Stream) HttpConnectionFactory(org.eclipse.jetty.server.HttpConnectionFactory) AtomicReference(java.util.concurrent.atomic.AtomicReference) CountDownLatch(java.util.concurrent.CountDownLatch) ByteBuffer(java.nio.ByteBuffer) EndPoint(org.eclipse.jetty.io.EndPoint) Parser(org.eclipse.jetty.http2.parser.Parser) MappedByteBufferPool(org.eclipse.jetty.io.MappedByteBufferPool) PrefaceFrame(org.eclipse.jetty.http2.frames.PrefaceFrame) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) HashMap(java.util.HashMap) Map(java.util.Map) ServerSessionListener(org.eclipse.jetty.http2.api.server.ServerSessionListener) Session(org.eclipse.jetty.http2.api.Session) Generator(org.eclipse.jetty.http2.generator.Generator) Test(org.junit.Test)

Example 78 with AtomicReference

use of java.util.concurrent.atomic.AtomicReference in project jetty.project by eclipse.

the class StreamResetTest method testStreamReceivingResetIsRemoved.

@Test
public void testStreamReceivingResetIsRemoved() throws Exception {
    final AtomicReference<Stream> streamRef = new AtomicReference<>();
    final CountDownLatch resetLatch = new CountDownLatch(1);
    start(new ServerSessionListener.Adapter() {

        @Override
        public Stream.Listener onNewStream(Stream stream, HeadersFrame frame) {
            return new Stream.Listener.Adapter() {

                @Override
                public void onReset(Stream stream, ResetFrame frame) {
                    Assert.assertNotNull(stream);
                    Assert.assertTrue(stream.isReset());
                    streamRef.set(stream);
                    resetLatch.countDown();
                }
            };
        }
    });
    Session client = newClient(new Session.Listener.Adapter());
    MetaData.Request request = newRequest("GET", new HttpFields());
    HeadersFrame requestFrame = new HeadersFrame(request, null, false);
    FuturePromise<Stream> promise = new FuturePromise<>();
    client.newStream(requestFrame, promise, new Stream.Listener.Adapter());
    Stream stream = promise.get(5, TimeUnit.SECONDS);
    ResetFrame resetFrame = new ResetFrame(stream.getId(), ErrorCode.CANCEL_STREAM_ERROR.code);
    stream.reset(resetFrame, Callback.NOOP);
    Assert.assertTrue(resetLatch.await(5, TimeUnit.SECONDS));
    // Wait a while to let the server remove the
    // stream after returning from onReset().
    Thread.sleep(1000);
    Stream serverStream = streamRef.get();
    Assert.assertEquals(0, serverStream.getSession().getStreams().size());
}
Also used : ServerSessionListener(org.eclipse.jetty.http2.api.server.ServerSessionListener) WriteListener(javax.servlet.WriteListener) FuturePromise(org.eclipse.jetty.util.FuturePromise) AtomicReference(java.util.concurrent.atomic.AtomicReference) CountDownLatch(java.util.concurrent.CountDownLatch) HeadersFrame(org.eclipse.jetty.http2.frames.HeadersFrame) MetaData(org.eclipse.jetty.http.MetaData) HttpFields(org.eclipse.jetty.http.HttpFields) Stream(org.eclipse.jetty.http2.api.Stream) ServletOutputStream(javax.servlet.ServletOutputStream) IStream(org.eclipse.jetty.http2.IStream) ResetFrame(org.eclipse.jetty.http2.frames.ResetFrame) ServerSessionListener(org.eclipse.jetty.http2.api.server.ServerSessionListener) Session(org.eclipse.jetty.http2.api.Session) ISession(org.eclipse.jetty.http2.ISession) Test(org.junit.Test)

Example 79 with AtomicReference

use of java.util.concurrent.atomic.AtomicReference in project jetty.project by eclipse.

the class MongoSessionDataStore method load.

/** 
     * @see org.eclipse.jetty.server.session.SessionDataStore#load(String)
     */
@Override
public SessionData load(String id) throws Exception {
    final AtomicReference<SessionData> reference = new AtomicReference<SessionData>();
    final AtomicReference<Exception> exception = new AtomicReference<Exception>();
    Runnable r = new Runnable() {

        public void run() {
            try {
                DBObject sessionDocument = _dbSessions.findOne(new BasicDBObject(__ID, id));
                if (LOG.isDebugEnabled())
                    LOG.debug("id={} loaded={}", id, sessionDocument);
                if (sessionDocument == null)
                    return;
                Boolean valid = (Boolean) sessionDocument.get(__VALID);
                if (LOG.isDebugEnabled())
                    LOG.debug("id={} valid={}", id, valid);
                if (valid == null || !valid)
                    return;
                Object version = getNestedValue(sessionDocument, getContextSubfield(__VERSION));
                Long lastSaved = (Long) getNestedValue(sessionDocument, getContextSubfield(__LASTSAVED));
                String lastNode = (String) getNestedValue(sessionDocument, getContextSubfield(__LASTNODE));
                Long created = (Long) sessionDocument.get(__CREATED);
                Long accessed = (Long) sessionDocument.get(__ACCESSED);
                Long maxInactive = (Long) sessionDocument.get(__MAX_IDLE);
                Long expiry = (Long) sessionDocument.get(__EXPIRY);
                NoSqlSessionData data = null;
                // get the session for the context
                DBObject sessionSubDocumentForContext = (DBObject) getNestedValue(sessionDocument, getContextField());
                if (LOG.isDebugEnabled())
                    LOG.debug("attrs {}", sessionSubDocumentForContext);
                if (sessionSubDocumentForContext != null) {
                    if (LOG.isDebugEnabled())
                        LOG.debug("Session {} present for context {}", id, _context);
                    //only load a session if it exists for this context
                    data = (NoSqlSessionData) newSessionData(id, created, accessed, accessed, maxInactive);
                    data.setVersion(version);
                    data.setExpiry(expiry);
                    data.setContextPath(_context.getCanonicalContextPath());
                    data.setVhost(_context.getVhost());
                    data.setLastSaved(lastSaved);
                    data.setLastNode(lastNode);
                    HashMap<String, Object> attributes = new HashMap<>();
                    for (String name : sessionSubDocumentForContext.keySet()) {
                        //skip special metadata attribute which is not one of the actual session attributes
                        if (__METADATA.equals(name))
                            continue;
                        String attr = decodeName(name);
                        Object value = decodeValue(sessionSubDocumentForContext.get(name));
                        attributes.put(attr, value);
                    }
                    data.putAllAttributes(attributes);
                } else {
                    if (LOG.isDebugEnabled())
                        LOG.debug("Session  {} not present for context {}", id, _context);
                }
                reference.set(data);
            } catch (Exception e) {
                exception.set(e);
            }
        }
    };
    _context.run(r);
    if (exception.get() != null)
        throw exception.get();
    return reference.get();
}
Also used : HashMap(java.util.HashMap) AtomicReference(java.util.concurrent.atomic.AtomicReference) SessionData(org.eclipse.jetty.server.session.SessionData) DBObject(com.mongodb.DBObject) BasicDBObject(com.mongodb.BasicDBObject) MongoException(com.mongodb.MongoException) IOException(java.io.IOException) BasicDBObject(com.mongodb.BasicDBObject) DBObject(com.mongodb.DBObject) BasicDBObject(com.mongodb.BasicDBObject)

Example 80 with AtomicReference

use of java.util.concurrent.atomic.AtomicReference in project jetty.project by eclipse.

the class JDBCSessionDataStore method load.

/** 
     * @see org.eclipse.jetty.server.session.SessionDataStore#load(java.lang.String)
     */
@Override
public SessionData load(String id) throws Exception {
    final AtomicReference<SessionData> reference = new AtomicReference<SessionData>();
    final AtomicReference<Exception> exception = new AtomicReference<Exception>();
    Runnable r = new Runnable() {

        public void run() {
            try (Connection connection = _dbAdaptor.getConnection();
                PreparedStatement statement = _sessionTableSchema.getLoadStatement(connection, id, _context);
                ResultSet result = statement.executeQuery()) {
                SessionData data = null;
                if (result.next()) {
                    data = newSessionData(id, result.getLong(_sessionTableSchema.getCreateTimeColumn()), result.getLong(_sessionTableSchema.getAccessTimeColumn()), result.getLong(_sessionTableSchema.getLastAccessTimeColumn()), result.getLong(_sessionTableSchema.getMaxIntervalColumn()));
                    data.setCookieSet(result.getLong(_sessionTableSchema.getCookieTimeColumn()));
                    data.setLastNode(result.getString(_sessionTableSchema.getLastNodeColumn()));
                    data.setLastSaved(result.getLong(_sessionTableSchema.getLastSavedTimeColumn()));
                    data.setExpiry(result.getLong(_sessionTableSchema.getExpiryTimeColumn()));
                    //TODO needed? this is part of the key now
                    data.setContextPath(result.getString(_sessionTableSchema.getContextPathColumn()));
                    //TODO needed??? this is part of the key now
                    data.setVhost(result.getString(_sessionTableSchema.getVirtualHostColumn()));
                    try (InputStream is = _dbAdaptor.getBlobInputStream(result, _sessionTableSchema.getMapColumn());
                        ClassLoadingObjectInputStream ois = new ClassLoadingObjectInputStream(is)) {
                        Object o = ois.readObject();
                        data.putAllAttributes((Map<String, Object>) o);
                    } catch (Exception e) {
                        throw new UnreadableSessionDataException(id, _context, e);
                    }
                    if (LOG.isDebugEnabled())
                        LOG.debug("LOADED session {}", data);
                } else if (LOG.isDebugEnabled())
                    LOG.debug("No session {}", id);
                reference.set(data);
            } catch (Exception e) {
                exception.set(e);
            }
        }
    };
    //ensure this runs with context classloader set
    _context.run(r);
    if (exception.get() != null)
        throw exception.get();
    return reference.get();
}
Also used : ClassLoadingObjectInputStream(org.eclipse.jetty.util.ClassLoadingObjectInputStream) ClassLoadingObjectInputStream(org.eclipse.jetty.util.ClassLoadingObjectInputStream) ByteArrayInputStream(java.io.ByteArrayInputStream) InputStream(java.io.InputStream) Connection(java.sql.Connection) AtomicReference(java.util.concurrent.atomic.AtomicReference) PreparedStatement(java.sql.PreparedStatement) SQLException(java.sql.SQLException) ResultSet(java.sql.ResultSet)

Aggregations

AtomicReference (java.util.concurrent.atomic.AtomicReference)1331 Test (org.junit.Test)668 CountDownLatch (java.util.concurrent.CountDownLatch)437 IOException (java.io.IOException)263 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)205 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)159 ArrayList (java.util.ArrayList)108 HashMap (java.util.HashMap)105 List (java.util.List)95 Map (java.util.Map)77 Test (org.testng.annotations.Test)76 File (java.io.File)64 ExecutionException (java.util.concurrent.ExecutionException)60 HashSet (java.util.HashSet)54 URI (java.net.URI)48 TimeoutException (java.util.concurrent.TimeoutException)48 HttpServletRequest (javax.servlet.http.HttpServletRequest)48 HttpServletResponse (javax.servlet.http.HttpServletResponse)46 MockResponse (okhttp3.mockwebserver.MockResponse)46 ByteBuffer (java.nio.ByteBuffer)44