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

com.epam.healenium.client.RestClient Maven / Gradle / Ivy

The newest version!
/**
 * Healenium-web Copyright (C) 2019 EPAM
 * 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.epam.healenium.client;

import com.epam.healenium.converter.NodeDeserializer;
import com.epam.healenium.converter.NodeSerializer;
import com.epam.healenium.exception.HealeniumException;
import com.epam.healenium.mapper.HealeniumMapper;
import com.epam.healenium.model.ConfigSelectorDto;
import com.epam.healenium.model.Context;
import com.epam.healenium.model.HealedElement;
import com.epam.healenium.model.HealingResult;
import com.epam.healenium.model.Locator;
import com.epam.healenium.model.ReferenceElementsDto;
import com.epam.healenium.model.RequestDto;
import com.epam.healenium.model.SelectorImitatorDto;
import com.epam.healenium.treecomparing.Node;
import com.epam.healenium.treecomparing.Scored;
import com.epam.healenium.utils.SystemUtils;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.typesafe.config.Config;
import lombok.Data;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.openqa.selenium.By;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.remote.http.Contents;
import org.openqa.selenium.remote.http.HttpClient;
import org.openqa.selenium.remote.http.HttpMethod;
import org.openqa.selenium.remote.http.HttpRequest;
import org.openqa.selenium.remote.http.HttpResponse;

import java.io.InputStream;
import java.io.UncheckedIOException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.function.Supplier;
import java.util.stream.Collectors;

import static java.net.HttpURLConnection.HTTP_NOT_FOUND;
import static org.openqa.selenium.json.Json.JSON_UTF_8;

/**
 * Wrapper for {@code RestTemplate} class.
 * Main purpose - encapsulate consumer from really used client and invocation complexity
 */

@Slf4j(topic = "healenium")
@Data
public class RestClient {

    private final String serverUrl;
    private final String imitateUrl;
    private final String sessionKey;
    private ObjectMapper objectMapper;
    private HealeniumMapper mapper;
    private HttpClient serverHttpClient;
    private HttpClient imitateHttpClient;

    public RestClient(Config config) {
        this.objectMapper = initMapper();
        this.sessionKey = config.getString("sessionKey");
        this.serverUrl = getHttpUrl(config.getString("hlm.server.url"), "/healenium");
        this.imitateUrl = getHttpUrl(config.getString("hlm.imitator.url"), "/imitate");
        this.serverHttpClient = getHttpClient(serverUrl);
        this.imitateHttpClient = getHttpClient(imitateUrl);
        log.debug("[Init] sessionKey: {}, serverUrl: {}, imitateUrl: {}", sessionKey, serverUrl, imitateUrl);
    }

    private String getHttpUrl(String hlmServerUrl, String path) {
        return (hlmServerUrl.startsWith("http") ? hlmServerUrl : "http://".concat(hlmServerUrl)).concat(path);
    }

    @SneakyThrows
    private HttpClient getHttpClient(String url) {
        ClientConfig clientConfig = ClientConfig.defaultConfig()
                .baseUrl(new URL(url));
        return HttpClient.Factory.createDefault().createClient(clientConfig);
    }

