@VisibleForTesting
  Object[] callHttpService( RowMetaInterface rowMeta, Object[] rowData ) throws KettleException {
    HttpClientManager.HttpClientBuilderFacade clientBuilder = HttpClientManager.getInstance().createBuilder();

    if ( data.realConnectionTimeout > -1 ) {
      clientBuilder.setConnectionTimeout( data.realConnectionTimeout );
    }
    if ( data.realSocketTimeout > -1 ) {
      clientBuilder.setSocketTimeout( data.realSocketTimeout );
    }
    if ( StringUtils.isNotBlank( data.realHttpLogin ) ) {
      clientBuilder.setCredentials( data.realHttpLogin, data.realHttpPassword );
    }
    if ( StringUtils.isNotBlank( data.realProxyHost ) ) {
      clientBuilder.setProxy( data.realProxyHost, data.realProxyPort );
    }

    CloseableHttpClient httpClient = clientBuilder.build();

    // Prepare HTTP get
    URI uri = null;
    try {
      URIBuilder uriBuilder = constructUrlBuilder( rowMeta, rowData );

      uri = uriBuilder.build();
      HttpGet method = new HttpGet( uri );

      // Add Custom HTTP headers
      if ( data.useHeaderParameters ) {
        for ( int i = 0; i < data.header_parameters_nrs.length; i++ ) {
          method.addHeader( data.headerParameters[ i ].getName(), data.inputRowMeta.getString( rowData,
            data.header_parameters_nrs[ i ] ) );
          if ( isDebug() ) {
            log.logDebug( BaseMessages.getString( PKG, "HTTPDialog.Log.HeaderValue",
              data.headerParameters[ i ].getName(), data.inputRowMeta
                .getString( rowData, data.header_parameters_nrs[ i ] ) ) );
          }
        }
      }

      Object[] newRow = null;
      if ( rowData != null ) {
        newRow = rowData.clone();
      }
      // Execute request
      CloseableHttpResponse httpResponse = null;
      try {
        // used for calculating the responseTime
        long startTime = System.currentTimeMillis();


        HttpHost target = new HttpHost( uri.getHost(), uri.getPort(), uri.getScheme() );
        // Create AuthCache instance
        AuthCache authCache = new BasicAuthCache();
        // Generate BASIC scheme object and add it to the local
        // auth cache
        BasicScheme basicAuth = new BasicScheme();
        authCache.put( target, basicAuth );
        // Add AuthCache to the execution context
        HttpClientContext localContext = HttpClientContext.create();
        localContext.setAuthCache( authCache );

        // Preemptive authentication
        if ( StringUtils.isNotBlank( data.realProxyHost ) ) {
          httpResponse = httpClient.execute( target, method, localContext );
        } else {
          httpResponse = httpClient.execute( method, localContext );
        }
        // calculate the responseTime
        long responseTime = System.currentTimeMillis() - startTime;
        if ( log.isDetailed() ) {
          log.logDetailed( BaseMessages.getString( PKG, "HTTP.Log.ResponseTime", responseTime, uri ) );
        }
        int statusCode = requestStatusCode( httpResponse );
        // The status code
        if ( isDebug() ) {
          logDebug( BaseMessages.getString( PKG, "HTTP.Log.ResponseStatusCode", "" + statusCode ) );
        }

        String body;
        switch ( statusCode ) {
          case HttpURLConnection.HTTP_UNAUTHORIZED:
            throw new KettleStepException( BaseMessages
              .getString( PKG, "HTTP.Exception.Authentication", data.realUrl ) );
          case -1:
            throw new KettleStepException( BaseMessages
              .getString( PKG, "HTTP.Exception.IllegalStatusCode", data.realUrl ) );
          case HttpURLConnection.HTTP_NO_CONTENT:
            body = "";
            break;
          default:
            HttpEntity entity = httpResponse.getEntity();
            if ( entity != null ) {
              body = StringUtils.isEmpty( meta.getEncoding() ) ? EntityUtils.toString( entity ) : EntityUtils.toString( entity, meta.getEncoding() );
            } else {
              body = "";
            }
            break;
        }

        Header[] headers = searchForHeaders( httpResponse );

        JSONObject json = new JSONObject();
        for ( Header header : headers ) {
          Object previousValue = json.get( header.getName() );
          if ( previousValue == null ) {
            json.put( header.getName(), header.getValue() );
          } else if ( previousValue instanceof List ) {
            List<String> list = (List<String>) previousValue;
            list.add( header.getValue() );
          } else {
            ArrayList<String> list = new ArrayList<String>();
            list.add( (String) previousValue );
            list.add( header.getValue() );
            json.put( header.getName(), list );
          }
        }
        String headerString = json.toJSONString();

        int returnFieldsOffset = rowMeta.size();
        if ( !Utils.isEmpty( meta.getFieldName() ) ) {
          newRow = RowDataUtil.addValueData( newRow, returnFieldsOffset, body );
          returnFieldsOffset++;
        }

        if ( !Utils.isEmpty( meta.getResultCodeFieldName() ) ) {
          newRow = RowDataUtil.addValueData( newRow, returnFieldsOffset, new Long( statusCode ) );
          returnFieldsOffset++;
        }
        if ( !Utils.isEmpty( meta.getResponseTimeFieldName() ) ) {
          newRow = RowDataUtil.addValueData( newRow, returnFieldsOffset, new Long( responseTime ) );
          returnFieldsOffset++;
        }
        if ( !Utils.isEmpty( meta.getResponseHeaderFieldName() ) ) {
          newRow = RowDataUtil.addValueData( newRow, returnFieldsOffset, headerString );
        }

      } finally {
        if ( httpResponse != null ) {
          httpResponse.close();
        }
        // Release current connection to the connection pool once you are done
        method.releaseConnection();
      }
      return newRow;
    } catch ( UnknownHostException uhe ) {
      throw new KettleException( BaseMessages.getString( PKG, "HTTP.Error.UnknownHostException", uhe.getMessage() ) );
    } catch ( Exception e ) {
      throw new KettleException( BaseMessages.getString( PKG, "HTTP.Log.UnableGetResult", uri ), e );
    }
  }
@Test
  public void callHttpServiceWithoutEncoding() throws Exception {
    try ( MockedStatic<HttpClientManager> httpClientManagerMockedStatic = mockStatic( HttpClientManager.class ) ) {
      httpClientManagerMockedStatic.when( HttpClientManager::getInstance ).thenReturn( manager );
      doReturn( null ).when( meta ).getEncoding();
      assertNotEquals( DATA, http.callHttpService( rmi, new Object[] { 0 } )[ 0 ] );
    }
  }