All Downloads are FREE. Search and download functionalities are using the official Maven repository.

restx.specs.RestxSpecRepository Maven / Gradle / Ivy

There is a newer version: 1.2.0-rc2
Show newest version
package restx.specs;

import com.google.common.base.Charsets;
import com.google.common.base.Optional;
import com.google.common.collect.*;
import com.google.common.io.CharSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import restx.*;
import restx.common.MoreResources;
import restx.factory.Component;

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;
import java.util.Collection;
import java.util.Map;
import java.util.regex.Pattern;

/**
 * User: xavierhanin
 * Date: 4/8/13
 * Time: 12:40 PM
 */
@Component
public class RestxSpecRepository {
    private static final Logger logger = LoggerFactory.getLogger(RestxSpecRepository.class);

    private ImmutableMap allSpecs;
    private RestxSpecLoader specLoader;

    public RestxSpecRepository(RestxSpecLoader specLoader) {
        this.specLoader = specLoader;
    }


    public Iterable findAll() {
        return findAllSpecs().keySet();
    }

    public Optional findSpecById(String id) {
        return Optional.fromNullable(findAllSpecs().get(id));
    }

    public Iterable findSpecsByOperation(String httpMethod, String path) {
        return filterSpecsByOperation(findAllSpecs(), httpMethod, path);
    }

    public Iterable findSpecsByRequest(RestxRequest request) {
        return findWhensMatchingRequest(findAllSpecs(), request);
    }

    synchronized ImmutableMap findAllSpecs() {
        if (allSpecs == null) {
            allSpecs = ImmutableMap.copyOf(buildSpecsMap(false));
        }
        return allSpecs;
    }

    protected Map buildSpecsMap(boolean searchInSources) {
        Map specsMap = Maps.newLinkedHashMap();
        Map specs = MoreResources.findResources("", Pattern.compile(".*\\.spec\\.yaml"), searchInSources);
        for (final Map.Entry spec : specs.entrySet()) {
            try {
                specsMap.put(spec.getKey(), specLoader.load(spec.getKey(), new CharSource() {
                    @Override
                    public Reader openStream() throws IOException {
                        return new InputStreamReader(spec.getValue().openStream(), Charsets.UTF_8);
                    }
                }));
            } catch (Exception e) {
                logger.warn("exception while loading restx spec " + spec + ": " + e, e);
            }
        }
        return specsMap;
    }

    Iterable filterSpecsByOperation(ImmutableMap allSpecs,
                                                    String httpMethod, String path) {
        StdRestxRequestMatcher matcher = new StdRestxRequestMatcher(httpMethod, path);
        Collection specs = Lists.newArrayList();
        for (Map.Entry spec : allSpecs.entrySet()) {
            for (When when : spec.getValue().getWhens()) {
                if (when instanceof WhenHttpRequest) {
                    WhenHttpRequest request = (WhenHttpRequest) when;
                    String requestPath = request.getPath();
                    if (!requestPath.startsWith("/")) {
                        requestPath = "/" + requestPath;
                    }
                    if (requestPath.indexOf("?") != -1) {
                        requestPath = requestPath.substring(0, requestPath.indexOf("?"));
                    }
                    Optional match = matcher.match(request.getMethod(), requestPath);
                    if (match.isPresent()) {
                        specs.add(spec.getKey());
                        break;
                    }
                }
            }
        }
        return specs;
    }

    Iterable findWhensMatchingRequest(ImmutableMap allSpecs, RestxRequest restxRequest) {
        Collection matchingRequestsSpecs = Lists.newArrayList();
        for (Map.Entry spec : allSpecs.entrySet()) {
            for (When when : spec.getValue().getWhens()) {
                if (when instanceof WhenHttpRequest) {
                    WhenHttpRequest request = (WhenHttpRequest) when;
                    String requestPath = request.getPath();
                    if (!requestPath.startsWith("/")) {
                        requestPath = "/" + requestPath;
                    }
                    StdRequest stdRequest = StdRequest.builder()
                            .setBaseUri("http://restx.io") // baseUri is required but we won't use it
                            .setHttpMethod(request.getMethod()).setFullPath(requestPath).build();

                    if (restxRequest.getHttpMethod().equals(stdRequest.getHttpMethod())
                            && restxRequest.getRestxPath().equals(stdRequest.getRestxPath())) {
                        MapDifference> difference =
                                Maps.difference(restxRequest.getQueryParams(), stdRequest.getQueryParams());
                        if (difference.entriesOnlyOnRight().isEmpty()
                                && difference.entriesDiffering().isEmpty()) {
                            matchingRequestsSpecs.add(request);
                            break;
                        }
                    }
                }
            }
        }
        return matchingRequestsSpecs;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy