Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

[W.I.P.] Add service-registry component (feedback wanted) #474

Closed
wants to merge 1 commit into from

3 participants

@Kami

The goal of this pull request is to add support for registering Respose instances in Rackspace Service Registry.

The patch is unfinished and work in progress. All it currently does it adds a filter which performs the following actions:

  • Register the instance in service registry in init and start heartbeating
  • Stop heartbeating and delete the service on destroy

I opened this pull request to start the discussion and get more feedback from Repose people on how to improve this patch to make it more "idiomatic" and better (best way to add tests, how to correctly use other abstractions such as handler, etc.).

Thanks,
Tomaz

@malconis

Implementing Filter requires the javax.servlet library

Please add:

import javax.servlet.*

to your list of imports

@malconis

The filter chain logic requires that the current filter call doFilter to continue the filter chain.

chain.doFilter(request, response);

@malconis

the getFilterConfig method only really returns the filename of the config file that the user would like to use. Within the system-model.cfg.xml when the user adds a filter to the filter chain they can include a 'configuration' attribute and point to a different config file than the default configuration.

We then pass this to a HandlerFactory which create request handlers whenever Repose receives a request. The ip-identity filter (https://github.com/rackerlabs/repose/tree/master/project-set/components/client-ip-identity/src/main/java/com/rackspace/papi/components/identity/ip) shows the basics of how we expanded the basic Filter methods (doFilter, destroy, and init).

@malconis
Collaborator

Hey Kami,

First of all thanks for writing this. This feature looks looks to be a great addition to Repose. I've added some notes to your code, which I hope would help. I would like discuss this with you further to see if I can help get this up and running with Repose soon. Please log in to to our public IRC channel #repose on freenode.net for questions you may have.

@Kami

@malconis Awesome, thank you for your comments.

I will try to get those comments addressed as soon as possible and let you know once the pull request is in a fully working state and ready to be reviewed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Mar 31, 2013
  1. @Kami
This page is out of date. Refresh to see the latest.
View
9 project-set/components/filter-bundle/pom.xml
@@ -127,6 +127,10 @@
<artifactId>flush-output</artifactId>
</dependency>
+ <dependency>
+ <groupId>com.rackspace.papi.components</groupId>
+ <artifactId>service-registry</artifactId>
+ </dependency>
</dependencies>
<build>
@@ -233,6 +237,11 @@
<groupId>com.rackspace.papi.components</groupId>
<artifactId>client-authorization</artifactId>
</jarModule>
+
+ <jarModule>
+ <groupId>com.rackspace.papi.components</groupId>
+ <artifactId>service-registry</artifactId>
+ </jarModule>
</modules>
</configuration>
</plugin>
View
7 project-set/components/pom.xml
@@ -39,6 +39,7 @@
<module>header-normalization</module>
<module>uri-normalization</module>
<module>replicated-datastore</module>
+ <module>service-registry</module>
</modules>
<dependencyManagement>
@@ -257,6 +258,12 @@
<artifactId>client-authorization</artifactId>
<version>${project.version}</version>
</dependency>
+
+ <dependency>
+ <groupId>com.rackspace.papi.components</groupId>
+ <artifactId>service-registry</artifactId>
+ <version>${project.version}</version>
+ </dependency>
</dependencies>
</dependencyManagement>
</project>
View
64 project-set/components/service-registry/pom.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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>com.rackspace.papi.components</groupId>
+ <artifactId>components-support</artifactId>
+ <version>2.6.12-SNAPSHOT</version>
+ </parent>
+
+ <groupId>com.rackspace.papi.components</groupId>
+ <artifactId>service-registry</artifactId>
+
+ <name>Repose Components - Service Registry Filter</name>
+ <description>Filter which registers Repose instance in Rackspace Service Registry.</description>
+
+ <packaging>jar</packaging>
+
+ <dependencies>
+ <dependency>
+ <groupId>com.rackspace.papi.core</groupId>
+ <artifactId>core-lib</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>com.rackspace.papi.commons</groupId>
+ <artifactId>configuration</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>com.rackspace.papi.commons</groupId>
+ <artifactId>utilities</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>com.rackspacecloud</groupId>
+ <artifactId>service-registry-client</artifactId>
+ <version>2.0.0</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.jvnet.jaxb2.maven2</groupId>
+ <artifactId>maven-jaxb2-plugin</artifactId>
+
+ <configuration>
+ <specVersion>2.1</specVersion>
+
+ <schemaIncludes>
+ <include>**/*.xsd</include>
+ </schemaIncludes>
+ <bindingIncludes>
+ <include>**/*.xjb</include>
+ </bindingIncludes>
+
+ <strict>true</strict>
+ <verbose>false</verbose>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
View
92 ...y/src/main/java/com/rackspace/papi/components/service_registry/ServiceRegistryFilter.java
@@ -0,0 +1,92 @@
+package com.rackspace.papi.components.service_registry;
+
+import com.rackspacecloud.client.service_registry.Client;
+import com.rackspacecloud.client.service_registry.HeartBeater;
+import com.rackspacecloud.client.service_registry.Region;
+import com.rackspacecloud.client.service_registry.ServiceCreateResponse;
+
+import com.rackspace.papi.components.service_registry.config.ServiceRegistryConfig;
+import com.rackspace.papi.filter.FilterConfigHelper;
+import com.rackspace.papi.filter.logic.impl.FilterLogicHandlerDelegate;
+import com.rackspace.papi.service.config.ConfigurationService;
+import com.rackspace.papi.service.context.ServletContextHelper;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.logging.Logger;
+import sun.util.logging.resources.logging;
+
+public class ServiceRegistryFilter implements Filter {
+
+ private static final Logger LOG = LoggerFactory.getLogger(ServiceRegistryFilter.class);
+ private static final String DEFAULT_CONFIG = "service-registry.cfg.xml";
+
+ private String config;
+
+ private Client rsrClient = null;
+ private HeartBeater heartbeater = null;
+ private String serviceId = null;
+
+ @Override
+ public void destroy() {
+ if (this.heartbeater != null) {
+ this.heartbeater.stop();
+ this.heartbeater = null;
+ }
+
+ // destroy is called when a repose instance is gracefully shut down.
+ // We explicitly remove service from the Service Registry so we can
+ // distinguish between a normal shutdown which doesn't require any action
+ // on the user side (service.remove event) and an unexpected shutdown
+ // (service.timeout) event.
+ if (this.serviceId != null) {
+ try {
+ this.rsrClient.getServicesClient().delete(this.serviceId);
+ }
+ catch (Exception ex) {
+ LOG.info("Failed to delete a service: " + ex.toString());
+ }
+
+ this.serviceId = null;
+ }
+ }
+
+ @Override
+ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
+ // Pass through
+ }
+
+ @Override
+ public void init(FilterConfig filterConfig) throws ServletException {
+ config = new FilterConfigHelper(filterConfig).getFilterConfig(DEFAULT_CONFIG);
+ LOG.info("Initializing filter using config " + config);
+
+ String username, apiKey, region;
+
+ // Auth Config
+ username = config.getUsername();
+ apiKey = config.getApiKey();
+ region = config.getRegion();
+
+ // Service config
+ String serviceId = config.getServiceId();
+ Integer heartbeatTimeout = config.getHeartbeatTimeout();
+ ArrayList<String> tags = config.getTags();
+ HashMap<String, String> metadata = new HashMap<String, String>();
+
+ this.rsrClient = new Client(username, apiKey, region);
+
+ LOG.info("Registering service in the registry: " + serviceId);
+
+ try {
+ ServiceCreateResponse response = this.rsrClient.getServicesClient().create(serviceId, heartbeatTimeout, tags, metadata);
+ }
+ catch (Exception ex) {
+ LOG.info("Failed to create a service: " + ex.toString());
+ return;
+ }
+
+ this.heartbeater = response.getHeartbeater();
+ this.heartbeater.start();
+ }
+}
View
11 ...ct-set/components/service-registry/src/main/resources/META-INF/schema/config/bindings.xjb
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<bindings xmlns="http://java.sun.com/xml/ns/jaxb" version="2.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/jaxb http://java.sun.com/xml/ns/jaxb/bindingschema_2_0.xsd"
+ schemaLocation="service-registry-configuration.xsd">
+
+ <schemaBindings>
+ <package name="com.rackspace.papi.components.service_registry.config" />
+ </schemaBindings>
+</bindings>
View
74 ...ice-registry/src/main/resources/META-INF/schema/config/service-registry-configuration.xsd
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<xs:schema elementFormDefault="qualified" attributeFormDefault="unqualified"
+ targetNamespace="http://docs.rackspacecloud.com/repose/service-registry/v1.0"
+ xmlns:sr="http://docs.rackspacecloud.com/repose/service-registry/v1.0"
+ xmlns:html="http://www.w3.org/1999/xhtml"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema">
+
+ <xs:element name="service-registry" type="sr:service-registry-config" />
+
+ <xs:simpleType name="regionType">
+ <xs:restriction base="xs:string">
+ <xs:enumeration value="us" />
+ <xs:enumeration value="uk" />
+ </xs:restriction>
+ </xs:simpleType>
+
+ <xs:complexType name="service-registry-config">
+ <xs:annotation>
+ <xs:documentation>
+ <html:p>This is the type def for a service registry config</html:p>
+ </xs:documentation>
+ </xs:annotation>
+
+ <xs:sequence>
+ <xs:element name="auth" type="sr:auth" minOccurs="1" maxOccurs="1" />
+ <xs:element name="service" type="sr:service" minOccurs="1" maxOccurs="1" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="auth">
+ <xs:attribute name="username" type="xs:string" use="required">
+ <xs:annotation>
+ <xs:documentation>
+ <html:p>Rackspace Cloud API username used for authentication.</html:p>
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <xs:attribute name="api-key" type="xs:string" use="required">
+ <xs:annotation>
+ <xs:documentation>
+ <html:p>Rackspace Cloud API key used for authentication.</html:p>
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <xs:attribute name="region" type="sr:regionType" use="optional" default="us">
+ <xs:annotation>
+ <xs:documentation>
+ <html:p>Account region.</html:p>
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:complexType>
+
+ <xs:complexType name="service">
+ <xs:attribute name="id" type="xs:string" use="required">
+ <xs:annotation>
+ <xs:documentation>
+ <html:p>Service ID.</html:p>
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+
+ <xs:attribute name="heartbeat_timeout" type="xs:integer" use="optional" default="20">
+ <xs:annotation>
+ <xs:documentation>
+ <html:p>Service heartbeat timeout.</html:p>
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:complexType>
+</xs:schema>
View
20 ...nts/service-registry/src/main/resources/META-INF/schema/examples/service-registry.cfg.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<service-registry xmlns="http://docs.rackspacecloud.com/repose/service-registry/v1.0">
+ <auth>
+ <username>rackspace-cloud-username</username>
+ <api-key>rackspace-cloud-api-key</api-key>
+ <region>us</region>
+ </auth>
+
+ <service>
+ <id>my-repose-instance-1</id>
+ <heartbeat_timeout>15</heartbeat_timeout>
+ <tags>
+ <tag>repose</tag>
+ <tag>dfw</tag>
+ <tag>maas</tag>
+ <tag>staging</tag>
+ </tags>
+ </service>
+</service-registry>
Something went wrong with that request. Please try again.