Skip to content

Commit

Permalink
CAMEL-12485: camel cloud : create camel-service component
Browse files Browse the repository at this point in the history
  • Loading branch information
lburgazzoli committed May 30, 2018
1 parent f3a29a0 commit e2834c9
Show file tree
Hide file tree
Showing 12 changed files with 131 additions and 178 deletions.
Expand Up @@ -16,9 +16,11 @@
*/ */
package org.apache.camel.cloud; package org.apache.camel.cloud;


import java.util.Map;

public interface DiscoverableService { public interface DiscoverableService {
/** /**
* Get the service definition. * Get the service properties.
*/ */
ServiceDefinition getServiceDefinition(); Map<String, Object> getServiceProperties();
} }
Expand Up @@ -33,7 +33,9 @@ public interface ServiceDefinition {
// default service meta-data keys // default service meta-data keys
String SERVICE_META_ID = "service.id"; String SERVICE_META_ID = "service.id";
String SERVICE_META_NAME = "service.name"; String SERVICE_META_NAME = "service.name";
String SERVICE_META_HOST = "service.host";
String SERVICE_META_PORT = "service.port"; String SERVICE_META_PORT = "service.port";
String SERVICE_META_ZONE = "service.zone";
String SERVICE_META_PROTOCOL= "service.protocol"; String SERVICE_META_PROTOCOL= "service.protocol";
String SERVICE_META_PATH = "service.path"; String SERVICE_META_PATH = "service.path";


Expand Down
Expand Up @@ -175,7 +175,7 @@ public static class Builder {
private String id; private String id;
private String name; private String name;
private String host; private String host;
private int port; private Integer port;
private Map<String, String> meta; private Map<String, String> meta;
private ServiceHealth health; private ServiceHealth health;


Expand All @@ -190,6 +190,51 @@ public Builder from(ServiceDefinition source) {
return this; return this;
} }


public Builder from(Map<String, Object> properties) {
Map<String, Object> options = new HashMap<>(properties);
Object val = null;

val = options.remove(ServiceDefinition.SERVICE_META_ID);
if (val != null && val instanceof String) {
withId((String)val);
}

val = options.remove(ServiceDefinition.SERVICE_META_NAME);
if (val != null && val instanceof String) {
withName((String)val);
}

val = options.remove(ServiceDefinition.SERVICE_META_HOST);
if (val != null && val instanceof String) {
withHost((String)val);
}

val = options.remove(ServiceDefinition.SERVICE_META_PORT);
if (val != null && val instanceof String) {
withPort((String)val);
}
if (val != null && val instanceof Integer) {
withPort((Integer)val);
}

val = options.remove(ServiceDefinition.SERVICE_META_HOST);
if (val != null && val instanceof String) {
withHost((String)val);
}

for (Map.Entry<String, Object> entry : options.entrySet()) {
if (!entry.getKey().startsWith(ServiceDefinition.SERVICE_META_PREFIX)) {
continue;
}

if (entry.getValue() instanceof String) {
addMeta(entry.getKey(), (String)entry.getValue());
}
}

return this;
}

public Builder withId(String id) { public Builder withId(String id) {
this.id = id; this.id = id;
return this; return this;
Expand Down Expand Up @@ -217,12 +262,20 @@ public String host() {
return host; return host;
} }


public Builder withPort(int port) { public Builder withPort(Integer port) {
this.port = port; this.port = port;
return this; return this;
} }


public int port() { public Builder withPort(String port) {
if (port != null) {
withPort(Integer.parseInt(port));
}

return this;
}

public Integer port() {
return port; return port;
} }


Expand Down Expand Up @@ -266,7 +319,7 @@ public ServiceHealth health() {
} }


public ServiceDefinition build() { public ServiceDefinition build() {
return new DefaultServiceDefinition(id, name, host, port, meta, health); return new DefaultServiceDefinition(id, name, host, port != null ? port : -1, meta, health);
} }
} }
} }
Expand Up @@ -125,7 +125,7 @@ private Optional<ServiceDefinition> computeServiceDefinition(Route route) {


if (endpoint instanceof DiscoverableService) { if (endpoint instanceof DiscoverableService) {
final DiscoverableService service = (DiscoverableService)endpoint; final DiscoverableService service = (DiscoverableService)endpoint;
final ServiceDefinition definition = service.getServiceDefinition(); final Map<String, Object> properties = service.getServiceProperties();


// try to get the service id from route properties // try to get the service id from route properties
String serviceId = (String)route.getProperties().get(ServiceDefinition.SERVICE_META_ID); String serviceId = (String)route.getProperties().get(ServiceDefinition.SERVICE_META_ID);
Expand All @@ -137,7 +137,7 @@ private Optional<ServiceDefinition> computeServiceDefinition(Route route) {
} }
if (serviceId == null) { if (serviceId == null) {
// finally get the id from the DiscoverableService // finally get the id from the DiscoverableService
serviceId = definition.getId(); serviceId = (String)properties.get(ServiceDefinition.SERVICE_META_ID);
} }


// try to get the service name from route properties // try to get the service name from route properties
Expand All @@ -148,7 +148,7 @@ private Optional<ServiceDefinition> computeServiceDefinition(Route route) {
} }
if (serviceName == null) { if (serviceName == null) {
// finally get the name from the DiscoverableService // finally get the name from the DiscoverableService
serviceName = definition.getName(); serviceName = (String)properties.get(ServiceDefinition.SERVICE_META_NAME);
} }


ObjectHelper.notNull(serviceId, "Service ID"); ObjectHelper.notNull(serviceId, "Service ID");
Expand All @@ -157,7 +157,7 @@ private Optional<ServiceDefinition> computeServiceDefinition(Route route) {
// Build the final resource definition from bits collected from the // Build the final resource definition from bits collected from the
// endpoint and the route. // endpoint and the route.
DefaultServiceDefinition.Builder builder = DefaultServiceDefinition.builder() DefaultServiceDefinition.Builder builder = DefaultServiceDefinition.builder()
.from(definition) .from(properties)
.withId(serviceId) .withId(serviceId)
.withName(serviceName); .withName(serviceName);


Expand Down
Expand Up @@ -16,7 +16,9 @@
*/ */
package org.apache.camel.component.consul.cloud; package org.apache.camel.component.consul.cloud;


import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.UUID; import java.util.UUID;


import com.orbitz.consul.CatalogClient; import com.orbitz.consul.CatalogClient;
Expand All @@ -35,6 +37,10 @@ public abstract class ConsulServiceRegistrationTestBase extends ConsulTestSuppor
protected final static String SERVICE_HOST = "localhost"; protected final static String SERVICE_HOST = "localhost";
protected final static int SERVICE_PORT = SocketUtils.findAvailableTcpPort(); protected final static int SERVICE_PORT = SocketUtils.findAvailableTcpPort();


protected Map<String, String> getMetadata() {
return Collections.emptyMap();
}

@Override @Override
protected CamelContext createCamelContext() throws Exception { protected CamelContext createCamelContext() throws Exception {
final CamelContext context = super.createCamelContext(); final CamelContext context = super.createCamelContext();
Expand Down Expand Up @@ -68,8 +74,13 @@ public void testRegistrationFromRoute() throws Exception {
assertEquals(SERVICE_PORT, services.get(0).getServicePort()); assertEquals(SERVICE_PORT, services.get(0).getServicePort());
assertEquals("localhost", services.get(0).getServiceAddress()); assertEquals("localhost", services.get(0).getServiceAddress());
assertTrue(services.get(0).getServiceTags().contains(ServiceDefinition.SERVICE_META_PROTOCOL + "=http")); assertTrue(services.get(0).getServiceTags().contains(ServiceDefinition.SERVICE_META_PROTOCOL + "=http"));
assertTrue(services.get(0).getServiceTags().contains(ServiceDefinition.SERVICE_META_PATH + "=/service/endpoint/")); assertTrue(services.get(0).getServiceTags().contains(ServiceDefinition.SERVICE_META_PATH + "=/service/endpoint"));
assertTrue(services.get(0).getServiceTags().contains(ServiceDefinition.SERVICE_META_PORT + "=" + SERVICE_PORT));
getMetadata().forEach(
(k, v) -> {
assertTrue(services.get(0).getServiceTags().contains(k + "=" + v));
}
);


List<ServiceHealth> checks = health.getHealthyServiceInstances(SERVICE_NAME).getResponse(); List<ServiceHealth> checks = health.getHealthyServiceInstances(SERVICE_NAME).getResponse();
assertEquals(1, checks.size()); assertEquals(1, checks.size());
Expand Down
Expand Up @@ -35,7 +35,7 @@ protected RoutesBuilder createRouteBuilder() throws Exception {
return new RouteBuilder() { return new RouteBuilder() {
@Override @Override
public void configure() throws Exception { public void configure() throws Exception {
fromF("jetty:http://0.0.0.0:%d/service/endpoint/", SERVICE_PORT) fromF("jetty:http://0.0.0.0:%d/service/endpoint", SERVICE_PORT)
.routeId(SERVICE_ID) .routeId(SERVICE_ID)
.routeGroup(SERVICE_NAME) .routeGroup(SERVICE_NAME)
.noAutoStartup() .noAutoStartup()
Expand Down
Expand Up @@ -26,7 +26,7 @@ protected RoutesBuilder createRouteBuilder() throws Exception {
return new RouteBuilder() { return new RouteBuilder() {
@Override @Override
public void configure() throws Exception { public void configure() throws Exception {
fromF("jetty:http://0.0.0.0:%d/service/endpoint/", SERVICE_PORT) fromF("jetty:http://0.0.0.0:%d/service/endpoint", SERVICE_PORT)
.routeId(SERVICE_ID) .routeId(SERVICE_ID)
.routeGroup(SERVICE_NAME) .routeGroup(SERVICE_NAME)
.routePolicy(new ServiceRegistrationRoutePolicy()) .routePolicy(new ServiceRegistrationRoutePolicy())
Expand Down
Expand Up @@ -16,12 +16,23 @@
*/ */
package org.apache.camel.component.consul.cloud; package org.apache.camel.component.consul.cloud;


import java.util.HashMap;
import java.util.Map;

import org.apache.camel.RoutesBuilder; import org.apache.camel.RoutesBuilder;
import org.apache.camel.builder.RouteBuilder; import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.service.ServiceComponent; import org.apache.camel.component.service.ServiceComponent;
import org.apache.camel.impl.JndiRegistry; import org.apache.camel.impl.JndiRegistry;


public class ConsulServiceRegistrationWithServiceComponentTest extends ConsulServiceRegistrationTestBase { public class ConsulServiceRegistrationWithServiceComponentTest extends ConsulServiceRegistrationTestBase {

protected Map<String, String> getMetadata() {
return new HashMap<String, String>() {{
put("service.type", "consul");
put("service.zone", "US");
}};
}

@Override @Override
protected JndiRegistry createRegistry() throws Exception { protected JndiRegistry createRegistry() throws Exception {
JndiRegistry registry = super.createRegistry(); JndiRegistry registry = super.createRegistry();
Expand All @@ -35,7 +46,7 @@ protected RoutesBuilder createRouteBuilder() throws Exception {
return new RouteBuilder() { return new RouteBuilder() {
@Override @Override
public void configure() throws Exception { public void configure() throws Exception {
fromF("service:%s:jetty:http://0.0.0.0:%d/service/endpoint/", SERVICE_NAME, SERVICE_PORT) fromF("service:%s:jetty:http://0.0.0.0:%d/service/endpoint?service.type=consul&service.zone=US", SERVICE_NAME, SERVICE_PORT)
.routeId(SERVICE_ID) .routeId(SERVICE_ID)
.routeGroup(SERVICE_NAME) .routeGroup(SERVICE_NAME)
.noAutoStartup() .noAutoStartup()
Expand Down
Expand Up @@ -18,12 +18,13 @@


import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;


import org.apache.camel.cloud.DiscoverableService; import org.apache.camel.cloud.DiscoverableService;
import org.apache.camel.cloud.ServiceDefinition; import org.apache.camel.cloud.ServiceDefinition;
import org.apache.camel.http.common.cookie.CookieHandler; import org.apache.camel.http.common.cookie.CookieHandler;
import org.apache.camel.impl.DefaultEndpoint; import org.apache.camel.impl.DefaultEndpoint;
import org.apache.camel.impl.cloud.DefaultServiceDefinition;
import org.apache.camel.spi.HeaderFilterStrategy; import org.apache.camel.spi.HeaderFilterStrategy;
import org.apache.camel.spi.HeaderFilterStrategyAware; import org.apache.camel.spi.HeaderFilterStrategyAware;
import org.apache.camel.spi.Metadata; import org.apache.camel.spi.Metadata;
Expand Down Expand Up @@ -200,14 +201,12 @@ public boolean isSingleton() {
//------------------------------------------------------------------------- //-------------------------------------------------------------------------


@Override @Override
public ServiceDefinition getServiceDefinition() { public Map<String, Object> getServiceProperties() {
// Returns a partial return new HashMap<String, Object>() {{
return DefaultServiceDefinition.builder() put(ServiceDefinition.SERVICE_META_PORT, getPort());
.withPort(getPort()) put(ServiceDefinition.SERVICE_META_PATH, getPath());
.addMeta(ServiceDefinition.SERVICE_META_PORT, Integer.toString(getPort())) put(ServiceDefinition.SERVICE_META_PROTOCOL, getProtocol());
.addMeta(ServiceDefinition.SERVICE_META_PATH, getPath()) }};
.addMeta(ServiceDefinition.SERVICE_META_PROTOCOL, getProtocol())
.build();
} }


// Properties // Properties
Expand Down
Expand Up @@ -17,16 +17,17 @@
package org.apache.camel.component.service; package org.apache.camel.component.service;




import java.util.HashMap;
import java.util.Map; import java.util.Map;


import org.apache.camel.CamelContext; import org.apache.camel.CamelContext;
import org.apache.camel.Endpoint; import org.apache.camel.Endpoint;
import org.apache.camel.cloud.ServiceDefinition;
import org.apache.camel.cloud.ServiceRegistry; import org.apache.camel.cloud.ServiceRegistry;
import org.apache.camel.impl.DefaultComponent; import org.apache.camel.impl.DefaultComponent;
import org.apache.camel.impl.cloud.ServiceRegistryHelper; import org.apache.camel.impl.cloud.ServiceRegistryHelper;
import org.apache.camel.impl.cloud.ServiceRegistrySelectors; import org.apache.camel.impl.cloud.ServiceRegistrySelectors;
import org.apache.camel.spi.Metadata; import org.apache.camel.spi.Metadata;
import org.apache.camel.util.IntrospectionSupport;
import org.apache.camel.util.ObjectHelper; import org.apache.camel.util.ObjectHelper;
import org.apache.camel.util.StringHelper; import org.apache.camel.util.StringHelper;
import org.apache.camel.util.URISupport; import org.apache.camel.util.URISupport;
Expand Down Expand Up @@ -56,15 +57,26 @@ protected Endpoint createEndpoint(String uri, String remaining, Map<String, Obje
ObjectHelper.notNull(delegateUri, "Delegate URI"); ObjectHelper.notNull(delegateUri, "Delegate URI");


// add service name to the parameters // add service name to the parameters
parameters.put("serviceName", serviceName); parameters.put(ServiceDefinition.SERVICE_META_NAME, serviceName);


// Lookup the service registry, this may be a static selected service // Lookup the service registry, this may be a static selected service
// or dynamically selected one through a ServiceRegistry.Selector // or dynamically selected one through a ServiceRegistry.Selector
final ServiceRegistry service = getServiceRegistry(); final ServiceRegistry service = getServiceRegistry();


// Compute service definition from parameters, this is used as default // Compute service definition from parameters, this is used as default
// definition // definition
final ServiceParameters params = computeServiceParameters(parameters); final Map<String, Object> params = new HashMap<>();
parameters.forEach(
(k, v) -> {
if (k.startsWith(ServiceDefinition.SERVICE_META_PREFIX)) {
params.put(k, v);
}
}
);

// remove all the service related options so the underlying component
// does not fail because of unknown parameters
parameters.keySet().removeAll(parameters.keySet());


return new ServiceEndpoint( return new ServiceEndpoint(
uri, uri,
Expand Down Expand Up @@ -111,23 +123,4 @@ private ServiceRegistry getServiceRegistry() {


return service; return service;
} }

@SuppressWarnings("unchecked")
private ServiceParameters computeServiceParameters(Map<String, Object> parameters) {
// Extract service definition related parameter from uri
final String serviceId = getAndRemoveParameter(parameters, "serviceId", String.class);
final String serviceName = getAndRemoveParameter(parameters, "serviceName", String.class);
final String serviceHost = getAndRemoveParameter(parameters, "serviceHost", String.class);
final String servicePort = getAndRemoveParameter(parameters, "servicePort", String.class);
final Map<String, Object> serviceMeta = IntrospectionSupport.extractProperties(parameters, "serviceMeta.", true);

ServiceParameters params = new ServiceParameters();
ObjectHelper.ifNotEmpty(serviceId, params::setId);
ObjectHelper.ifNotEmpty(serviceName, params::setName);
ObjectHelper.ifNotEmpty(serviceHost, params::setHost);
ObjectHelper.ifNotEmpty(servicePort, params::setPort);
ObjectHelper.ifNotEmpty(serviceMeta, meta -> params.setMeta(Map.class.cast(meta)));

return params;
}
} }

0 comments on commit e2834c9

Please sign in to comment.