You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by dk...@apache.org on 2015/03/19 22:39:27 UTC
[2/2] cxf git commit: Start stubbing in a throttling feature and a
sample for it. Lots more work to go.
Start stubbing in a throttling feature and a sample for it. Lots more work to go.
Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/3a080015
Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/3a080015
Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/3a080015
Branch: refs/heads/master
Commit: 3a080015474d27075b0b03aa9ec74ab443504ebd
Parents: 015419b
Author: Daniel Kulp <dk...@apache.org>
Authored: Thu Mar 19 17:38:45 2015 -0400
Committer: Daniel Kulp <dk...@apache.org>
Committed: Thu Mar 19 17:38:45 2015 -0400
----------------------------------------------------------------------
distribution/src/main/release/samples/pom.xml | 1 +
.../main/release/samples/throttling/README.txt | 24 +++
.../src/main/release/samples/throttling/pom.xml | 158 +++++++++++++++++++
.../throttling/src/main/config/hello_world.wsdl | 73 +++++++++
.../java/demo/throttling/client/Client.java | 113 +++++++++++++
.../java/demo/throttling/server/Customer.java | 110 +++++++++++++
.../server/CustomerMetricsInterceptor.java | 71 +++++++++
.../demo/throttling/server/GreeterImpl.java | 33 ++++
.../java/demo/throttling/server/Server.java | 82 ++++++++++
rt/features/throttling/pom.xml | 46 ++++++
.../cxf/throttling/ThrottlingInterceptor.java | 62 ++++++++
.../cxf/throttling/ThrottlingManager.java | 35 ++++
.../codahale/CodahaleMetricsContext.java | 40 +++++
rt/pom.xml | 1 +
14 files changed, 849 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cxf/blob/3a080015/distribution/src/main/release/samples/pom.xml
----------------------------------------------------------------------
diff --git a/distribution/src/main/release/samples/pom.xml b/distribution/src/main/release/samples/pom.xml
index 82d6bf4..ff09a4f 100644
--- a/distribution/src/main/release/samples/pom.xml
+++ b/distribution/src/main/release/samples/pom.xml
@@ -102,6 +102,7 @@
<module>jax_rs/minimal_osgi</module>
<module>ws_discovery</module>
<module>ws_eventing</module>
+ <module>throttling</module>
</modules>
<dependencyManagement>
<dependencies>
http://git-wip-us.apache.org/repos/asf/cxf/blob/3a080015/distribution/src/main/release/samples/throttling/README.txt
----------------------------------------------------------------------
diff --git a/distribution/src/main/release/samples/throttling/README.txt b/distribution/src/main/release/samples/throttling/README.txt
new file mode 100644
index 0000000..5468659
--- /dev/null
+++ b/distribution/src/main/release/samples/throttling/README.txt
@@ -0,0 +1,24 @@
+Throttling Hello World Demo
+=============================================
+This demo provides a "hello world" example of making SOAP calls.
+
+Please review the README in the samples directory before continuing.
+
+Building and running the demo using Maven
+-----------------------------------------
+From the base directory of this sample (i.e., where this README file is
+located), the Maven pom.xml file can be used to build and run the demo.
+
+ mvn clean install (builds the demo)
+
+In the first terminal windows:
+ mvn -Pserver (starts the server)
+
+Sequentially, in the second terminal window:
+ mvn -Pclient
+
+Later, when desired:
+ mvn clean (removes all generated and compiled classes)
+
+
+
http://git-wip-us.apache.org/repos/asf/cxf/blob/3a080015/distribution/src/main/release/samples/throttling/pom.xml
----------------------------------------------------------------------
diff --git a/distribution/src/main/release/samples/throttling/pom.xml b/distribution/src/main/release/samples/throttling/pom.xml
new file mode 100644
index 0000000..c553c5f
--- /dev/null
+++ b/distribution/src/main/release/samples/throttling/pom.xml
@@ -0,0 +1,158 @@
+<?xml version="1.0"?>
+<!--
+ 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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>throttling</artifactId>
+ <name>Demo using the throttling feature</name>
+ <description>Demo using the throttling feature</description>
+ <parent>
+ <groupId>org.apache.cxf.samples</groupId>
+ <artifactId>cxf-samples</artifactId>
+ <version>3.1.0-SNAPSHOT</version>
+ </parent>
+ <properties>
+ <wsdl.location>${basedir}/src/main/config/hello_world.wsdl</wsdl.location>
+ </properties>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.cxf</groupId>
+ <artifactId>cxf-codegen-plugin</artifactId>
+ <version>${project.version}</version>
+ <executions>
+ <execution>
+ <id>generate-sources</id>
+ <phase>generate-sources</phase>
+ <configuration>
+ <wsdlOptions>
+ <wsdlOption>
+ <faultSerialVersionUID>1</faultSerialVersionUID>
+ <wsdl>${wsdl.location}</wsdl>
+ <seiSuper>
+ <super>java.lang.AutoCloseable</super>
+ <super>javax.xml.ws.BindingProvider</super>
+ </seiSuper>
+ </wsdlOption>
+ </wsdlOptions>
+ </configuration>
+ <goals>
+ <goal>wsdl2java</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ <profiles>
+ <profile>
+ <id>server</id>
+ <build>
+ <defaultGoal>test</defaultGoal>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>exec-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <phase>test</phase>
+ <goals>
+ <goal>exec</goal>
+ </goals>
+ <configuration>
+ <executable>java</executable>
+ <arguments>
+ <argument>-classpath</argument>
+ <classpath />
+ <argument>demo.throttling.server.Server</argument>
+ </arguments>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ <profile>
+ <id>client</id>
+ <build>
+ <defaultGoal>integration-test</defaultGoal>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>exec-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <phase>test</phase>
+ <goals>
+ <goal>java</goal>
+ </goals>
+ <configuration>
+ <mainClass>demo.throttling.client.Client</mainClass>
+ <arguments>
+ <argument>${wsdl.location}</argument>
+ </arguments>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.cxf</groupId>
+ <artifactId>cxf-rt-frontend-jaxws</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.cxf</groupId>
+ <artifactId>cxf-rt-transports-http</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.cxf</groupId>
+ <artifactId>cxf-rt-transports-http-jetty</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.cxf</groupId>
+ <artifactId>cxf-rt-management</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.cxf</groupId>
+ <artifactId>cxf-rt-features-throttling</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-context</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>jcl-over-slf4j</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>io.dropwizard.metrics</groupId>
+ <artifactId>metrics-core</artifactId>
+ </dependency>
+ </dependencies>
+</project>
http://git-wip-us.apache.org/repos/asf/cxf/blob/3a080015/distribution/src/main/release/samples/throttling/src/main/config/hello_world.wsdl
----------------------------------------------------------------------
diff --git a/distribution/src/main/release/samples/throttling/src/main/config/hello_world.wsdl b/distribution/src/main/release/samples/throttling/src/main/config/hello_world.wsdl
new file mode 100644
index 0000000..352986d
--- /dev/null
+++ b/distribution/src/main/release/samples/throttling/src/main/config/hello_world.wsdl
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<wsdl:definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://apache.org/hello_world_soap_http" xmlns:x1="http://apache.org/hello_world_soap_http/types" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="HelloWorld" targetNamespace="http://apache.org/hello_world_soap_http">
+ <wsdl:types>
+ <schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://apache.org/hello_world_soap_http/types" targetNamespace="http://apache.org/hello_world_soap_http/types" elementFormDefault="qualified">
+ <simpleType name="MyStringType">
+ <restriction base="string">
+ <maxLength value="30"/>
+ </restriction>
+ </simpleType>
+ <element name="greetMe">
+ <complexType>
+ <sequence>
+ <element name="requestType" type="tns:MyStringType"/>
+ </sequence>
+ </complexType>
+ </element>
+ <element name="greetMeResponse">
+ <complexType>
+ <sequence>
+ <element name="responseType" type="string"/>
+ </sequence>
+ </complexType>
+ </element>
+ </schema>
+ </wsdl:types>
+ <wsdl:message name="greetMeRequest">
+ <wsdl:part element="x1:greetMe" name="in"/>
+ </wsdl:message>
+ <wsdl:message name="greetMeResponse">
+ <wsdl:part element="x1:greetMeResponse" name="out"/>
+ </wsdl:message>
+ <wsdl:portType name="Greeter">
+ <wsdl:operation name="greetMe">
+ <wsdl:input message="tns:greetMeRequest" name="greetMeRequest"/>
+ <wsdl:output message="tns:greetMeResponse" name="greetMeResponse"/>
+ </wsdl:operation>
+ </wsdl:portType>
+ <wsdl:binding name="Greeter_SOAPBinding" type="tns:Greeter">
+ <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
+ <wsdl:operation name="greetMe">
+ <soap:operation soapAction="" style="document"/>
+ <wsdl:input name="greetMeRequest">
+ <soap:body use="literal"/>
+ </wsdl:input>
+ <wsdl:output name="greetMeResponse">
+ <soap:body use="literal"/>
+ </wsdl:output>
+ </wsdl:operation>
+ </wsdl:binding>
+ <wsdl:service name="SOAPService">
+ <wsdl:port binding="tns:Greeter_SOAPBinding" name="SoapPort">
+ <soap:address location="http://localhost:9001/SoapContext/SoapPort"/>
+ </wsdl:port>
+ </wsdl:service>
+</wsdl:definitions>
http://git-wip-us.apache.org/repos/asf/cxf/blob/3a080015/distribution/src/main/release/samples/throttling/src/main/java/demo/throttling/client/Client.java
----------------------------------------------------------------------
diff --git a/distribution/src/main/release/samples/throttling/src/main/java/demo/throttling/client/Client.java b/distribution/src/main/release/samples/throttling/src/main/java/demo/throttling/client/Client.java
new file mode 100644
index 0000000..7e191e7
--- /dev/null
+++ b/distribution/src/main/release/samples/throttling/src/main/java/demo/throttling/client/Client.java
@@ -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 demo.throttling.client;
+
+import java.io.File;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.namespace.QName;
+import javax.xml.ws.BindingProvider;
+
+import org.apache.hello_world_soap_http.Greeter;
+import org.apache.hello_world_soap_http.SOAPService;
+
+public final class Client implements Runnable {
+
+ private static final QName SERVICE_NAME
+ = new QName("http://apache.org/hello_world_soap_http", "SOAPService");
+
+ private final String username;
+ private final SOAPService service;
+ private volatile boolean doStop;
+ private Client(String name, SOAPService service) {
+ this.username = name;
+ this.service = service;
+ }
+
+ @Override
+ public void run() {
+ long start = System.currentTimeMillis();
+ try (Greeter port = service.getSoapPort()) {
+ port.getRequestContext().put(BindingProvider.USERNAME_PROPERTY, username);
+ port.getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, "password");
+ int x = 0;
+ do {
+ if (doStop) {
+ break;
+ }
+ port.greetMe(username + "-" + x);
+ x++;
+ } while (x < 10000);
+ long end = System.currentTimeMillis();
+ double rate = x * 1000 / (end - start);
+ System.out.println(username + " finished " + x + " invocations: " + rate + " req/sec");
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ }
+ public void stop() {
+ doStop = true;
+ }
+
+ public static void main(String args[]) throws Exception {
+ if (args.length == 0) {
+ System.out.println("please specify wsdl");
+ System.exit(1);
+ }
+
+ URL wsdlURL;
+ File wsdlFile = new File(args[0]);
+ if (wsdlFile.exists()) {
+ wsdlURL = wsdlFile.toURI().toURL();
+ } else {
+ wsdlURL = new URL(args[0]);
+ }
+
+ System.out.println(wsdlURL);
+ SOAPService ss = new SOAPService(wsdlURL, SERVICE_NAME);
+ List<Client> c = new ArrayList<Client>();
+ Client client = new Client("Tom", ss);
+ new Thread(client).start();
+ c.add(client);
+ client = new Client("Rob", ss);
+ new Thread(client).start();
+ c.add(client);
+ client = new Client("Vince", ss);
+ new Thread(client).start();
+ c.add(client);
+ client = new Client("Malcolm", ss);
+ new Thread(client).start();
+ c.add(client);
+
+ System.out.println("Sleeping on main thread for 60 seconds");
+ Thread.sleep(60000);
+ for (Client c2 : c) {
+ c2.stop();
+ }
+ Thread.sleep(2000);
+
+ System.exit(0);
+ }
+
+
+
+}
http://git-wip-us.apache.org/repos/asf/cxf/blob/3a080015/distribution/src/main/release/samples/throttling/src/main/java/demo/throttling/server/Customer.java
----------------------------------------------------------------------
diff --git a/distribution/src/main/release/samples/throttling/src/main/java/demo/throttling/server/Customer.java b/distribution/src/main/release/samples/throttling/src/main/java/demo/throttling/server/Customer.java
new file mode 100644
index 0000000..184468c
--- /dev/null
+++ b/distribution/src/main/release/samples/throttling/src/main/java/demo/throttling/server/Customer.java
@@ -0,0 +1,110 @@
+/**
+ * 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 demo.throttling.server;
+
+import com.codahale.metrics.MetricRegistry;
+
+import org.apache.cxf.management.codahale.CodahaleMetricsContext;
+import org.apache.cxf.management.codahale.MetricsContext;
+import org.apache.cxf.message.Message;
+
+/**
+ *
+ */
+public abstract class Customer {
+ protected final String name;
+ protected volatile CodahaleMetricsContext metrics;
+
+ public Customer(String n) {
+ name = n;
+ }
+
+ MetricsContext getMetricsContext(MetricRegistry registry) {
+ if (metrics == null) {
+ metrics = new CodahaleMetricsContext("Customer-" + name, registry);
+ }
+ return metrics;
+ }
+
+ public abstract long throttle(Message m);
+
+
+ public static class PremiumCustomer extends Customer {
+ public PremiumCustomer(String n) {
+ super(n);
+ }
+ public long throttle(Message m) {
+ //Premium customers are unthrottled
+ return 0;
+ }
+ }
+ public static class PreferredCustomer extends Customer {
+ public PreferredCustomer(String n) {
+ super(n);
+ }
+ public long throttle(Message m) {
+ //System.out.println("p " + metrics.getTotals().getOneMinuteRate() + " " + metrics.getTotals().getCount());
+ //Preferred customers are unthrottled until they hit 100req/sec, then start delaying by .05 seconds
+ //(drops to max of 50req/sec until below the 100req/sec rate)
+ if (metrics.getTotals().getOneMinuteRate() > 100) {
+ return 20;
+ }
+ return 0;
+ }
+ }
+ public static class RegularCustomer extends Customer {
+ public RegularCustomer(String n) {
+ super(n);
+ }
+ public long throttle(Message m) {
+ //Regular customers are unthrottled until they hit 25req/sec, then start delaying by 0.25 seconds
+ //(drops to max of 4req/sec until below the 25req/sec rate)
+ if (metrics.getTotals().getOneMinuteRate() > 25) {
+ return 250;
+ }
+ //They also get throttled more if they are over 10req/sec over a 5 minute period
+ //(drops to max of 2req/sec until below the 10req/sec rate)
+ if (metrics.getTotals().getFiveMinuteRate() > 10) {
+ return 500;
+ }
+ return 0;
+ }
+ }
+ public static class CheapCustomer extends Customer {
+ public CheapCustomer(String n) {
+ super(n);
+ }
+ public long throttle(Message m) {
+ //System.out.println("ch " + metrics.getTotals().getOneMinuteRate() + " " + metrics.getTotals().getCount());
+ //Cheap customers are always get a .1 sec delay
+ long delay = 100;
+ //Then they get futher throttled dependending on rates
+ if (metrics.getTotals().getOneMinuteRate() > 5) {
+ delay += 1000;
+ }
+ //They also get throttled after 5 minutes of more than
+ if (metrics.getTotals().getFiveMinuteRate() > 1) {
+ delay += 1000;
+ }
+ return delay;
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/cxf/blob/3a080015/distribution/src/main/release/samples/throttling/src/main/java/demo/throttling/server/CustomerMetricsInterceptor.java
----------------------------------------------------------------------
diff --git a/distribution/src/main/release/samples/throttling/src/main/java/demo/throttling/server/CustomerMetricsInterceptor.java b/distribution/src/main/release/samples/throttling/src/main/java/demo/throttling/server/CustomerMetricsInterceptor.java
new file mode 100644
index 0000000..c84eaee
--- /dev/null
+++ b/distribution/src/main/release/samples/throttling/src/main/java/demo/throttling/server/CustomerMetricsInterceptor.java
@@ -0,0 +1,71 @@
+/**
+ * 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 demo.throttling.server;
+
+import java.util.List;
+import java.util.Map;
+
+import com.codahale.metrics.MetricRegistry;
+
+import org.apache.cxf.common.util.Base64Exception;
+import org.apache.cxf.common.util.Base64Utility;
+import org.apache.cxf.helpers.CastUtils;
+import org.apache.cxf.interceptor.Fault;
+import org.apache.cxf.management.codahale.MessageMetrics;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.phase.AbstractPhaseInterceptor;
+import org.apache.cxf.phase.Phase;
+
+/**
+ *
+ */
+public class CustomerMetricsInterceptor extends AbstractPhaseInterceptor<Message> {
+ MetricRegistry registry;
+ Map<String, Customer> customers;
+ public CustomerMetricsInterceptor(MetricRegistry reg, Map<String, Customer> c) {
+ super(Phase.PRE_STREAM);
+ registry = reg;
+ customers = c;
+ }
+
+ @Override
+ public void handleMessage(Message message) throws Fault {
+ MessageMetrics m = message.getExchange().get(MessageMetrics.class);
+ if (m != null) {
+ Map<String, List<String>> h = CastUtils.cast((Map<?,?>)message.get(Message.PROTOCOL_HEADERS));
+ String auth = h.get("Authorization").toString();
+ auth = auth.substring(auth.indexOf(' ') + 1);
+ try {
+ auth = new String(Base64Utility.decode(auth));
+ } catch (Base64Exception e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ auth = auth.substring(0, auth.indexOf(':'));
+ Customer c = customers.get(auth);
+ if (c == null) {
+ throw new RuntimeException("Not authorized");
+ }
+ m.addContext(c.getMetricsContext(registry));
+ message.getExchange().put(Customer.class, c);
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/cxf/blob/3a080015/distribution/src/main/release/samples/throttling/src/main/java/demo/throttling/server/GreeterImpl.java
----------------------------------------------------------------------
diff --git a/distribution/src/main/release/samples/throttling/src/main/java/demo/throttling/server/GreeterImpl.java b/distribution/src/main/release/samples/throttling/src/main/java/demo/throttling/server/GreeterImpl.java
new file mode 100644
index 0000000..e8664ab
--- /dev/null
+++ b/distribution/src/main/release/samples/throttling/src/main/java/demo/throttling/server/GreeterImpl.java
@@ -0,0 +1,33 @@
+/**
+ * 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 demo.throttling.server;
+
+
+@javax.jws.WebService(name = "Greeter", serviceName = "SOAPService",
+ targetNamespace = "http://apache.org/hello_world_soap_http",
+ wsdlLocation = "file:./src/main/config/hello_world.wsdl",
+ endpointInterface = "org.apache.hello_world_soap_http.Greeter")
+
+public class GreeterImpl {
+
+ public String greetMe(String me) {
+ return "Hello " + me;
+ }
+}
http://git-wip-us.apache.org/repos/asf/cxf/blob/3a080015/distribution/src/main/release/samples/throttling/src/main/java/demo/throttling/server/Server.java
----------------------------------------------------------------------
diff --git a/distribution/src/main/release/samples/throttling/src/main/java/demo/throttling/server/Server.java b/distribution/src/main/release/samples/throttling/src/main/java/demo/throttling/server/Server.java
new file mode 100644
index 0000000..bb01535
--- /dev/null
+++ b/distribution/src/main/release/samples/throttling/src/main/java/demo/throttling/server/Server.java
@@ -0,0 +1,82 @@
+/**
+ * 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 demo.throttling.server;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.ws.Endpoint;
+
+import com.codahale.metrics.MetricRegistry;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.BusFactory;
+import org.apache.cxf.management.codahale.Metrics;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.phase.Phase;
+import org.apache.cxf.throttling.ThrottlingInterceptor;
+import org.apache.cxf.throttling.ThrottlingManager;
+
+public class Server {
+ Map<String, Customer> customers = new HashMap<>();
+
+ protected Server() throws Exception {
+ System.out.println("Starting Server");
+
+ customers.put("Tom", new Customer.PremiumCustomer("Tom"));
+ customers.put("Rob", new Customer.PreferredCustomer("Rob"));
+ customers.put("Vince", new Customer.RegularCustomer("Vince"));
+ customers.put("Malcolm", new Customer.CheapCustomer("Malcolm"));
+
+ Bus b = BusFactory.getDefaultBus();
+ MetricRegistry registry = new MetricRegistry();
+ b.setExtension(registry, MetricRegistry.class);
+ new Metrics(b);
+
+
+ ThrottlingManager manager = new ThrottlingManager() {
+ @Override
+ public long getThrottleDelay(Message m) {
+ if (m.get("THROTTLED") != null) {
+ return 0;
+ }
+ m.put("THROTTLED", true);
+ Customer c = m.getExchange().get(Customer.class);
+ return c.throttle(m);
+ }
+ };
+ b.getInInterceptors().add(new CustomerMetricsInterceptor(registry, customers));
+ b.getInInterceptors().add(new ThrottlingInterceptor(Phase.PRE_STREAM, manager));
+ //add Throttling
+
+ Object implementor = new GreeterImpl();
+ String address = "http://localhost:9001/SoapContext/SoapPort";
+ Endpoint.publish(address, implementor);
+ }
+
+ public static void main(String args[]) throws Exception {
+ new Server();
+ System.out.println("Server ready...");
+
+ Thread.sleep(5 * 60 * 1000);
+ System.out.println("Server exiting");
+ System.exit(0);
+ }
+}
http://git-wip-us.apache.org/repos/asf/cxf/blob/3a080015/rt/features/throttling/pom.xml
----------------------------------------------------------------------
diff --git a/rt/features/throttling/pom.xml b/rt/features/throttling/pom.xml
new file mode 100644
index 0000000..1cf7d1c
--- /dev/null
+++ b/rt/features/throttling/pom.xml
@@ -0,0 +1,46 @@
+<project
+ xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.cxf</groupId>
+ <artifactId>cxf-parent</artifactId>
+ <version>3.1.0-SNAPSHOT</version>
+ <relativePath>../../../parent/pom.xml</relativePath>
+ </parent>
+ <artifactId>cxf-rt-features-throttling</artifactId>
+ <packaging>bundle</packaging>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.cxf</groupId>
+ <artifactId>cxf-core</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.easymock</groupId>
+ <artifactId>easymock</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.cxf</groupId>
+ <artifactId>cxf-rt-frontend-jaxws</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.cxf</groupId>
+ <artifactId>cxf-rt-transports-http-jetty</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cxf/blob/3a080015/rt/features/throttling/src/main/java/org/apache/cxf/throttling/ThrottlingInterceptor.java
----------------------------------------------------------------------
diff --git a/rt/features/throttling/src/main/java/org/apache/cxf/throttling/ThrottlingInterceptor.java b/rt/features/throttling/src/main/java/org/apache/cxf/throttling/ThrottlingInterceptor.java
new file mode 100644
index 0000000..f35e144
--- /dev/null
+++ b/rt/features/throttling/src/main/java/org/apache/cxf/throttling/ThrottlingInterceptor.java
@@ -0,0 +1,62 @@
+/**
+ * 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.cxf.throttling;
+
+import java.util.logging.Logger;
+
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.continuations.Continuation;
+import org.apache.cxf.continuations.ContinuationProvider;
+import org.apache.cxf.interceptor.Fault;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.phase.AbstractPhaseInterceptor;
+
+/**
+ *
+ */
+public class ThrottlingInterceptor extends AbstractPhaseInterceptor<Message> {
+ public static final Logger LOG = LogUtils.getL7dLogger(ThrottlingInterceptor.class);
+
+ final ThrottlingManager manager;
+ public ThrottlingInterceptor(String phase, ThrottlingManager manager) {
+ super(ThrottlingInterceptor.class.getName() + "-" + phase, phase);
+ this.manager = manager;
+ }
+
+ @Override
+ public void handleMessage(Message message) throws Fault {
+ long l = manager.getThrottleDelay(message);
+ if (l > 0) {
+ ContinuationProvider cp = message.get(ContinuationProvider.class);
+ if (cp == null) {
+ LOG.warning("No ContinuationProvider available, sleeping on current thread");
+ try {
+ Thread.sleep(l);
+ } catch (InterruptedException e) {
+ //ignore
+ }
+ return;
+ }
+ Continuation c = cp.getContinuation();
+ c.suspend(l);
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/cxf/blob/3a080015/rt/features/throttling/src/main/java/org/apache/cxf/throttling/ThrottlingManager.java
----------------------------------------------------------------------
diff --git a/rt/features/throttling/src/main/java/org/apache/cxf/throttling/ThrottlingManager.java b/rt/features/throttling/src/main/java/org/apache/cxf/throttling/ThrottlingManager.java
new file mode 100644
index 0000000..ea7c841
--- /dev/null
+++ b/rt/features/throttling/src/main/java/org/apache/cxf/throttling/ThrottlingManager.java
@@ -0,0 +1,35 @@
+/**
+ * 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.cxf.throttling;
+
+import org.apache.cxf.message.Message;
+
+/**
+ *
+ */
+public interface ThrottlingManager {
+
+ /**
+ * Returns the number of milliseconds the request should be delayed before further processing
+ * @param m
+ * @return
+ */
+ long getThrottleDelay(Message m);
+}
http://git-wip-us.apache.org/repos/asf/cxf/blob/3a080015/rt/management/src/main/java/org/apache/cxf/management/codahale/CodahaleMetricsContext.java
----------------------------------------------------------------------
diff --git a/rt/management/src/main/java/org/apache/cxf/management/codahale/CodahaleMetricsContext.java b/rt/management/src/main/java/org/apache/cxf/management/codahale/CodahaleMetricsContext.java
index 9c23d75..8c547b3 100644
--- a/rt/management/src/main/java/org/apache/cxf/management/codahale/CodahaleMetricsContext.java
+++ b/rt/management/src/main/java/org/apache/cxf/management/codahale/CodahaleMetricsContext.java
@@ -106,4 +106,44 @@ public class CodahaleMetricsContext implements MetricsContext, Closeable {
inFlight.dec();
}
+ public Counter getInFlight() {
+ return inFlight;
+ }
+
+ public Timer getTotals() {
+ return totals;
+ }
+
+ public Timer getUncheckedApplicationFaults() {
+ return uncheckedApplicationFaults;
+ }
+
+ public Timer getCheckedApplicationFaults() {
+ return checkedApplicationFaults;
+ }
+
+ public Timer getRuntimeFaults() {
+ return runtimeFaults;
+ }
+
+ public Timer getLogicalRuntimeFaults() {
+ return logicalRuntimeFaults;
+ }
+
+ public Meter getIncomingData() {
+ return incomingData;
+ }
+
+ public Meter getOutgoingData() {
+ return outgoingData;
+ }
+
+ public String getBaseName() {
+ return baseName;
+ }
+
+ public MetricRegistry getRegistry() {
+ return registry;
+ }
+
}
http://git-wip-us.apache.org/repos/asf/cxf/blob/3a080015/rt/pom.xml
----------------------------------------------------------------------
diff --git a/rt/pom.xml b/rt/pom.xml
index c2f5c70..7e8555e 100644
--- a/rt/pom.xml
+++ b/rt/pom.xml
@@ -40,6 +40,7 @@
<module>bindings</module>
<module>features/clustering</module>
<module>features/logging</module>
+ <module>features/throttling</module>
<module>frontend/simple</module>
<module>frontend/jaxws</module>
<module>frontend/jaxrs</module>