/*
* Copyright 2015-2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed 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.hawkular.inventory.rest;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.annotation.PostConstruct;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import org.jboss.resteasy.core.Dispatcher;
import org.jboss.resteasy.core.ResourceInvoker;
import org.jboss.resteasy.core.ResourceMethodInvoker;
import org.jboss.resteasy.core.ResourceMethodRegistry;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
/**
* @author Lukas Krejci
* @since 0.0.1
*/
@Path("/")
@Produces(value = APPLICATION_JSON)
@Consumes(value = APPLICATION_JSON)
@Api(value = "/", tags = "API Info")
public class RestPing {
@Context
private Dispatcher dispatcher;
private InventoryJaxRsInfo inventoryJaxRsInfo;
@PostConstruct
private void init() {
inventoryJaxRsInfo = getEndpoints((ResourceMethodRegistry)dispatcher.getRegistry());
Collections.sort(inventoryJaxRsInfo.getEndpoints());
}
@GET
@Path("/")
@ApiOperation(value = "List Endpoints", notes = "Lists all the REST API endpoints available")
public Response ping(@Context Dispatcher dispatcher) {
return Response.status(Response.Status.OK).entity(inventoryJaxRsInfo).build();
}
private InventoryJaxRsInfo getEndpoints(ResourceMethodRegistry resourceMethodRegistry) {
InventoryJaxRsInfo inventoryJaxRsInfo = new InventoryJaxRsInfo();
for (Map.Entry<String, List<ResourceInvoker>> entry : resourceMethodRegistry.getBounded().entrySet()) {
String uri = entry.getKey();
JaxRsResource jaxRsResource = new JaxRsResource(uri);
for (ResourceInvoker invoker : entry.getValue()) {
if (invoker instanceof ResourceMethodInvoker) {
ResourceMethodInvoker method = (ResourceMethodInvoker) invoker;
if (method.getMethod().getDeclaringClass() == getClass()) {
continue;
}
method.getHttpMethods().forEach(jaxRsResource::addMethod);
} else {
continue;
}
}
if (jaxRsResource.getMethods().size() > 0) {
inventoryJaxRsInfo.addJaxRsResources(jaxRsResource);
}
}
return inventoryJaxRsInfo;
}
public static class InventoryJaxRsInfo {
private static final String DOC_URL = "http://www.hawkular.org/";
private List<JaxRsResource> endpoints = new ArrayList<>();
public String getDocumentation() {
return DOC_URL;
}
public List<JaxRsResource> getEndpoints() {
return endpoints;
}
public boolean addJaxRsResources(JaxRsResource jaxRsResources) {
return this.endpoints.add(jaxRsResources);
}
}
public static class JaxRsResource implements Comparable<JaxRsResource> {
private static final Pattern NAME_PATTERN = Pattern.compile("(/[a-zA-Z]+)");
private Set<String> methods = new HashSet<>();
private String uri;
public JaxRsResource(String uri) {
this.uri = uri;
}
public boolean addMethod(String method) {
return methods.add(method);
}
public Set<String> getMethods() {
return methods;
}
public String getUri() {
return uri;
}
public void setUri(String uri) {
this.uri = uri;
}
private String getUriPattern(String uri) {
Matcher matcher = NAME_PATTERN.matcher(uri);
if (matcher.find()) {
return matcher.group();
}
return uri;
}
@Override
public int compareTo(JaxRsResource that) {
if (this == that) {
return 0;
}
String other = getUriPattern(that.getUri());
String current = getUriPattern(this.uri);
return current.compareTo(other);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof JaxRsResource)) return false;
JaxRsResource that = (JaxRsResource) o;
return !(uri != null ? !uri.equals(that.uri) : that.uri != null);
}
@Override
public int hashCode() {
return uri != null ? uri.hashCode() : 0;
}
}
}