    private ObjectMapper initMapper() {
        SimpleModule module = new SimpleModule("node");
        module.addSerializer(Node.class, new NodeSerializer());
        module.addDeserializer(Node.class, new NodeDeserializer());
        ObjectMapper mapper = new ObjectMapper().registerModule(module);
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        mapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);
        return mapper;
    }

    /**
     * Store info in backend
     * 

* // * @param by element By locator * // * @param nodePath List of nodes * // * @param currentUrl url of web page */ public void saveElements(RequestDto requestDto) { try { HttpRequest request = new HttpRequest(HttpMethod.POST, ""); String content = objectMapper.writeValueAsString(requestDto); byte[] data = content.getBytes(StandardCharsets.UTF_8); request.setHeader("Content-Length", String.valueOf(data.length)); request.setHeader("Content-Type", JSON_UTF_8); request.setContent(Contents.bytes(data)); log.debug("[Save Elements] By: {}, Locator: {}, Command: {}, URL: {}", requestDto.getType(), requestDto.getLocator(), requestDto.getCommand(), requestDto.getUrl()); serverExecute(request); } catch (Exception e) { log.warn("[Save Elements] Error during call. Message: {}, Exception: {}", e.getMessage(), e.toString()); } } public ConfigSelectorDto getElements() { ConfigSelectorDto configSelectorDto = null; try { HttpRequest request = new HttpRequest(HttpMethod.GET, "/elements"); request.setHeader("Cache-Control", "no-cache"); log.debug("[Get Elements] Request: {}", request); HttpResponse response = serverExecute(request); if (HTTP_NOT_FOUND == response.getStatus()) { throw new RuntimeException("[Get Elements] Compatibility error. Hlm-backend service must be 3.3.0 and height." + "\nActual versions you can find here: https://github.com/healenium/healenium/blob/master/docker-compose-web.yaml"); } Supplier result = response.getContent(); configSelectorDto = objectMapper.readValue(result.get(), new TypeReference() { }); } catch (RuntimeException e) { throw e; } catch (Exception e) { log.warn("[Get Elements] Error during call. Message: {}, Exception: {}", e.getMessage(), e.toString()); } return configSelectorDto; } /** * Collect results from previous healing * * @param context healing context */ public void healRequest(Context context) { try { List requestDtos = new ArrayList<>(); for (HealingResult healingResult : context.getHealingResults()) { List> choices = healingResult.getHealedElements().stream() .map(HealedElement::getScored) .collect(Collectors.toList()); if (choices.isEmpty()) { return; } String metrics = objectMapper.writeValueAsString(healingResult.getMetricsDto()); requestDtos.add(mapper.buildMultRequest(context, healingResult, choices, metrics)); } HttpRequest request = new HttpRequest(HttpMethod.POST, "/healing"); String content = objectMapper.writeValueAsString(requestDtos); byte[] data = content.getBytes(StandardCharsets.UTF_8); request.setHeader("Content-Length", String.valueOf(data.length)); request.setHeader("Content-Type", JSON_UTF_8); request.setHeader("sessionKey", sessionKey); request.setHeader("hostProject", SystemUtils.getHostProjectName()); request.setContent(Contents.bytes(data)); for (RequestDto requestDto : requestDtos) { log.debug("[Save Healed Elements] {}", requestDto.getUsedResult().getLocator()); } serverExecute(request); } catch (Exception e) { log.warn("[Heal Element] Error during call. Message: {}. Exception: {}", e.getMessage(), e.toString()); } } /** * Get node path for given selector * * @param locator element By locator * @param currentUrl url of web page * @param command name of command * @return lastHealingDataDto previous success healing data */ public Optional getReferenceElements(By locator, String command, String currentUrl) { ReferenceElementsDto referenceElementsDto = null; RequestDto requestDto = mapper.buildDto(locator, command, currentUrl); try { HttpRequest request = new HttpRequest(HttpMethod.GET, ""); request.setHeader("Cache-Control", "no-cache") .setHeader("sessionKey", sessionKey) .addQueryParameter("locator", requestDto.getLocator()) .addQueryParameter("className", requestDto.getClassName()) .addQueryParameter("methodName", requestDto.getMethodName()) .addQueryParameter("command", requestDto.getCommand()) .addQueryParameter("url", currentUrl); log.debug("[Get Reference Elements] Request. Locator: {}, Command: {}, Url: {}", requestDto.getLocator(), requestDto.getCommand(), currentUrl); HttpResponse response = serverExecute(request); if (response.getStatus() == 200) { Supplier result = response.getContent(); referenceElementsDto = objectMapper.readValue(result.get(), new TypeReference() { }); } } catch (Exception e) { log.warn("[Get Reference Elements] Error during call. Message: {}. Exception: {}", e.getMessage(), e.toString()); } return Optional.ofNullable(referenceElementsDto); } /** * Get imitated locators by target node and user selector from selector-imitator service * * @param selectorImitatorDto element By locator * @return locators */ public List imitate(SelectorImitatorDto selectorImitatorDto) { try { HttpRequest request = new HttpRequest(HttpMethod.POST, ""); String content = objectMapper.writeValueAsString(selectorImitatorDto); byte[] data = content.getBytes(StandardCharsets.UTF_8); request.setHeader("Content-Length", String.valueOf(data.length)); request.setHeader("Content-Type", JSON_UTF_8); request.setContent(Contents.bytes(data)); HttpResponse response = imitateExecute(request); if (response.getStatus() == 200) { Supplier result = response.getContent(); List locators = objectMapper.readValue(result.get(), new TypeReference>() { }); log.debug("[Selector Imitate] Response: {}", locators); return locators; } } catch (Exception e) { log.warn("[Selector Imitate] Error during call. Message: {}, Exception: {}", e.getMessage(), e.toString()); } return Collections.emptyList(); } public void initReport(String sessionId) { try { HttpRequest request = new HttpRequest(HttpMethod.POST, "/report/init/" + sessionId); request.setHeader("Content-Type", JSON_UTF_8); log.debug("[Init Report] Request: {}", request); serverExecute(request); } catch (Exception e) { log.warn("[Init Report] Error during call. Message: {}, Exception: {}", e.getMessage(), e.toString()); } } private HttpResponse serverExecute(HttpRequest request) { try { return serverHttpClient.execute(request); } catch (UncheckedIOException e) { String errorMessage = "[Execute Error] Unable to connect to the hlm-backend service. " + "Please check if the service is up and running, and verify that the connection URL is correct."; log.error(errorMessage); throw new HealeniumException(errorMessage, e); } } private HttpResponse imitateExecute(HttpRequest request) { try { return imitateHttpClient.execute(request); } catch (UncheckedIOException e) { String errorMessage = "[Execute Error] Unable to connect to the selector-imitator service. " + "Please check if the service is up and running, and verify that the connection URL is correct."; log.error(errorMessage); throw new HealeniumException(errorMessage, e); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy