Java tutorial
/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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.tomitribe.beryllium.mocks; import com.google.common.collect.Multimap; import com.google.common.collect.Multimaps; import com.xebialabs.restito.builder.stub.StubHttp; import com.xebialabs.restito.semantics.Action; import com.xebialabs.restito.semantics.Applicable; import com.xebialabs.restito.semantics.Condition; import com.xebialabs.restito.semantics.ConditionWithApplicables; import com.xebialabs.restito.semantics.Function; import com.xebialabs.restito.server.StubServer; import cucumber.api.DataTable; import cucumber.api.java.After; import cucumber.api.java.Before; import cucumber.api.java.en.Given; import lombok.Value; import org.glassfish.grizzly.http.server.Response; import org.glassfish.grizzly.http.util.HttpStatus; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.Map; import static com.xebialabs.restito.builder.stub.StubHttp.whenHttp; import static com.xebialabs.restito.semantics.Action.composite; import static com.xebialabs.restito.semantics.Action.custom; import static com.xebialabs.restito.semantics.Action.resourceContent; import static com.xebialabs.restito.semantics.Action.status; import static com.xebialabs.restito.semantics.Condition.delete; import static com.xebialabs.restito.semantics.Condition.get; import static com.xebialabs.restito.semantics.Condition.parameter; import static com.xebialabs.restito.semantics.Condition.post; import static com.xebialabs.restito.semantics.Condition.put; public class CallsSteps { private StubServer server; private StubHttp stubHttp; @Before public void setUp() { server = new StubServer(9090).run(); stubHttp = whenHttp(server); } @After public void tearDown() { server.stop(); } @Given("^The call to external service should be:$") public void theCallToExternalServiceShouldBe(final DataTable data) throws Throwable { final Multimap<Call, Call> calls = Multimaps.index(data.asList(Call.class), new com.google.common.base.Function<Call, Call>() { @Override public Call apply(Call call) { return new Call(call.getMethod(), call.getUrl(), -1, null); } }); for (final Map.Entry<Call, Collection<Call>> groupedCalls : calls.asMap().entrySet()) { final List<Action> actions = new ArrayList<>(groupedCalls.getValue().size()); for (Call call : groupedCalls.getValue()) { actions.add(composite(status(HttpStatus.getHttpStatus(call.getStatusCode())), resourceContent(Thread .currentThread().getContextClassLoader().getResource("fixtures/" + call.getFilename())))); } final Call key = groupedCalls.getKey(); stubHttp.match(key.getHttpMethod(), key.buildQueryParams()).then(sequential(actions)); } } /** * Creates a composite action which contains all passed actions and * executes them one by one on different invocations. */ private static <T extends Applicable> Action sequential(final Iterable<T> actions) { return custom(new Function<Response, Response>() { private final Iterator<T> iterator = actions.iterator(); private T last; @Override public Response apply(final Response input) { if (iterator.hasNext()) last = iterator.next(); return last.apply(input); } }); } @Value private static class Call { private String method; private String url; private int statusCode; private String filename; ConditionWithApplicables getHttpMethod() { switch (getMethod().toUpperCase()) { case "POST": return post(buildUrl()); case "PUT": return put(buildUrl()); case "DELETE": return delete(buildUrl()); case "GET": return get(buildUrl()); default: return get(buildUrl()); } } String buildUrl() { return (getUrl().contains("?")) ? getUrl().split("\\?")[0] : getUrl(); } Condition buildQueryParams() { final String queryParamsStr = (getUrl().contains("?")) ? getUrl().split("\\?")[1] : null; final String[] kvs = queryParamsStr != null ? queryParamsStr.split("\\&") : new String[0]; final List<Condition> conditions = new ArrayList<>(); for (final String kv : kvs) { final String[] sp = kv.split("\\="); conditions.add(parameter(sp[0], sp[1])); } return Condition.composite(conditions.toArray(new Condition[conditions.size()])); } } }