/** * Copyright 2016 Yahoo Inc. * * 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 com.yahoo.pulsar.discovery.service.web; import static org.testng.Assert.assertEquals; import static org.testng.Assert.fail; import java.util.Map; import java.util.TreeMap; import java.util.concurrent.CompletableFuture; import javax.ws.rs.HttpMethod; import javax.ws.rs.client.Client; import javax.ws.rs.client.ClientBuilder; import javax.ws.rs.client.Entity; import javax.ws.rs.client.Invocation; import javax.ws.rs.client.WebTarget; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import org.apache.bookkeeper.test.PortManager; import org.apache.zookeeper.ZooKeeper; import org.glassfish.jersey.client.ClientConfig; import org.glassfish.jersey.filter.LoggingFilter; import com.google.gson.Gson; import com.google.gson.JsonParseException; import com.google.gson.JsonObject; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import com.google.common.collect.Lists; import com.yahoo.pulsar.client.api.ProducerConsumerBase; import com.yahoo.pulsar.common.policies.data.BundlesData; import com.yahoo.pulsar.discovery.service.server.ServerManager; import com.yahoo.pulsar.discovery.service.server.ServiceConfig; import com.yahoo.pulsar.discovery.service.web.DiscoveryServiceServlet; import com.yahoo.pulsar.zookeeper.ZooKeeperClientFactory; public class DiscoveryServiceWebTest extends ProducerConsumerBase { private Client client = ClientBuilder.newClient(new ClientConfig().register(LoggingFilter.class)); @BeforeMethod @Override protected void setup() throws Exception { super.internalSetup(); super.producerBaseSetup(); } @AfterMethod @Override protected void cleanup() throws Exception { super.internalCleanup(); } /** * 1. Start : Broker and Discovery service. 2. Provide started broker server as active broker to Discovery service * 3. Call GET, PUT, POST request to discovery service that redirects to Broker service and receives response * * @throws Exception */ @Test public void testRiderectUrlWithServerStarted() throws Exception { // 1. start server int port = PortManager.nextFreePort(); ServiceConfig config = new ServiceConfig(); config.setWebServicePort(port); ServerManager server = new ServerManager(config); DiscoveryZooKeeperClientFactoryImpl.zk = mockZookKeeper; Map<String, String> params = new TreeMap<>(); params.put("zookeeperServers", ""); params.put("zookeeperClientFactoryClass", DiscoveryZooKeeperClientFactoryImpl.class.getName()); server.addServlet("/", DiscoveryServiceServlet.class, params); server.start(); String serviceUrl = server.getServiceUri().toString(); String putRequestUrl = serviceUrl + "admin/namespaces/p1/c1/n1"; String postRequestUrl = serviceUrl + "admin/namespaces/p1/c1/n1/replication"; String getRequestUrl = serviceUrl + "admin/namespaces/p1"; /** * verify : every time when vip receives a request: it redirects to above brokers sequentially and broker * returns appropriate response which must not be null. **/ assertEquals(hitBrokerService(HttpMethod.POST, postRequestUrl, Lists.newArrayList("use")), "Cannot set replication on a non-global namespace"); assertEquals(hitBrokerService(HttpMethod.PUT, putRequestUrl, new BundlesData(1)), "Property does not exist"); assertEquals(hitBrokerService(HttpMethod.GET, getRequestUrl, null), "Property does not exist"); server.stop(); } public String hitBrokerService(String method, String url, Object data) throws JsonParseException { Response response = null; try { WebTarget webTarget = client.target(url); Invocation.Builder invocationBuilder = webTarget.request(MediaType.APPLICATION_JSON); if (HttpMethod.PUT.equals(method)) { response = (Response) invocationBuilder.put(Entity.entity(data, MediaType.APPLICATION_JSON)); } else if (HttpMethod.GET.equals(method)) { response = (Response) invocationBuilder.get(); } else if (HttpMethod.POST.equals(method)) { response = (Response) invocationBuilder.post(Entity.entity(data, MediaType.APPLICATION_JSON)); } else { fail("Unsupported http method"); } } catch (Exception e) { // fail fail(); } JsonObject jsonObject = new Gson().fromJson(response.readEntity(String.class), JsonObject.class); String serviceResponse = jsonObject.get("reason").getAsString(); return serviceResponse; } static class DiscoveryZooKeeperClientFactoryImpl implements ZooKeeperClientFactory { static ZooKeeper zk; @Override public CompletableFuture<ZooKeeper> create(String serverList, SessionType sessionType, int zkSessionTimeoutMillis) { return CompletableFuture.completedFuture(zk); } } }