Commit 492b0a5c by amir

add prefix in method path, add interval query in metrics.html

parent 30bcab95
group 'com.ipgallery.common' group 'com.ipgallery.common'
version '2.0.0-services' version '2.0.2-services'
apply plugin: 'java' apply plugin: 'java'
apply plugin: 'maven-publish' apply plugin: 'maven-publish'
......
...@@ -40,7 +40,7 @@ ...@@ -40,7 +40,7 @@
### Metrics ### Metrics
To see the Metrics go to /_mon/_stat to get in json To see the Metrics go to /_mon/_stat or /_mon/_stat?viewType=list to get in json
to see in html go to /static/metrics.html to see in html go to /static/metrics.html
### ZMQRestService ### ZMQRestService
![alt text](ZMQRestService.png) ![alt text](ZMQRestService.png)
...@@ -24,4 +24,19 @@ ...@@ -24,4 +24,19 @@
- add static page for monitor metrics that calls http://localhost:32000/_mon/_stat?viewType=list - add static page for monitor metrics that calls http://localhost:32000/_mon/_stat?viewType=list
- periodically via jquery and display the metrics in a table - periodically via jquery and display the metrics in a table
- Add zipkin to trace and monitor requests across microservices - Add zipkin to trace and monitor requests across microservices
\ No newline at end of file - Check Elasticsearch RestClient as the http rest client
- extend the HystrixObservableCommand for the async http client:
public class ObservableHttpCommand extends HystrixObsverableCommand<BackendResponse> {
@Override
protected Observable<BackendResponse> construct() {
return httpClient.submit(HttpClientRequest.createGet("/mock.json?numItems=" + numItems))
.flatMap((HttpClientResponse<ByteBuf> r) -> r.getContent()
.map(b -> BackendResponse.fromJson(new ByteBufInputStream(b))));
}
@Override
protected Observable<BackendResponse> resumeWithFallback() {
return Observable.just(new BackendResponse(0, numItems, new String[] {}));
}}
\ No newline at end of file
...@@ -543,14 +543,14 @@ public class MicroserviceApp ...@@ -543,14 +543,14 @@ public class MicroserviceApp
return this; return this;
} }
CommonServices.IService getService(Enums.EnumServiceType serviceType, String serviceKey){ public CommonServices.IService getService(Enums.EnumServiceType serviceType, String serviceKey){
Map<String, CommonServices.IService> serviceMap = servicesArray[serviceType.ordinal()]; Map<String, CommonServices.IService> serviceMap = servicesArray[serviceType.ordinal()];
if (serviceMap != null) if (serviceMap != null)
return serviceMap.get(serviceKey); return serviceMap.get(serviceKey);
return null; return null;
} }
CommonServices.IService getService(String serviceKey){ public CommonServices.IService getService(String serviceKey){
Optional<CommonServices.IService> iServiceOptional = Arrays.stream(servicesArray) Optional<CommonServices.IService> iServiceOptional = Arrays.stream(servicesArray)
.filter(serviceMap -> serviceMap != null && serviceMap.containsKey(serviceKey)) .filter(serviceMap -> serviceMap != null && serviceMap.containsKey(serviceKey))
.map(serviceMap -> serviceMap.get(serviceKey)) .map(serviceMap -> serviceMap.get(serviceKey))
......
...@@ -17,6 +17,7 @@ public class Constants ...@@ -17,6 +17,7 @@ public class Constants
public static final String INVALID_REQUEST_TOKEN = "invalid request/token"; public static final String INVALID_REQUEST_TOKEN = "invalid request/token";
public static final String AUTHORIZATION_HEADER = "Authorization"; public static final String AUTHORIZATION_HEADER = "Authorization";
public static final String TYPE_PREFIX_SEPERATOR = ":"; public static final String TYPE_PREFIX_SEPERATOR = ":";
public static final String SLASH_SEPERATOR = "/";
public static final String EXIT_MSG = "exit"; public static final String EXIT_MSG = "exit";
public static final int EXIT_MSG_LEN = EXIT_MSG.length(); public static final int EXIT_MSG_LEN = EXIT_MSG.length();
public static final int STRING_INITIAL_CAPACITY = 64; public static final int STRING_INITIAL_CAPACITY = 64;
......
package microservice.handlers; package microservice.handlers;
import io.undertow.util.PathMatcher;
import io.undertow.util.PathTemplateMatcher; import io.undertow.util.PathTemplateMatcher;
import microservice.defs.Constants; import microservice.defs.Constants;
import microservice.defs.Enums; import microservice.defs.Enums;
...@@ -57,10 +58,15 @@ public class Reactor implements CommonServices.IServiceReactor { ...@@ -57,10 +58,15 @@ public class Reactor implements CommonServices.IServiceReactor {
} }
} }
/// the methods hashmap /**
private final PathTemplateMatcher<MethodMatch> methodsMap = new PathTemplateMatcher<>(); * the methods hashmaps, we use 2 one for exact match i.e like swagger api
* the other is for prefix/wildcard use and we're using it when the first one fails
*/
///
private final PathTemplateMatcher<MethodMatch> exactMethodsMap = new PathTemplateMatcher<>();
private final PathMatcher<MethodMatch> prefixMethodsMap = new PathMatcher<>();
private final List<String> methodKeyList = new ArrayList<>(); private final List<String> methodKeyList = new ArrayList<>();
//private Map<String,BiConsumer<CommonServices.IMsgContext,CommonServices.IService>> methodsMap = new HashMap<>();
private IMetricsFactory metricsFactory = null; private IMetricsFactory metricsFactory = null;
/// the metrics map /// the metrics map
private Map<String,MethodMetrics> methodMetricsMap = null; private Map<String,MethodMetrics> methodMetricsMap = null;
...@@ -74,20 +80,23 @@ public class Reactor implements CommonServices.IServiceReactor { ...@@ -74,20 +80,23 @@ public class Reactor implements CommonServices.IServiceReactor {
* build the key * build the key
*/ */
String key = buildServiceKey(methodParams); String key = buildServiceKey(methodParams);
methodsMap.add(key,new MethodMatch(methodParams.getConsumerMethod())); final MethodMatch methodMatch = new MethodMatch(methodParams.getConsumerMethod());
exactMethodsMap.add(key, methodMatch);
prefixMethodsMap.addPrefixPath(key,methodMatch);
methodKeyList.add(key); methodKeyList.add(key);
} }
public static String buildServiceKey(CommonServices.MethodParams methodParams) { public static String buildServiceKey(CommonServices.MethodParams methodParams) {
return methodParams.getServiceType().name() + Constants.TYPE_PREFIX_SEPERATOR + return Constants.SLASH_SEPERATOR +
methodParams.getServiceCommand().toString() + Constants.TYPE_PREFIX_SEPERATOR + methodParams.getServiceType().name() + Constants.TYPE_PREFIX_SEPERATOR +
methodParams.getResourceUri(); methodParams.getServiceCommand().toString() + Constants.TYPE_PREFIX_SEPERATOR +
methodParams.getResourceUri();
} }
public static String buildServiceKey(Enums.EnumServiceType enumServiceType, public static String buildServiceKey(Enums.EnumServiceType enumServiceType,
CommonServices.IServiceCommands serviceCommands, CommonServices.IServiceCommands serviceCommands,
String resourceUri) { String resourceUri) {
return new StringBuilder(32).append(enumServiceType.name()).append(Constants.TYPE_PREFIX_SEPERATOR) return new StringBuilder(32).append(Constants.SLASH_SEPERATOR).append(enumServiceType.name()).append(Constants.TYPE_PREFIX_SEPERATOR)
.append(serviceCommands.toString()).append(Constants.TYPE_PREFIX_SEPERATOR) .append(serviceCommands.toString()).append(Constants.TYPE_PREFIX_SEPERATOR)
.append(resourceUri).toString(); .append(resourceUri).toString();
} }
...@@ -103,16 +112,34 @@ public class Reactor implements CommonServices.IServiceReactor { ...@@ -103,16 +112,34 @@ public class Reactor implements CommonServices.IServiceReactor {
public boolean delegate(CommonServices.IService orgService, String key, CommonServices.IMsgContext msgContext){ public boolean delegate(CommonServices.IService orgService, String key, CommonServices.IMsgContext msgContext){
MethodMetrics methodMetrics = null; MethodMetrics methodMetrics = null;
boolean result = true; boolean result = true;
final PathTemplateMatcher.PathMatchResult<MethodMatch> match = methodsMap.match(key); MethodMatch methodMatch = null;
String matchedTemplate = null;
Map<String, String> exactMatchParameters = null;
final PathTemplateMatcher.PathMatchResult<MethodMatch> exactMatch = exactMethodsMap.match(key);
if (exactMatch != null) {
methodMatch = exactMatch.getValue();
matchedTemplate = exactMatch.getMatchedTemplate();
exactMatchParameters = exactMatch.getParameters();
} else {
/**
* checking for prefix, key must start with '/'
*/
final PathMatcher.PathMatch<MethodMatch> prefixMatch = prefixMethodsMap.match(key);
if (prefixMatch != null) {
methodMatch = prefixMatch.getValue();
matchedTemplate = key.substring(0,key.length() - prefixMatch.getRemaining().length());
}
}
try { try {
if (match != null && match.getValue().getMethodCallback() != null) { if (methodMatch != null && methodMatch.getMethodCallback() != null) {
msgContext.setParameters(match.getParameters()); if (exactMatchParameters != null)
final BiConsumer<CommonServices.IMsgContext, CommonServices.IService> methodCallback = match.getValue().getMethodCallback(); msgContext.setParameters(exactMatchParameters);
final BiConsumer<CommonServices.IMsgContext, CommonServices.IService> methodCallback = methodMatch.getMethodCallback();
/** /**
* pre-handling * pre-handling
*/ */
if (metricsFactory != null) { if (metricsFactory != null && matchedTemplate != null) {
methodMetrics = methodMetricsMap.get(match.getMatchedTemplate()); methodMetrics = methodMetricsMap.get(matchedTemplate);
if (methodMetrics != null) if (methodMetrics != null)
methodMetrics.preHandle(); methodMetrics.preHandle();
} }
...@@ -134,8 +161,8 @@ public class Reactor implements CommonServices.IServiceReactor { ...@@ -134,8 +161,8 @@ public class Reactor implements CommonServices.IServiceReactor {
return result; return result;
} }
public final PathTemplateMatcher<MethodMatch> getMethodsMap() { public final PathTemplateMatcher<MethodMatch> getExactMethodsMap() {
return methodsMap; return exactMethodsMap;
} }
public Reactor withMetricsFactory(IMetricsFactory metricsFactory) { public Reactor withMetricsFactory(IMetricsFactory metricsFactory) {
......
...@@ -138,8 +138,25 @@ public class IRestServiceHttpImpl extends CommonServices.IRestService implements ...@@ -138,8 +138,25 @@ public class IRestServiceHttpImpl extends CommonServices.IRestService implements
@Override @Override
public boolean init() { public boolean init() {
boolean stat = true;
logger = MicroserviceApp.getsInstance().getLogger(); logger = MicroserviceApp.getsInstance().getLogger();
this.appName = MicroserviceApp.getsInstance().getAppName(); this.appName = MicroserviceApp.getsInstance().getAppName();
switch (getServiceMode()){
case E_CLIENT:
break;
case E_CLIENT_SERVER:
case E_SERVER:
stat = buildRestServer();
break;
default:
stat = false;
logger.error(getClass().getName() + " >> no service mode!!!");
break;
}
return stat;
}
private boolean buildRestServer() {
String host = this.restServerParams.getHost(); String host = this.restServerParams.getHost();
if (host == null || Network.LOCALHOST.equals(host)) if (host == null || Network.LOCALHOST.equals(host))
host = Network.getLocalIpAddress(); host = Network.getLocalIpAddress();
...@@ -167,8 +184,7 @@ public class IRestServiceHttpImpl extends CommonServices.IRestService implements ...@@ -167,8 +184,7 @@ public class IRestServiceHttpImpl extends CommonServices.IRestService implements
serverBuilder.setHandler(pathHandler); serverBuilder.setHandler(pathHandler);
// build // build
this.restServer = serverBuilder.build(); this.restServer = serverBuilder.build();
return (this.restServer != null);
return true;
} }
......
...@@ -7,13 +7,16 @@ ...@@ -7,13 +7,16 @@
<script> <script>
// Builds the HTML Table out of myList. // Builds the HTML Table out of myList.
function buildHtmlTable(data) { function buildHtmlTable(data) {
var selector = '#meterTable'; var selector = '#meterTable';
$(selector).empty()
var list = data.objectNode.meters; var list = data.objectNode.meters;
var columns = addAllColumnHeaders(list, selector); var columns = addAllColumnHeaders(list, selector);
addRows(selector,columns,list); addRows(selector,columns,list);
selector = '#timerTable'; selector = '#timerTable';
$(selector).empty()
list = data.objectNode.timers; list = data.objectNode.timers;
columns = addAllColumnHeaders(list, selector); columns = addAllColumnHeaders(list, selector);
...@@ -38,6 +41,7 @@ function addRows(selector,columns,myList){ ...@@ -38,6 +41,7 @@ function addRows(selector,columns,myList){
// Need to do union of keys from all records as some records may not contain // Need to do union of keys from all records as some records may not contain
// all records. // all records.
function addAllColumnHeaders(myList, selector) { function addAllColumnHeaders(myList, selector) {
var columnSet = []; var columnSet = [];
var headerTr$ = $('<tr/>'); var headerTr$ = $('<tr/>');
...@@ -56,18 +60,32 @@ function addAllColumnHeaders(myList, selector) { ...@@ -56,18 +60,32 @@ function addAllColumnHeaders(myList, selector) {
} }
$(document).ready(function(){ $(document).ready(function(){
$.get("http://localhost:32000/_mon/_stat?viewType=list", function(data, status){
/* $.get("http://localhost:32000/_mon/_stat?viewType=list", function(data, status){
buildHtmlTable(data); buildHtmlTable(data);
}); });
*/
(function poll() {
$.ajax({
url: "/_mon/_stat?viewType=list",
type: "GET",
success: function(data) {
buildHtmlTable(data);
},
dataType: "json",
complete: setTimeout(function() {poll()}, 5000),
timeout: 2000
})
})();
}); });
</script> </script>
</head> </head>
<body> <body>
<table id="meterTable" border="1"> <table id="meterTable" class="highlight striped bordered">
</table> </table>
<table id="timerTable" border="1"> <table class="striped" id="timerTable" border="1">
</table> </table>
</body> </body>
......
...@@ -24,7 +24,6 @@ public class TestMicroClient ...@@ -24,7 +24,6 @@ public class TestMicroClient
MicroserviceClient client = null; MicroserviceClient client = null;
BaseRestResponse brr = null; BaseRestResponse brr = null;
RestClientParams clientParams = new RestClientParams("ds",true,0, "172.16.1.244:8080",null,100); RestClientParams clientParams = new RestClientParams("ds",true,0, "172.16.1.244:8080",null,100);
final IServiceDiscoveryConsulImpl serDisco = new IServiceDiscoveryConsulImpl("localhost", 8500); final IServiceDiscoveryConsulImpl serDisco = new IServiceDiscoveryConsulImpl("localhost", 8500);
......
...@@ -123,6 +123,12 @@ public class TestMicroserviceApp { ...@@ -123,6 +123,12 @@ public class TestMicroserviceApp {
(msgCtx,orgService) -> { (msgCtx,orgService) -> {
resourceRid((RestContext)msgCtx); resourceRid((RestContext)msgCtx);
})); }));
methodParamsList.add(new CommonServices.MethodParams(Enums.EnumServiceType.E_REST,
CommonServices.EnumRestCommands.E_READ,
"/resource/r1",
(msgCtx,orgService) -> {
resourceRid((RestContext)msgCtx);
}));
methodParamsList.add(new CommonServices.MethodParams(Enums.EnumServiceType.E_REST, methodParamsList.add(new CommonServices.MethodParams(Enums.EnumServiceType.E_REST,
CommonServices.EnumRestCommands.E_CREATE, CommonServices.EnumRestCommands.E_CREATE,
"/resource/{rid}", "/resource/{rid}",
......
...@@ -12,6 +12,7 @@ import com.google.common.cache.Cache; ...@@ -12,6 +12,7 @@ import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheBuilder;
import common.JsonHandler; import common.JsonHandler;
import io.undertow.predicate.Predicate; import io.undertow.predicate.Predicate;
import io.undertow.util.PathMatcher;
import io.undertow.util.PathTemplateMatcher; import io.undertow.util.PathTemplateMatcher;
import microservice.services.CommonServices; import microservice.services.CommonServices;
import microservice.services.IRestServiceZmqImpl; import microservice.services.IRestServiceZmqImpl;
...@@ -56,8 +57,8 @@ public class TestServicesAndMethods { ...@@ -56,8 +57,8 @@ public class TestServicesAndMethods {
@Test @Test
public void testMatcher(){ public void testMatcher(){
final PathTemplateMatcher<RoutingMatch> allMethodsMatcher = new PathTemplateMatcher<>(); //final PathTemplateMatcher<RoutingMatch> allMethodsMatcher = new PathTemplateMatcher<>();
PathMatcher<RoutingMatch> allMethodsMatcher = new PathMatcher<>();
addMatch(allMethodsMatcher, "/baz/{foo}"); addMatch(allMethodsMatcher, "/baz/{foo}");
addMatch(allMethodsMatcher, "/baz/ok/{foo}"); addMatch(allMethodsMatcher, "/baz/ok/{foo}");
...@@ -69,8 +70,9 @@ public class TestServicesAndMethods { ...@@ -69,8 +70,9 @@ public class TestServicesAndMethods {
findMatch(allMethodsMatcher, "/baz/ok"); findMatch(allMethodsMatcher, "/baz/ok");
findMatch(allMethodsMatcher, "/baz/entities"); findMatch(allMethodsMatcher, "/baz/entities");
findMatch(allMethodsMatcher, "/baz/entities/entity/"); findMatch(allMethodsMatcher, "/baz/entities/entity/");
long start = System.currentTimeMillis(); findMatch(allMethodsMatcher, "/baz/entities/entity/a/s/d");
long start = System.currentTimeMillis();
for (int i = 0; i < ITERATIONS; i++) { for (int i = 0; i < ITERATIONS; i++) {
findMatch(allMethodsMatcher, "REST:GET:/baz/entities/entity/12345"); findMatch(allMethodsMatcher, "REST:GET:/baz/entities/entity/12345");
} }
...@@ -78,13 +80,14 @@ public class TestServicesAndMethods { ...@@ -78,13 +80,14 @@ public class TestServicesAndMethods {
} }
public void addMatch(PathTemplateMatcher<RoutingMatch> allMethodsMatcher, String template1) { public void addMatch(PathMatcher<RoutingMatch> allMethodsMatcher, String template1) {
RoutingMatch res1 = new RoutingMatch(); RoutingMatch res1 = new RoutingMatch();
allMethodsMatcher.add(template1, res1); allMethodsMatcher.addPrefixPath(template1, res1);
} }
public void findMatch(PathTemplateMatcher<RoutingMatch> allMethodsMatcher, String path) { public void findMatch(PathMatcher<RoutingMatch> allMethodsMatcher, String path) {
PathTemplateMatcher.PathMatchResult<RoutingMatch> match = allMethodsMatcher.match(path); //PathTemplateMatcher.PathMatchResult<RoutingMatch> match = allMethodsMatcher.match(path);
final PathMatcher.PathMatch<RoutingMatch> match = allMethodsMatcher.match(path);
if (match == null) if (match == null)
System.out.println("Failed to find handler for: " + path); System.out.println("Failed to find handler for: " + path);
// else // else
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment