/* * 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.apache.geode.tools.pulse; import static com.jayway.awaitility.Awaitility.await; import static org.assertj.core.api.Assertions.assertThat; import org.apache.geode.cache.client.ClientCacheFactory; import org.apache.geode.cache.client.ClientRegionShortcut; import org.apache.geode.test.dunit.IgnoredException; import org.apache.geode.test.dunit.internal.JUnit4DistributedTestCase; import org.apache.geode.test.dunit.rules.GfshShellConnectionRule; import org.apache.geode.test.dunit.rules.Locator; import org.apache.geode.test.dunit.rules.LocatorServerStartupRule; import org.apache.geode.test.junit.categories.DistributedTest; import org.apache.http.Consts; import org.apache.http.Header; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.client.CookieStore; import org.apache.http.client.HttpClient; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.client.utils.URIBuilder; import org.apache.http.cookie.Cookie; import org.apache.http.impl.client.BasicCookieStore; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.message.BasicNameValuePair; import org.apache.http.protocol.BasicHttpContext; import org.apache.http.protocol.HttpContext; import org.apache.http.util.EntityUtils; import org.junit.Before; import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.experimental.categories.Category; import java.io.IOException; import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Properties; import java.util.concurrent.TimeUnit; @Category(DistributedTest.class) public class PulseDataExportTest extends JUnit4DistributedTestCase { @Rule public LocatorServerStartupRule lsRule = new LocatorServerStartupRule(); private Locator locator; private org.apache.geode.test.dunit.rules.Server server; private GfshShellConnectionRule gfshConnector; private HttpClient httpClient; private CookieStore cookieStore; @Before public void before() throws Throwable { IgnoredException .addIgnoredException("Failed to properly release resources held by the HTTP service:"); IgnoredException.addIgnoredException("!STOPPED"); locator = lsRule.startLocatorVMWithPulse(0, new Properties()); gfshConnector = new GfshShellConnectionRule(locator); gfshConnector.connect(); assertThat(gfshConnector.isConnected()).isTrue(); server = lsRule.startServerVM(1, locator.getPort()); gfshConnector.executeAndVerifyCommand("create region --name=regionA --type=REPLICATE"); org.apache.geode.cache.Region<String, String> region = new ClientCacheFactory() .addPoolLocator("localhost", locator.getPort()).create() .<String, String>createClientRegionFactory(ClientRegionShortcut.PROXY).create("regionA"); region.put("key1", "value1"); region.put("key2", "value2"); region.put("key3", "value3"); cookieStore = new BasicCookieStore(); httpClient = HttpClientBuilder.create().setDefaultCookieStore(cookieStore).build(); await().atMost(2, TimeUnit.MINUTES).until(this::pulseServerHasStarted); } @Test public void dataBrowserExportWorksAsExpected() throws Throwable { getAuthenticatedJSESSIONID(); HttpContext authenticatedHttpContext = buildAuthenticatedHttpContext(); HttpGet dataExportGET = buildDataExportGET(); HttpResponse response = httpClient.execute(dataExportGET, authenticatedHttpContext); assertThat(response.getStatusLine().getStatusCode()).describedAs(response.toString()) .isEqualTo(200); String responseBody = EntityUtils.toString(response.getEntity(), "UTF-8"); assertThat(responseBody).describedAs(response.toString()).isEqualTo( "{\"result\":[[\"java.lang.String\",\"value1\"],[\"java.lang.String\",\"value2\"],[\"java.lang.String\",\"value3\"]]}"); } private HttpPost buildLoginPOST() { HttpPost httpPost = new HttpPost("http://localhost:7070/pulse/login"); List<NameValuePair> formData = new ArrayList<>(); formData.add(new BasicNameValuePair("username", "admin")); formData.add(new BasicNameValuePair("password", "admin")); httpPost.setEntity(new UrlEncodedFormEntity(formData, Consts.UTF_8)); return httpPost; } private HttpGet buildDataExportGET() throws URISyntaxException { URIBuilder builder = new URIBuilder(); builder.setScheme("http").setHost("localhost").setPort(7070).setPath("/pulse/dataBrowserExport") .setParameter("query", "select * from /regionA a order by a"); return new HttpGet(builder.build()); } private HttpContext buildAuthenticatedHttpContext() throws Throwable { HttpContext localContext = new BasicHttpContext(); localContext.setAttribute(HttpClientContext.COOKIE_STORE, cookieStore); return localContext; } public void getAuthenticatedJSESSIONID() throws Throwable { HttpResponse loginResponse = httpClient.execute(buildLoginPOST()); assertThat(loginResponse.getStatusLine().getStatusCode()).describedAs(loginResponse.toString()) .isEqualTo(302); String JSESSIONIDFromSetCookieHeader = Arrays.stream(loginResponse.getHeaders("SET-COOKIE")) .map(Header::getValue).filter(setCookie -> setCookie.contains("JSESSIONID")).findAny() .orElseThrow(() -> new AssertionError( "No JSESSIONID cookie was set in the login response: " + loginResponse.toString())); Cookie JESSIONIDFromCookieStore = cookieStore.getCookies().stream() .filter(cookie -> cookie.getName().equalsIgnoreCase("JSESSIONID")).findFirst() .orElseThrow(() -> new AssertionError("No JSESSIONID cookie was set in the cookie store")); assertThat(JSESSIONIDFromSetCookieHeader).contains(JESSIONIDFromCookieStore.getValue()); } private boolean pulseServerHasStarted() { try { httpClient.execute(buildLoginPOST()); } catch (IOException e) { e.printStackTrace(); return false; } return true; } }