Author: markt
Date: Wed May 13 17:44:47 2015
New Revision: 1679251
URL: http://svn.apache.org/r1679251
Log:
Lay some groundwork for processing priority frames
Added:
tomcat/trunk/java/org/apache/coyote/http2/AbstractStream.java (with props)
tomcat/trunk/test/org/apache/coyote/http2/TestAbstractStream.java (with
props)
Modified:
tomcat/trunk/java/org/apache/coyote/http2/Http2UpgradeHandler.java
tomcat/trunk/java/org/apache/coyote/http2/Stream.java
Added: tomcat/trunk/java/org/apache/coyote/http2/AbstractStream.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http2/AbstractStream.java?rev=1679251&view=auto
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http2/AbstractStream.java (added)
+++ tomcat/trunk/java/org/apache/coyote/http2/AbstractStream.java Wed May 13
17:44:47 2015
@@ -0,0 +1,113 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.coyote.http2;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+/**
+ * Used to managed prioritisation.
+ */
+abstract class AbstractStream {
+
+ private static final int DEFAULT_WEIGHT = 16;
+
+ private final Integer identifier;
+
+ private volatile AbstractStream parentStream = null;
+ private final Set<AbstractStream> childStreams = new HashSet<>();
+ private volatile int weight = DEFAULT_WEIGHT;
+
+ public Integer getIdentifier() {
+ return identifier;
+ }
+
+
+ public AbstractStream(Integer identifier) {
+ this.identifier = identifier;
+ }
+
+
+ public void rePrioritise(Stream parent, boolean exclusive, int weight) {
+ // Check if new parent is a descendant of this stream
+ if (isDescendant(parent)) {
+ parent.detachFromParent();
+ parentStream.addChild(parent);
+ }
+
+ if (exclusive) {
+ // Need to move children of the new parent to be children of this
+ // stream. Slightly convoluted to avoid concurrent modification.
+ Iterator<AbstractStream> parentsChildren =
parent.getChildStreams().iterator();
+ while (parentsChildren.hasNext()) {
+ AbstractStream parentsChild = parentsChildren.next();
+ parentsChildren.remove();
+ this.addChild(parentsChild);
+ }
+ }
+ parent.addChild(this);
+ this.weight = weight;
+ }
+
+
+ void detachFromParent() {
+ if (parentStream != null) {
+ parentStream.getChildStreams().remove(this);
+ parentStream = null;
+ }
+ }
+
+
+ void addChild(AbstractStream child) {
+ child.setParent(this);
+ childStreams.add(child);
+ }
+
+
+ private void setParent(AbstractStream parent) {
+ this.parentStream = parent;
+ }
+
+
+ boolean isDescendant(AbstractStream stream) {
+ if (childStreams.contains(stream)) {
+ return true;
+ }
+ for (AbstractStream child : childStreams) {
+ if (child.isDescendant(stream)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+
+ AbstractStream getParentStream() {
+ return parentStream;
+ }
+
+
+ void setParentStream(AbstractStream parentStream) {
+ this.parentStream = parentStream;
+ }
+
+
+ Set<AbstractStream> getChildStreams() {
+ return childStreams;
+ }
+}
Propchange: tomcat/trunk/java/org/apache/coyote/http2/AbstractStream.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: tomcat/trunk/java/org/apache/coyote/http2/Http2UpgradeHandler.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http2/Http2UpgradeHandler.java?rev=1679251&r1=1679250&r2=1679251&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http2/Http2UpgradeHandler.java
(original)
+++ tomcat/trunk/java/org/apache/coyote/http2/Http2UpgradeHandler.java Wed May
13 17:44:47 2015
@@ -45,11 +45,13 @@ import org.apache.tomcat.util.res.String
* network.http.spdy.enforce-tls-profile=false in order for FireFox to be able
* to connect.
*/
-public class Http2UpgradeHandler implements InternalHttpUpgradeHandler {
+public class Http2UpgradeHandler extends AbstractStream implements
InternalHttpUpgradeHandler {
private static final Log log =
LogFactory.getLog(Http2UpgradeHandler.class);
private static final StringManager sm =
StringManager.getManager(Http2UpgradeHandler.class);
+ private static final Integer STREAM_ID_ZERO = Integer.valueOf(0);
+
private static final int FRAME_TYPE_SETTINGS = 4;
private static final int FRAME_TYPE_WINDOW_UPDATE = 8;
@@ -68,6 +70,12 @@ public class Http2UpgradeHandler impleme
private final Map<Integer,Stream> streams = new HashMap<>();
+
+ public Http2UpgradeHandler() {
+ super (STREAM_ID_ZERO);
+ }
+
+
@Override
public void init(WebConnection unused) {
initialized = true;
@@ -271,7 +279,7 @@ public class Http2UpgradeHandler impleme
Integer key = Integer.valueOf(streamId);
Stream stream = streams.get(key);
if (stream == null) {
- stream = new Stream(key,
remoteSettings.getInitialWindowSize());
+ stream = new Stream(key, this);
}
stream.incrementWindowSize(windowSizeIncrement);
}
@@ -362,6 +370,11 @@ public class Http2UpgradeHandler impleme
}
+ ConnectionSettings getRemoteSettings() {
+ return remoteSettings;
+ }
+
+
@Override
public void destroy() {
// NO-OP
Modified: tomcat/trunk/java/org/apache/coyote/http2/Stream.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http2/Stream.java?rev=1679251&r1=1679250&r2=1679251&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http2/Stream.java (original)
+++ tomcat/trunk/java/org/apache/coyote/http2/Stream.java Wed May 13 17:44:47
2015
@@ -16,20 +16,15 @@
*/
package org.apache.coyote.http2;
-public class Stream {
-
- private final Integer identifier;
+public class Stream extends AbstractStream {
private volatile long flowControlWindowSize;
- public Stream(Integer identifier, long intitalWindowSize) {
- this.identifier = identifier;
- flowControlWindowSize = intitalWindowSize;
- }
-
- public Integer getIdentifier() {
- return identifier;
+ public Stream(Integer identifier, Http2UpgradeHandler handler) {
+ super(identifier);
+ setParentStream(handler);
+ flowControlWindowSize =
handler.getRemoteSettings().getInitialWindowSize();
}
Added: tomcat/trunk/test/org/apache/coyote/http2/TestAbstractStream.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/coyote/http2/TestAbstractStream.java?rev=1679251&view=auto
==============================================================================
--- tomcat/trunk/test/org/apache/coyote/http2/TestAbstractStream.java (added)
+++ tomcat/trunk/test/org/apache/coyote/http2/TestAbstractStream.java Wed May
13 17:44:47 2015
@@ -0,0 +1,172 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.coyote.http2;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+/*
+ * This tests use A=1, B=2, etc to map stream IDs to the names used in the
+ * figures.
+ */
+public class TestAbstractStream {
+
+ @Test
+ public void testDependenciesFig3() {
+ // Setup
+ Http2UpgradeHandler handler = new Http2UpgradeHandler();
+ Stream a = new Stream(Integer.valueOf(1), handler);
+ Stream b = new Stream(Integer.valueOf(2), handler);
+ Stream c = new Stream(Integer.valueOf(3), handler);
+ Stream d = new Stream(Integer.valueOf(4), handler);
+ b.rePrioritise(a, false, 16);
+ c.rePrioritise(a, false, 16);
+
+ // Action
+ d.rePrioritise(a, false, 16);
+
+ // Check parents
+ Assert.assertEquals(handler, a.getParentStream());
+ Assert.assertEquals(a, b.getParentStream());
+ Assert.assertEquals(a, c.getParentStream());
+ Assert.assertEquals(a, d.getParentStream());
+
+ // Check children
+ Assert.assertEquals(3, a.getChildStreams().size());
+ Assert.assertTrue(a.getChildStreams().contains(b));
+ Assert.assertTrue(a.getChildStreams().contains(c));
+ Assert.assertTrue(a.getChildStreams().contains(d));
+ Assert.assertEquals(0, b.getChildStreams().size());
+ Assert.assertEquals(0, c.getChildStreams().size());
+ Assert.assertEquals(0, d.getChildStreams().size());
+ }
+
+
+ @Test
+ public void testDependenciesFig4() {
+ // Setup
+ Http2UpgradeHandler handler = new Http2UpgradeHandler();
+ Stream a = new Stream(Integer.valueOf(1), handler);
+ Stream b = new Stream(Integer.valueOf(2), handler);
+ Stream c = new Stream(Integer.valueOf(3), handler);
+ Stream d = new Stream(Integer.valueOf(4), handler);
+ b.rePrioritise(a, false, 16);
+ c.rePrioritise(a, false, 16);
+
+ // Action
+ d.rePrioritise(a, true, 16);
+
+ // Check parents
+ Assert.assertEquals(handler, a.getParentStream());
+ Assert.assertEquals(d, b.getParentStream());
+ Assert.assertEquals(d, c.getParentStream());
+ Assert.assertEquals(a, d.getParentStream());
+
+ // Check children
+ Assert.assertEquals(1, a.getChildStreams().size());
+ Assert.assertTrue(a.getChildStreams().contains(d));
+ Assert.assertEquals(2, d.getChildStreams().size());
+ Assert.assertTrue(d.getChildStreams().contains(b));
+ Assert.assertTrue(d.getChildStreams().contains(c));
+ Assert.assertEquals(0, b.getChildStreams().size());
+ Assert.assertEquals(0, c.getChildStreams().size());
+ }
+
+
+ @Test
+ public void testDependenciesFig5NonExclusive() {
+ // Setup
+ Http2UpgradeHandler handler = new Http2UpgradeHandler();
+ Stream a = new Stream(Integer.valueOf(1), handler);
+ Stream b = new Stream(Integer.valueOf(2), handler);
+ Stream c = new Stream(Integer.valueOf(3), handler);
+ Stream d = new Stream(Integer.valueOf(4), handler);
+ Stream e = new Stream(Integer.valueOf(5), handler);
+ Stream f = new Stream(Integer.valueOf(6), handler);
+ b.rePrioritise(a, false, 16);
+ c.rePrioritise(a, false, 16);
+ d.rePrioritise(c, false, 16);
+ e.rePrioritise(c, false, 16);
+ f.rePrioritise(d, false, 16);
+
+ // Action
+ a.rePrioritise(d, false, 16);
+
+ // Check parents
+ Assert.assertEquals(handler, d.getParentStream());
+ Assert.assertEquals(d, f.getParentStream());
+ Assert.assertEquals(d, a.getParentStream());
+ Assert.assertEquals(a, b.getParentStream());
+ Assert.assertEquals(a, c.getParentStream());
+ Assert.assertEquals(c, e.getParentStream());
+
+ // Check children
+ Assert.assertEquals(2, d.getChildStreams().size());
+ Assert.assertTrue(d.getChildStreams().contains(a));
+ Assert.assertTrue(d.getChildStreams().contains(f));
+ Assert.assertEquals(0, f.getChildStreams().size());
+ Assert.assertEquals(2, a.getChildStreams().size());
+ Assert.assertTrue(a.getChildStreams().contains(b));
+ Assert.assertTrue(a.getChildStreams().contains(c));
+ Assert.assertEquals(0, b.getChildStreams().size());
+ Assert.assertEquals(1, c.getChildStreams().size());
+ Assert.assertTrue(c.getChildStreams().contains(e));
+ Assert.assertEquals(0, e.getChildStreams().size());
+ }
+
+
+ @Test
+ public void testDependenciesFig5Exclusive() {
+ // Setup
+ Http2UpgradeHandler handler = new Http2UpgradeHandler();
+ Stream a = new Stream(Integer.valueOf(1), handler);
+ Stream b = new Stream(Integer.valueOf(2), handler);
+ Stream c = new Stream(Integer.valueOf(3), handler);
+ Stream d = new Stream(Integer.valueOf(4), handler);
+ Stream e = new Stream(Integer.valueOf(5), handler);
+ Stream f = new Stream(Integer.valueOf(6), handler);
+ b.rePrioritise(a, false, 16);
+ c.rePrioritise(a, false, 16);
+ d.rePrioritise(c, false, 16);
+ e.rePrioritise(c, false, 16);
+ f.rePrioritise(d, false, 16);
+
+ // Action
+ a.rePrioritise(d, true, 16);
+
+ // Check parents
+ Assert.assertEquals(handler, d.getParentStream());
+ Assert.assertEquals(d, a.getParentStream());
+ Assert.assertEquals(a, b.getParentStream());
+ Assert.assertEquals(a, c.getParentStream());
+ Assert.assertEquals(a, f.getParentStream());
+ Assert.assertEquals(c, e.getParentStream());
+
+ // Check children
+ Assert.assertEquals(1, d.getChildStreams().size());
+ Assert.assertTrue(d.getChildStreams().contains(a));
+ Assert.assertEquals(3, a.getChildStreams().size());
+ Assert.assertTrue(a.getChildStreams().contains(b));
+ Assert.assertTrue(a.getChildStreams().contains(c));
+ Assert.assertTrue(a.getChildStreams().contains(f));
+ Assert.assertEquals(0, b.getChildStreams().size());
+ Assert.assertEquals(0, f.getChildStreams().size());
+ Assert.assertEquals(1, c.getChildStreams().size());
+ Assert.assertTrue(c.getChildStreams().contains(e));
+ Assert.assertEquals(0, e.getChildStreams().size());
+ }
+}
Propchange: tomcat/trunk/test/org/apache/coyote/http2/TestAbstractStream.java
------------------------------------------------------------------------------
svn:eol-style = native
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]