From bf5ec467e1714246662420eb3a6f63e119ae4686 Mon Sep 17 00:00:00 2001 From: "veselinov.viktor" Date: Thu, 24 Jul 2025 11:42:42 +0300 Subject: [PATCH 01/12] Added getting-started, data-tests, headers functionality support --- .../data/http/configuration/HttpSettings.java | 5 + .../data/http/httpContext/HttpContext.java | 45 +++++- .../data/http/infrastructure/Entity.java | 1 + .../data/http/infrastructure/HttpEntity.java | 3 +- .../data/http/infrastructure/HttpHeader.java | 20 +++ .../http/infrastructure/HttpRepository.java | 5 +- .../http/infrastructure/HttpResponse.java | 7 +- .../internal/HttpStatusCode.java | 55 +++++++ framework-tests/bellatrix.data.tests/pom.xml | 20 +++ .../bellatrix.data.getting.started/pom.xml | 28 ++++ .../src/main/java/Artist.java | 20 +++ .../src/main/java/ArtistRepository.java | 20 +++ .../src/main/java/ArtistsConverter.java | 10 ++ .../src/main/resources/application.properties | 15 ++ .../resources/testFrameworkSettings.test.json | 146 ++++++++++++++++++ .../src/test/java/BaseTest.java | 13 ++ pom.xml | 4 +- 17 files changed, 403 insertions(+), 14 deletions(-) create mode 100644 bellatrix.data/src/main/java/solutions/bellatrix/data/http/infrastructure/HttpHeader.java create mode 100644 bellatrix.data/src/main/java/solutions/bellatrix/data/http/infrastructure/internal/HttpStatusCode.java create mode 100644 framework-tests/bellatrix.data.tests/pom.xml create mode 100644 getting-started/bellatrix.data.getting.started/pom.xml create mode 100644 getting-started/bellatrix.data.getting.started/src/main/java/Artist.java create mode 100644 getting-started/bellatrix.data.getting.started/src/main/java/ArtistRepository.java create mode 100644 getting-started/bellatrix.data.getting.started/src/main/java/ArtistsConverter.java create mode 100644 getting-started/bellatrix.data.getting.started/src/main/resources/application.properties create mode 100644 getting-started/bellatrix.data.getting.started/src/main/resources/testFrameworkSettings.test.json create mode 100644 getting-started/bellatrix.data.getting.started/src/test/java/BaseTest.java diff --git a/bellatrix.data/src/main/java/solutions/bellatrix/data/http/configuration/HttpSettings.java b/bellatrix.data/src/main/java/solutions/bellatrix/data/http/configuration/HttpSettings.java index fd338ebb..4e896770 100644 --- a/bellatrix.data/src/main/java/solutions/bellatrix/data/http/configuration/HttpSettings.java +++ b/bellatrix.data/src/main/java/solutions/bellatrix/data/http/configuration/HttpSettings.java @@ -6,7 +6,9 @@ import solutions.bellatrix.data.configuration.DataSettings; import solutions.bellatrix.data.http.authentication.Authentication; import solutions.bellatrix.data.http.authentication.AuthenticationMethod; +import solutions.bellatrix.data.http.infrastructure.HttpHeader; +import java.util.LinkedHashSet; import java.util.function.Consumer; @Data @@ -21,6 +23,8 @@ public class HttpSettings { private Authentication authentication; @SerializedName("urlEncoderEnabled") private boolean urlEncoderEnabled; + @SerializedName("headers") + private LinkedHashSet headers; public HttpSettings(HttpSettings httpSettings) { setBaseUrl(httpSettings.getBaseUrl()); @@ -28,6 +32,7 @@ public HttpSettings(HttpSettings httpSettings) { setContentType(httpSettings.getContentType()); setUrlEncoderEnabled(httpSettings.isUrlEncoderEnabled()); setAuthentication(httpSettings.getAuthentication()); + setHeaders(httpSettings.getHeaders()); } public static HttpSettings custom(Consumer httpSettings) { diff --git a/bellatrix.data/src/main/java/solutions/bellatrix/data/http/httpContext/HttpContext.java b/bellatrix.data/src/main/java/solutions/bellatrix/data/http/httpContext/HttpContext.java index 9ce76a6d..e885902b 100644 --- a/bellatrix.data/src/main/java/solutions/bellatrix/data/http/httpContext/HttpContext.java +++ b/bellatrix.data/src/main/java/solutions/bellatrix/data/http/httpContext/HttpContext.java @@ -9,6 +9,7 @@ import solutions.bellatrix.data.http.authentication.AuthenticationMethod; import solutions.bellatrix.data.http.configuration.HttpSettings; import solutions.bellatrix.data.http.infrastructure.HTTPMethod; +import solutions.bellatrix.data.http.infrastructure.HttpHeader; import solutions.bellatrix.data.http.infrastructure.QueryParameter; import java.util.*; @@ -18,16 +19,16 @@ public class HttpContext { private final HttpSettings httpSettings; private final LinkedList pathParameters; private final LinkedHashSet queryParameters; - @Setter - private RequestSpecBuilder specBuilder; - @Getter - private String requestBody; + private final LinkedHashSet httpHeaders; + @Setter private RequestSpecBuilder specBuilder; + @Getter private String requestBody; @Getter private HTTPMethod httpMethod; public HttpContext(HttpSettings settings) { this.httpSettings = settings; this.pathParameters = new LinkedList<>(); this.queryParameters = new LinkedHashSet<>(); + this.httpHeaders = httpSettings.getHeaders(); this.specBuilder = createInitialSpecBuilder(httpSettings); } @@ -36,6 +37,7 @@ public HttpContext(HttpContext httpContext) { this.queryParameters = httpContext.getQueryParameters(); this.pathParameters = httpContext.getPathParameters(); this.specBuilder = httpContext.getRequestBuilder(); + this.httpHeaders = httpContext.getHeaders(); } public HttpSettings getHttpSettings() { @@ -58,6 +60,10 @@ public LinkedList getPathParameters() { return new LinkedList<>(pathParameters); } + public LinkedHashSet getHeaders() { + return new LinkedHashSet<>(httpHeaders); + } + public LinkedHashSet getQueryParameters() { return new LinkedHashSet<>(queryParameters); } @@ -67,7 +73,7 @@ private RequestSpecBuilder getRequestBuilder() { } public RequestSpecification requestSpecification() { - if (requestBody != null) { + if (Objects.nonNull(requestBody)) { specBuilder.setBody(requestBody); } @@ -75,6 +81,8 @@ public RequestSpecification requestSpecification() { specBuilder.addQueryParams(getRequestQueryParameters()); } + specBuilder.addHeaders(getRequestHeaders()); + specBuilder.setBasePath(buildRequestPath()); return specBuilder.build(); @@ -98,10 +106,27 @@ public void addQueryParameters(Collection parameters) { parameters.forEach(this::addQueryParameter); } + public void addHeader(HttpHeader httpHeader) { + httpHeaders.add(httpHeader); + } + + public void addHeaders(Collection headers) { + headers.forEach(this::addHeader); + } + public void addQueryParameter(QueryParameter parameter) { queryParameters.add(parameter); } + private Map getRequestHeaders() { + LinkedHashMap requestHeaders = new LinkedHashMap<>(); + httpHeaders.forEach(x -> { + requestHeaders.put(x.getName(), x.getValue()); + }); + + return requestHeaders; + } + private Map getRequestQueryParameters() { //todo: this logic should be extracted because create tightly coupling with settings LinkedHashMap queryParams = new LinkedHashMap<>(); @@ -139,7 +164,6 @@ private Map getRequestQueryParameters() { return queryParams; } - public String buildRequestPath() { if (!pathParameters.isEmpty()) { String[] pathList = pathParameters.stream().filter(path -> !String.valueOf(path).isEmpty()).map(String::valueOf).toArray(String[]::new); @@ -151,9 +175,16 @@ public String buildRequestPath() { } private RequestSpecBuilder createInitialSpecBuilder(HttpSettings httpSettings) { + LinkedHashMap initialHeaders = new LinkedHashMap<>(); + httpHeaders.forEach(x -> { + initialHeaders.put(x.getName(), x.getValue()); + }); + return new RequestSpecBuilder() .setBaseUri(httpSettings.getBaseUrl()) - .setBasePath(httpSettings.getBasePath()).setContentType(httpSettings.getContentType()) + .addHeaders(initialHeaders) + .setBasePath(httpSettings.getBasePath()) + .setContentType(httpSettings.getContentType()) .setAuth(AuthSchemaFactory.getAuthenticationScheme(httpSettings.getAuthentication())) .setUrlEncodingEnabled(httpSettings.isUrlEncoderEnabled()) .log(LogDetail.ALL); diff --git a/bellatrix.data/src/main/java/solutions/bellatrix/data/http/infrastructure/Entity.java b/bellatrix.data/src/main/java/solutions/bellatrix/data/http/infrastructure/Entity.java index f16e45c1..2e991b6c 100644 --- a/bellatrix.data/src/main/java/solutions/bellatrix/data/http/infrastructure/Entity.java +++ b/bellatrix.data/src/main/java/solutions/bellatrix/data/http/infrastructure/Entity.java @@ -5,6 +5,7 @@ import solutions.bellatrix.data.contracts.Repository; @SuperBuilder +@SuppressWarnings("unchecked") public abstract class Entity { public TEntity get() { var repository = (Repository)RepositoryFactory.INSTANCE.getRepository(this.getClass()); diff --git a/bellatrix.data/src/main/java/solutions/bellatrix/data/http/infrastructure/HttpEntity.java b/bellatrix.data/src/main/java/solutions/bellatrix/data/http/infrastructure/HttpEntity.java index 3cbe16bd..f3b06964 100644 --- a/bellatrix.data/src/main/java/solutions/bellatrix/data/http/infrastructure/HttpEntity.java +++ b/bellatrix.data/src/main/java/solutions/bellatrix/data/http/infrastructure/HttpEntity.java @@ -1,6 +1,5 @@ package solutions.bellatrix.data.http.infrastructure; -import io.restassured.response.Response; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.experimental.SuperBuilder; @@ -12,7 +11,7 @@ @SuperBuilder @EqualsAndHashCode(callSuper = true) public abstract class HttpEntity extends Entity implements Queryable { - private transient Response response; + private transient HttpResponse response; public boolean hasInvalidIdentifier() { return Objects.isNull(this.getIdentifier()); diff --git a/bellatrix.data/src/main/java/solutions/bellatrix/data/http/infrastructure/HttpHeader.java b/bellatrix.data/src/main/java/solutions/bellatrix/data/http/infrastructure/HttpHeader.java new file mode 100644 index 00000000..0f5206cd --- /dev/null +++ b/bellatrix.data/src/main/java/solutions/bellatrix/data/http/infrastructure/HttpHeader.java @@ -0,0 +1,20 @@ +package solutions.bellatrix.data.http.infrastructure; + +import lombok.Getter; + +@Getter +public class HttpHeader { + private final String name; + private final String value; + + public HttpHeader(String name, String value) { + this.name = name; + this.value = value; + } + + @Override + public boolean equals(Object obj) { + HttpHeader ob = (HttpHeader)obj; + return this.value.equals(ob.getValue()); + } +} \ No newline at end of file diff --git a/bellatrix.data/src/main/java/solutions/bellatrix/data/http/infrastructure/HttpRepository.java b/bellatrix.data/src/main/java/solutions/bellatrix/data/http/infrastructure/HttpRepository.java index 2627c2c1..bf9d351d 100644 --- a/bellatrix.data/src/main/java/solutions/bellatrix/data/http/infrastructure/HttpRepository.java +++ b/bellatrix.data/src/main/java/solutions/bellatrix/data/http/infrastructure/HttpRepository.java @@ -16,6 +16,7 @@ import static solutions.bellatrix.data.http.infrastructure.HTTPMethod.*; +@SuppressWarnings("unchecked") public abstract class HttpRepository implements Repository { public static final EventListener SENDING_REQUEST = new EventListener<>(); public static final EventListener REQUEST_SENT = new EventListener<>(); @@ -161,11 +162,11 @@ private R deserializeInternal(HttpResponse response, DeserializationMode mod try { if (mode == DeserializationMode.LIST) { List entities = objectConverter.fromStringToList(response.getBody(), entityType); - entities.forEach(entity -> entity.setResponse(response.getResponse())); + entities.forEach(entity -> entity.setResponse(response)); return (R)entities; } else { THttpEntity entity = objectConverter.fromString(response.getBody(), entityType); - entity.setResponse(response.getResponse()); + entity.setResponse(response); return (R)entity; } } catch (Exception e) { diff --git a/bellatrix.data/src/main/java/solutions/bellatrix/data/http/infrastructure/HttpResponse.java b/bellatrix.data/src/main/java/solutions/bellatrix/data/http/infrastructure/HttpResponse.java index 4ebab26a..c1a69978 100644 --- a/bellatrix.data/src/main/java/solutions/bellatrix/data/http/infrastructure/HttpResponse.java +++ b/bellatrix.data/src/main/java/solutions/bellatrix/data/http/infrastructure/HttpResponse.java @@ -2,14 +2,17 @@ import io.restassured.response.Response; import lombok.Getter; +import solutions.bellatrix.data.http.infrastructure.internal.HttpStatusCode; @Getter public class HttpResponse { private final String body; - private final Response response; + private final Response nativeResponse; + private final HttpStatusCode statusCode; public HttpResponse(String body, Response response) { this.body = body; - this.response = response; + this.nativeResponse = response; + statusCode = HttpStatusCode.parse(response.getStatusCode()); } } \ No newline at end of file diff --git a/bellatrix.data/src/main/java/solutions/bellatrix/data/http/infrastructure/internal/HttpStatusCode.java b/bellatrix.data/src/main/java/solutions/bellatrix/data/http/infrastructure/internal/HttpStatusCode.java new file mode 100644 index 00000000..503939fa --- /dev/null +++ b/bellatrix.data/src/main/java/solutions/bellatrix/data/http/infrastructure/internal/HttpStatusCode.java @@ -0,0 +1,55 @@ +package solutions.bellatrix.data.http.infrastructure.internal; + +import lombok.Getter; + +@Getter +public enum HttpStatusCode { + // 1xx Informational responses + CONTINUE(100, "Continue"), + SWITCHING_PROTOCOLS(101, "Switching Protocols"), + PROCESSING(102, "Processing"), + EARLY_HINTS(103, "Early Hints"), + + // 2xx Success + OK(200, "OK"), + CREATED(201, "Created"), + ACCEPTED(202, "Accepted"), + NO_CONTENT(204, "No Content"), + // 3xx Redirection + MULTIPLE_CHOICES(300, "Multiple Choices"), + MOVED_PERMANENTLY(301, "Moved Permanently"), + FOUND(302, "Found"), + + // 4xx Client errors + BAD_REQUEST(400, "Bad Request"), + UNAUTHORIZED(401, "Unauthorized"), + FORBIDDEN(403, "Forbidden"), + NOT_FOUND(404, "Not Found"), + METHOD_NOT_ALLOWED(405, "Method Not Allowed"), + UNSUPPORTED_MEDIA_TYPE(415, "Unsupported Media Type"), + + // 5xx Server errors + INTERNAL_SERVER_ERROR(500, "Internal Server Error"), + NOT_IMPLEMENTED(501, "Not Implemented"), + BAD_GATEWAY(502, "Bad Gateway"), + SERVICE_UNAVAILABLE(503, "Service Unavailable"); + + private final int code; + private final String reasonPhrase; + + HttpStatusCode(int code, String reasonPhrase) { + this.code = code; + this.reasonPhrase = reasonPhrase; + } + + public static HttpStatusCode parse(int statusCode) { + for (var state : values()) { + int enumDisplayValue = state.getCode(); + if (enumDisplayValue == statusCode) { + return state; + } + } + + throw new IllegalArgumentException("Not found"); + } +} \ No newline at end of file diff --git a/framework-tests/bellatrix.data.tests/pom.xml b/framework-tests/bellatrix.data.tests/pom.xml new file mode 100644 index 00000000..966b5fc2 --- /dev/null +++ b/framework-tests/bellatrix.data.tests/pom.xml @@ -0,0 +1,20 @@ + + + 4.0.0 + + solutions.bellatrix + bellatrix + 1.0-SNAPSHOT + + + bellatrix.data.tests + + + 19 + 19 + UTF-8 + + + \ No newline at end of file diff --git a/getting-started/bellatrix.data.getting.started/pom.xml b/getting-started/bellatrix.data.getting.started/pom.xml new file mode 100644 index 00000000..f62c7516 --- /dev/null +++ b/getting-started/bellatrix.data.getting.started/pom.xml @@ -0,0 +1,28 @@ + + + 4.0.0 + + solutions.bellatrix + bellatrix + 1.0-SNAPSHOT + + + bellatrix.data.getting.started + + + 19 + 19 + UTF-8 + + + + + + solutions.bellatrix + bellatrix.data + 1.0-SNAPSHOT + + + \ No newline at end of file diff --git a/getting-started/bellatrix.data.getting.started/src/main/java/Artist.java b/getting-started/bellatrix.data.getting.started/src/main/java/Artist.java new file mode 100644 index 00000000..bdd9d90e --- /dev/null +++ b/getting-started/bellatrix.data.getting.started/src/main/java/Artist.java @@ -0,0 +1,20 @@ +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.SuperBuilder; +import solutions.bellatrix.data.http.infrastructure.HttpEntity; + +@Data +@SuperBuilder +@EqualsAndHashCode(callSuper = true) +public class Artist extends HttpEntity { + @SerializedName("ArtistId") + private String id; + @SerializedName("Name") + private String name; + + @Override + public String getIdentifier() { + return id; + } +} \ No newline at end of file diff --git a/getting-started/bellatrix.data.getting.started/src/main/java/ArtistRepository.java b/getting-started/bellatrix.data.getting.started/src/main/java/ArtistRepository.java new file mode 100644 index 00000000..36dd9e4c --- /dev/null +++ b/getting-started/bellatrix.data.getting.started/src/main/java/ArtistRepository.java @@ -0,0 +1,20 @@ +import com.google.gson.FieldNamingPolicy; +import solutions.bellatrix.core.configuration.ConfigurationService; +import solutions.bellatrix.data.configuration.DataSettings; +import solutions.bellatrix.data.http.httpContext.HttpContext; +import solutions.bellatrix.data.http.infrastructure.HttpRepository; +import solutions.bellatrix.data.http.infrastructure.JsonConverter; + +public class ArtistRepository extends HttpRepository { + public ArtistRepository() { + super(Artist.class, new JsonConverter(builder -> { + builder.setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE); + }), () -> { + var httpSettings = ConfigurationService.get(DataSettings.class).getHttpSettings(); + var httpContext = new HttpContext(httpSettings); + httpContext.addPathParameter("artists"); + return httpContext; + }); + } + +} \ No newline at end of file diff --git a/getting-started/bellatrix.data.getting.started/src/main/java/ArtistsConverter.java b/getting-started/bellatrix.data.getting.started/src/main/java/ArtistsConverter.java new file mode 100644 index 00000000..5d186f4e --- /dev/null +++ b/getting-started/bellatrix.data.getting.started/src/main/java/ArtistsConverter.java @@ -0,0 +1,10 @@ +import com.google.gson.FieldNamingPolicy; +import solutions.bellatrix.data.http.infrastructure.JsonConverter; + +public class ArtistsConverter extends JsonConverter { + public ArtistsConverter() { + super(builder -> { + builder.setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE); + }); + } +} \ No newline at end of file diff --git a/getting-started/bellatrix.data.getting.started/src/main/resources/application.properties b/getting-started/bellatrix.data.getting.started/src/main/resources/application.properties new file mode 100644 index 00000000..1f94aee3 --- /dev/null +++ b/getting-started/bellatrix.data.getting.started/src/main/resources/application.properties @@ -0,0 +1,15 @@ +# +# Copyright 2022 Automate The Planet Ltd. +# Author: Anton Angelov +# 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. +# + +environment=test +buildName={randomNumber} \ No newline at end of file diff --git a/getting-started/bellatrix.data.getting.started/src/main/resources/testFrameworkSettings.test.json b/getting-started/bellatrix.data.getting.started/src/main/resources/testFrameworkSettings.test.json new file mode 100644 index 00000000..e4b630cd --- /dev/null +++ b/getting-started/bellatrix.data.getting.started/src/main/resources/testFrameworkSettings.test.json @@ -0,0 +1,146 @@ +{ + "troubleshootingSettings": { + "debugInformationEnabled": "true" + }, + "dataSettings": { + "dataSourceType": "HTTP", + "httpSettings": { + "baseUrl": "http://localhost:3001/", + "basePath": "/api", + "urlEncoderEnabled": "false", + "contentType": "application/json", + "headers": [ + { + "name": "Accept", + "value": "application/json" + } + ], + "authentication": { + "method": "Basic", + "options": [ + { + "type": "Bearer", + "token": "{env_http_bearer_token}" + }, + { + "type": "Basic", + "username": "{env_http_username}", + "password": "{env_http_password}" + }, + { + "insertionOrder": "start", + "type": "QueryParameters", + "key": "{env_http_query_key}", + "token": "{env_http_query_token}" + } + ] + } + } + }, + "webSettings": { + "baseUrl": "https://ecommerce-playground.lambdatest.io", + "executionType": "regular", + "defaultBrowser": "chrome", + "defaultLifeCycle": "restart everytime time", + "artificialDelayBeforeAction": "0", + "automaticallyScrollToVisible": "false", + "waitUntilReadyOnElementFound": "false", + "waitForAngular": "false", + "shouldHighlightElements": "true", + "shouldCaptureHttpTraffic": "false", + "screenshotsOnFailEnabled": "false", + "screenshotsSaveLocation": "${user.home}/BELLATRIX/Screenshots", + "videosOnFailEnabled": "false", + "videosSaveLocation": "${user.home}/BELLATRIX/Videos", + "timeoutSettings": { + "elementWaitTimeout": "30", + "pageLoadTimeout": "30", + "scriptTimeout": "1", + "waitForAjaxTimeout": "30", + "sleepInterval": "1", + "waitUntilReadyTimeout": "30", + "waitForJavaScriptAnimationsTimeout": "30", + "waitForAngularTimeout": "30", + "waitForPartialUrl": "30", + "validationsTimeout": "30", + "elementToBeVisibleTimeout": "30", + "elementToExistTimeout": "30", + "elementToNotExistTimeout": "30", + "elementToBeClickableTimeout": "30", + "elementNotToBeVisibleTimeout": "30", + "elementToHaveContentTimeout": "15" + }, + "gridSettings": [ + { + "providerName": "saucelabs", + "url": "http://ondemand.saucelabs.com:80/wd/hub", + "arguments": [ + { + "screenResolution": "1280x800", + "recordVideo": "true", + "recordScreenshots": "true", + "username": "myUserName", + "accessKey": "myPass", + "name": "bellatrix_run" + } + ] + }, + { + "providerName": "browserstack", + "url": "http://hub-cloud.browserstack.com/wd/hub/", + "arguments": [ + { + "resolution": "1280x800", + "browserstack.video": "true", + "browserstack.networkLogs": "true", + "browserstack.debug": "true", + "browserstack.console": "errors", + "browserstack.user": "myUserName", + "browserstack.key": "myPass", + "build": "bellatrix_run" + } + ] + }, + { + "providerName": "crossbrowsertesting", + "url": "http://hub.crossbrowsertesting.com:80/wd/hub", + "arguments": [ + { + "screen_resolution": "1280x800", + "record_video": "true", + "record_network": "true", + "username": "myUserName", + "password": "myPass", + "name": "bellatrix_run" + } + ] + }, + { + "providerName": "selenoid", + "url": "http://127.0.0.1:4444/wd/hub", + "arguments": [ + { + "screenResolution": "1280x800", + "enableVNC": "true", + "enableVideo": "true", + "enableLog": "true", + "name": "bellatrix_run" + } + ] + }, + { + "providerName": "grid", + "url": "http://127.0.0.1:4444/wd/hub", + "arguments": [ + { + "name": "bellatrix_run" + } + ] + } + ] + }, + "urlSettings": { + "shopUrl": "http://demos.bellatrix.solutions/cart/", + "accountUrl": "http://demos.bellatrix.solutions/account/" + } +} \ No newline at end of file diff --git a/getting-started/bellatrix.data.getting.started/src/test/java/BaseTest.java b/getting-started/bellatrix.data.getting.started/src/test/java/BaseTest.java new file mode 100644 index 00000000..cce1cab5 --- /dev/null +++ b/getting-started/bellatrix.data.getting.started/src/test/java/BaseTest.java @@ -0,0 +1,13 @@ +import org.junit.jupiter.api.Test; +import solutions.bellatrix.data.configuration.RepositoryFactory; + +public class BaseTest { + + @Test + public void getAllResources_when_sendGetAlRequest() { + RepositoryFactory.INSTANCE.registerRepository(Artist.class, ArtistRepository.class); + var artistRepository = new ArtistRepository(); + + Artist artist = Artist.builder().name("James Clavell").build().create(); + } +} \ No newline at end of file diff --git a/pom.xml b/pom.xml index c7ef85be..c837c072 100644 --- a/pom.xml +++ b/pom.xml @@ -31,9 +31,11 @@ framework-tests/bellatrix.android.tests framework-tests/bellatrix.ios.tests framework-tests/bellatrix.playwright.tests + framework-tests/bellatrix.data.tests getting-started/bellatrix.web.getting.started getting-started/bellatrix.playwright.getting.started + getting-started/bellatrix.data.getting.started @@ -46,7 +48,7 @@ 2.22.2 3.0.0-M5 - 1.18.30 + 1.18.38 ${surefire.junit} From fd8ddc3325fefc5fedbc895ce8ce7bccbf633ca0 Mon Sep 17 00:00:00 2001 From: "veselinov.viktor" Date: Thu, 24 Jul 2025 14:32:50 +0300 Subject: [PATCH 02/12] added test md file --- .../bellatrix.data.getting.started/README.md | 1 + .../src/test/java/project_setup/ReadMe.md | 10 ++++++++++ 2 files changed, 11 insertions(+) create mode 100644 getting-started/bellatrix.data.getting.started/README.md create mode 100644 getting-started/bellatrix.data.getting.started/src/test/java/project_setup/ReadMe.md diff --git a/getting-started/bellatrix.data.getting.started/README.md b/getting-started/bellatrix.data.getting.started/README.md new file mode 100644 index 00000000..8a5e7ce6 --- /dev/null +++ b/getting-started/bellatrix.data.getting.started/README.md @@ -0,0 +1 @@ +# Bellatrix data service \ No newline at end of file diff --git a/getting-started/bellatrix.data.getting.started/src/test/java/project_setup/ReadMe.md b/getting-started/bellatrix.data.getting.started/src/test/java/project_setup/ReadMe.md new file mode 100644 index 00000000..af6928f2 --- /dev/null +++ b/getting-started/bellatrix.data.getting.started/src/test/java/project_setup/ReadMe.md @@ -0,0 +1,10 @@ +# Prerequisite + +To start using Data Module you need to add following dependency to your project +```xml + + solutions.bellatrix + bellatrix.data + 1.0-SNAPSHOT + +``` \ No newline at end of file From c499f6cb7a8dd24d44eab1c664edb9e6ce1aaef3 Mon Sep 17 00:00:00 2001 From: "veselinov.viktor" Date: Thu, 24 Jul 2025 16:34:00 +0300 Subject: [PATCH 03/12] adding read me file --- framework-tests/bellatrix.data.tests/pom.xml | 8 + .../java/infrastructure/artist/Artist.java | 23 ++ .../resources/testFrameworkSettings.dev.json | 146 ++++++++++ .../bellatrix.data.getting.started/README.md | 26 +- .../src/test/java/project_setup/ReadMe.md | 265 +++++++++++++++++- .../template/application.properties | 1 + .../template/testFrameworkSettings.test.json | 146 ++++++++++ 7 files changed, 606 insertions(+), 9 deletions(-) create mode 100644 framework-tests/bellatrix.data.tests/src/main/java/infrastructure/artist/Artist.java create mode 100644 framework-tests/bellatrix.data.tests/src/main/resources/testFrameworkSettings.dev.json create mode 100644 getting-started/bellatrix.data.getting.started/src/test/java/project_setup/template/application.properties create mode 100644 getting-started/bellatrix.data.getting.started/src/test/java/project_setup/template/testFrameworkSettings.test.json diff --git a/framework-tests/bellatrix.data.tests/pom.xml b/framework-tests/bellatrix.data.tests/pom.xml index 966b5fc2..fe8e93f8 100644 --- a/framework-tests/bellatrix.data.tests/pom.xml +++ b/framework-tests/bellatrix.data.tests/pom.xml @@ -17,4 +17,12 @@ UTF-8 + + + solutions.bellatrix + bellatrix.data + 1.0-SNAPSHOT + + + \ No newline at end of file diff --git a/framework-tests/bellatrix.data.tests/src/main/java/infrastructure/artist/Artist.java b/framework-tests/bellatrix.data.tests/src/main/java/infrastructure/artist/Artist.java new file mode 100644 index 00000000..d132776c --- /dev/null +++ b/framework-tests/bellatrix.data.tests/src/main/java/infrastructure/artist/Artist.java @@ -0,0 +1,23 @@ +package infrastructure.artist; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.SuperBuilder; +import solutions.bellatrix.data.http.infrastructure.HttpEntity; + +@Data +@SuperBuilder +@EqualsAndHashCode(callSuper = true) +public class Artist extends HttpEntity { + @SerializedName("ArtistId") + private String id; + + @SerializedName("Name") + private String name; + + @Override + public String getIdentifier() { + return id; + } +} \ No newline at end of file diff --git a/framework-tests/bellatrix.data.tests/src/main/resources/testFrameworkSettings.dev.json b/framework-tests/bellatrix.data.tests/src/main/resources/testFrameworkSettings.dev.json new file mode 100644 index 00000000..e4b630cd --- /dev/null +++ b/framework-tests/bellatrix.data.tests/src/main/resources/testFrameworkSettings.dev.json @@ -0,0 +1,146 @@ +{ + "troubleshootingSettings": { + "debugInformationEnabled": "true" + }, + "dataSettings": { + "dataSourceType": "HTTP", + "httpSettings": { + "baseUrl": "http://localhost:3001/", + "basePath": "/api", + "urlEncoderEnabled": "false", + "contentType": "application/json", + "headers": [ + { + "name": "Accept", + "value": "application/json" + } + ], + "authentication": { + "method": "Basic", + "options": [ + { + "type": "Bearer", + "token": "{env_http_bearer_token}" + }, + { + "type": "Basic", + "username": "{env_http_username}", + "password": "{env_http_password}" + }, + { + "insertionOrder": "start", + "type": "QueryParameters", + "key": "{env_http_query_key}", + "token": "{env_http_query_token}" + } + ] + } + } + }, + "webSettings": { + "baseUrl": "https://ecommerce-playground.lambdatest.io", + "executionType": "regular", + "defaultBrowser": "chrome", + "defaultLifeCycle": "restart everytime time", + "artificialDelayBeforeAction": "0", + "automaticallyScrollToVisible": "false", + "waitUntilReadyOnElementFound": "false", + "waitForAngular": "false", + "shouldHighlightElements": "true", + "shouldCaptureHttpTraffic": "false", + "screenshotsOnFailEnabled": "false", + "screenshotsSaveLocation": "${user.home}/BELLATRIX/Screenshots", + "videosOnFailEnabled": "false", + "videosSaveLocation": "${user.home}/BELLATRIX/Videos", + "timeoutSettings": { + "elementWaitTimeout": "30", + "pageLoadTimeout": "30", + "scriptTimeout": "1", + "waitForAjaxTimeout": "30", + "sleepInterval": "1", + "waitUntilReadyTimeout": "30", + "waitForJavaScriptAnimationsTimeout": "30", + "waitForAngularTimeout": "30", + "waitForPartialUrl": "30", + "validationsTimeout": "30", + "elementToBeVisibleTimeout": "30", + "elementToExistTimeout": "30", + "elementToNotExistTimeout": "30", + "elementToBeClickableTimeout": "30", + "elementNotToBeVisibleTimeout": "30", + "elementToHaveContentTimeout": "15" + }, + "gridSettings": [ + { + "providerName": "saucelabs", + "url": "http://ondemand.saucelabs.com:80/wd/hub", + "arguments": [ + { + "screenResolution": "1280x800", + "recordVideo": "true", + "recordScreenshots": "true", + "username": "myUserName", + "accessKey": "myPass", + "name": "bellatrix_run" + } + ] + }, + { + "providerName": "browserstack", + "url": "http://hub-cloud.browserstack.com/wd/hub/", + "arguments": [ + { + "resolution": "1280x800", + "browserstack.video": "true", + "browserstack.networkLogs": "true", + "browserstack.debug": "true", + "browserstack.console": "errors", + "browserstack.user": "myUserName", + "browserstack.key": "myPass", + "build": "bellatrix_run" + } + ] + }, + { + "providerName": "crossbrowsertesting", + "url": "http://hub.crossbrowsertesting.com:80/wd/hub", + "arguments": [ + { + "screen_resolution": "1280x800", + "record_video": "true", + "record_network": "true", + "username": "myUserName", + "password": "myPass", + "name": "bellatrix_run" + } + ] + }, + { + "providerName": "selenoid", + "url": "http://127.0.0.1:4444/wd/hub", + "arguments": [ + { + "screenResolution": "1280x800", + "enableVNC": "true", + "enableVideo": "true", + "enableLog": "true", + "name": "bellatrix_run" + } + ] + }, + { + "providerName": "grid", + "url": "http://127.0.0.1:4444/wd/hub", + "arguments": [ + { + "name": "bellatrix_run" + } + ] + } + ] + }, + "urlSettings": { + "shopUrl": "http://demos.bellatrix.solutions/cart/", + "accountUrl": "http://demos.bellatrix.solutions/account/" + } +} \ No newline at end of file diff --git a/getting-started/bellatrix.data.getting.started/README.md b/getting-started/bellatrix.data.getting.started/README.md index 8a5e7ce6..75086f90 100644 --- a/getting-started/bellatrix.data.getting.started/README.md +++ b/getting-started/bellatrix.data.getting.started/README.md @@ -1 +1,25 @@ -# Bellatrix data service \ No newline at end of file +# Getting Started with Bellatrix Data Module + +## Overview + +The Data Module simplifies data management in your tests by providing a clean, type-safe interface for API interactions. + +## Who Is This Guide For? + +Test automation engineers looking to streamline data management in their automation projects. + +## Why Use the Data Module? + +**Simplicity** - Eliminate boilerplate HTTP request code and focus on test logic +**Speed** - Get started instantly without learning complex HTTP client libraries +**Type Safety** - Work with strongly-typed models instead of raw JSON responses +**Flexibility** - Begin with simple scenarios and extend later as needed + +## Key Features + +- Abstract away HTTP request complexity +- Built-in serialization and response parsing +- Repository pattern for data access +- Minimal setup required + +Transform complex API interactions into intuitive operations that focus on business logic, not infrastructure code. \ No newline at end of file diff --git a/getting-started/bellatrix.data.getting.started/src/test/java/project_setup/ReadMe.md b/getting-started/bellatrix.data.getting.started/src/test/java/project_setup/ReadMe.md index af6928f2..970f243f 100644 --- a/getting-started/bellatrix.data.getting.started/src/test/java/project_setup/ReadMe.md +++ b/getting-started/bellatrix.data.getting.started/src/test/java/project_setup/ReadMe.md @@ -1,10 +1,259 @@ -# Prerequisite +# Getting Started with Bellatrix Data Module + +## Prerequisites + +### 1. Add Maven Dependency + +To start using the Data Module, add the following dependency to your project's `pom.xml`: -To start using Data Module you need to add following dependency to your project ```xml - - solutions.bellatrix - bellatrix.data - 1.0-SNAPSHOT - -``` \ No newline at end of file + + solutions.bellatrix + bellatrix.data + 1.0-SNAPSHOT + +``` + +### 2. Create Configuration File + +Create `testFrameworkSettings.{env}.json` inside the `src/main/resources` or `src/test/resources` folder. + +## Configuration Structure + +The configuration file contains several key sections: + +- **dataSettings**: HTTP data source configuration for API interactions +- **webSettings**: Web automation settings (if using web testing features) +- **urlSettings**: Custom URL definitions for your application + +### Example Configuration File + +```json +{ + "troubleshootingSettings": { + "debugInformationEnabled": "true" + }, + "dataSettings": { + "dataSourceType": "HTTP", + "httpSettings": { + "baseUrl": "http://localhost:3001/", + "basePath": "/api", + "urlEncoderEnabled": "false", + "contentType": "application/json", + "headers": [ + { + "name": "Accept", + "value": "application/json" + } + ], + "authentication": { + "method": "Bearer", + "options": [ + { + "type": "Bearer", + "token": "{env_http_bearer_token}" + }, + { + "type": "Basic", + "username": "{env_http_username}", + "password": "{env_http_password}" + }, + { + "insertionOrder": "start", + "type": "QueryParameters", + "key": "{env_http_query_key}", + "token": "{env_http_query_token}" + } + ] + } + } + }, + "webSettings": { + "baseUrl": "https://ecommerce-playground.lambdatest.io", + "executionType": "regular", + "defaultBrowser": "chrome", + "defaultLifeCycle": "restart everytime time", + "artificialDelayBeforeAction": "0", + "automaticallyScrollToVisible": "false", + "waitUntilReadyOnElementFound": "false", + "waitForAngular": "false", + "shouldHighlightElements": "true", + "shouldCaptureHttpTraffic": "false", + "screenshotsOnFailEnabled": "false", + "screenshotsSaveLocation": "${user.home}/BELLATRIX/Screenshots", + "videosOnFailEnabled": "false", + "videosSaveLocation": "${user.home}/BELLATRIX/Videos", + "timeoutSettings": { + "elementWaitTimeout": "30", + "pageLoadTimeout": "30", + "scriptTimeout": "1", + "waitForAjaxTimeout": "30", + "sleepInterval": "1", + "waitUntilReadyTimeout": "30", + "waitForJavaScriptAnimationsTimeout": "30", + "waitForAngularTimeout": "30", + "waitForPartialUrl": "30", + "validationsTimeout": "30", + "elementToBeVisibleTimeout": "30", + "elementToExistTimeout": "30", + "elementToNotExistTimeout": "30", + "elementToBeClickableTimeout": "30", + "elementNotToBeVisibleTimeout": "30", + "elementToHaveContentTimeout": "15" + }, + "gridSettings": [ + { + "providerName": "saucelabs", + "url": "http://ondemand.saucelabs.com:80/wd/hub", + "arguments": [ + { + "screenResolution": "1280x800", + "recordVideo": "true", + "recordScreenshots": "true", + "username": "myUserName", + "accessKey": "myPass", + "name": "bellatrix_run" + } + ] + }, + { + "providerName": "browserstack", + "url": "http://hub-cloud.browserstack.com/wd/hub/", + "arguments": [ + { + "resolution": "1280x800", + "browserstack.video": "true", + "browserstack.networkLogs": "true", + "browserstack.debug": "true", + "browserstack.console": "errors", + "browserstack.user": "myUserName", + "browserstack.key": "myPass", + "build": "bellatrix_run" + } + ] + }, + { + "providerName": "crossbrowsertesting", + "url": "http://hub.crossbrowsertesting.com:80/wd/hub", + "arguments": [ + { + "screen_resolution": "1280x800", + "record_video": "true", + "record_network": "true", + "username": "myUserName", + "password": "myPass", + "name": "bellatrix_run" + } + ] + }, + { + "providerName": "selenoid", + "url": "http://127.0.0.1:4444/wd/hub", + "arguments": [ + { + "screenResolution": "1280x800", + "enableVNC": "true", + "enableVideo": "true", + "enableLog": "true", + "name": "bellatrix_run" + } + ] + }, + { + "providerName": "grid", + "url": "http://127.0.0.1:4444/wd/hub", + "arguments": [ + { + "name": "bellatrix_run" + } + ] + } + ] + }, + "urlSettings": { + "shopUrl": "http://demos.bellatrix.solutions/cart/", + "accountUrl": "http://demos.bellatrix.solutions/account/" + } +} +``` + +## Key Configuration Sections + +### Data Settings (Required for HTTP APIs) + +- **dataSourceType**: Set to "HTTP" for REST API interactions +- **baseUrl**: Your API's root URL +- **basePath**: Common path prefix for all endpoints +- **authentication**: Support for Bearer tokens, Basic auth, or query parameters +- **headers**: Default headers sent with every request + +### Environment Variables + +Use `{env_variable_name}` syntax for sensitive data: + +- `{env_http_bearer_token}` - Your API bearer token +- `{env_http_username}` - Basic auth username +- `{env_http_password}` - Basic auth password + +### Web Settings (Optional) + +Configure web automation if you're using Bellatrix for both API and UI testing. + +## Environment-Specific Configuration + +You can create multiple configuration files for different environments: + +- `testFrameworkSettings.dev.json` - Development environment +- `testFrameworkSettings.test.json` - Test environment +- `testFrameworkSettings.staging.json` - Staging environment +- `testFrameworkSettings.prod.json` - Production environment + +## Environment Configuration + +### 3. Create Application Properties File + +Add an `application.properties` file inside the `/src/main/resources` or `/src/test/resources` folder to specify which configuration environment to use. + +### Environment Mapping + +The `environment` property determines which configuration file the framework will load: + +| Environment Value | Configuration File Loaded | Use Case | +|------------------|---------------------------|----------| +| `dev` | `testFrameworkSettings.dev.json` | Development environment | +| `test` | `testFrameworkSettings.test.json` | Test environment | +| `staging` | `testFrameworkSettings.staging.json` | Staging environment | +| `prod` | `testFrameworkSettings.prod.json` | Production environment | + +### Example Application Properties + +```properties +# Set environment for configuration file selection +environment=test +``` + +> **Note**: Make sure your `testFrameworkSettings.{environment}.json` file exists and matches the environment value you specify. + +## Using Template Configuration + +For faster setup, you can use the provided template configuration file: + +### Setup Steps + +1. **Locate the template**: Find the example configuration file in the `template` folder of the project +2. **Copy the template**: Copy `testFrameworkSettings.template.json` +3. **Place in resources**: Paste the file into your `src/main/resources` or `src/test/resources` folder +4. **Rename appropriately**: Rename to match your environment (e.g., `testFrameworkSettings.dev.json`) +5. **Customize settings**: Update the configuration values to match your environment + +> **Tip**: This template includes all necessary sections with example values, making it easier to get started quickly. + +## Next Steps + +After completing the configuration: + +1. Create your data entities (models) +2. Set up repositories for API interactions +3. Write your first tests + +*Detailed implementation examples will be provided in the following sections.* \ No newline at end of file diff --git a/getting-started/bellatrix.data.getting.started/src/test/java/project_setup/template/application.properties b/getting-started/bellatrix.data.getting.started/src/test/java/project_setup/template/application.properties new file mode 100644 index 00000000..14f1a606 --- /dev/null +++ b/getting-started/bellatrix.data.getting.started/src/test/java/project_setup/template/application.properties @@ -0,0 +1 @@ +environment=test \ No newline at end of file diff --git a/getting-started/bellatrix.data.getting.started/src/test/java/project_setup/template/testFrameworkSettings.test.json b/getting-started/bellatrix.data.getting.started/src/test/java/project_setup/template/testFrameworkSettings.test.json new file mode 100644 index 00000000..e4b630cd --- /dev/null +++ b/getting-started/bellatrix.data.getting.started/src/test/java/project_setup/template/testFrameworkSettings.test.json @@ -0,0 +1,146 @@ +{ + "troubleshootingSettings": { + "debugInformationEnabled": "true" + }, + "dataSettings": { + "dataSourceType": "HTTP", + "httpSettings": { + "baseUrl": "http://localhost:3001/", + "basePath": "/api", + "urlEncoderEnabled": "false", + "contentType": "application/json", + "headers": [ + { + "name": "Accept", + "value": "application/json" + } + ], + "authentication": { + "method": "Basic", + "options": [ + { + "type": "Bearer", + "token": "{env_http_bearer_token}" + }, + { + "type": "Basic", + "username": "{env_http_username}", + "password": "{env_http_password}" + }, + { + "insertionOrder": "start", + "type": "QueryParameters", + "key": "{env_http_query_key}", + "token": "{env_http_query_token}" + } + ] + } + } + }, + "webSettings": { + "baseUrl": "https://ecommerce-playground.lambdatest.io", + "executionType": "regular", + "defaultBrowser": "chrome", + "defaultLifeCycle": "restart everytime time", + "artificialDelayBeforeAction": "0", + "automaticallyScrollToVisible": "false", + "waitUntilReadyOnElementFound": "false", + "waitForAngular": "false", + "shouldHighlightElements": "true", + "shouldCaptureHttpTraffic": "false", + "screenshotsOnFailEnabled": "false", + "screenshotsSaveLocation": "${user.home}/BELLATRIX/Screenshots", + "videosOnFailEnabled": "false", + "videosSaveLocation": "${user.home}/BELLATRIX/Videos", + "timeoutSettings": { + "elementWaitTimeout": "30", + "pageLoadTimeout": "30", + "scriptTimeout": "1", + "waitForAjaxTimeout": "30", + "sleepInterval": "1", + "waitUntilReadyTimeout": "30", + "waitForJavaScriptAnimationsTimeout": "30", + "waitForAngularTimeout": "30", + "waitForPartialUrl": "30", + "validationsTimeout": "30", + "elementToBeVisibleTimeout": "30", + "elementToExistTimeout": "30", + "elementToNotExistTimeout": "30", + "elementToBeClickableTimeout": "30", + "elementNotToBeVisibleTimeout": "30", + "elementToHaveContentTimeout": "15" + }, + "gridSettings": [ + { + "providerName": "saucelabs", + "url": "http://ondemand.saucelabs.com:80/wd/hub", + "arguments": [ + { + "screenResolution": "1280x800", + "recordVideo": "true", + "recordScreenshots": "true", + "username": "myUserName", + "accessKey": "myPass", + "name": "bellatrix_run" + } + ] + }, + { + "providerName": "browserstack", + "url": "http://hub-cloud.browserstack.com/wd/hub/", + "arguments": [ + { + "resolution": "1280x800", + "browserstack.video": "true", + "browserstack.networkLogs": "true", + "browserstack.debug": "true", + "browserstack.console": "errors", + "browserstack.user": "myUserName", + "browserstack.key": "myPass", + "build": "bellatrix_run" + } + ] + }, + { + "providerName": "crossbrowsertesting", + "url": "http://hub.crossbrowsertesting.com:80/wd/hub", + "arguments": [ + { + "screen_resolution": "1280x800", + "record_video": "true", + "record_network": "true", + "username": "myUserName", + "password": "myPass", + "name": "bellatrix_run" + } + ] + }, + { + "providerName": "selenoid", + "url": "http://127.0.0.1:4444/wd/hub", + "arguments": [ + { + "screenResolution": "1280x800", + "enableVNC": "true", + "enableVideo": "true", + "enableLog": "true", + "name": "bellatrix_run" + } + ] + }, + { + "providerName": "grid", + "url": "http://127.0.0.1:4444/wd/hub", + "arguments": [ + { + "name": "bellatrix_run" + } + ] + } + ] + }, + "urlSettings": { + "shopUrl": "http://demos.bellatrix.solutions/cart/", + "accountUrl": "http://demos.bellatrix.solutions/account/" + } +} \ No newline at end of file From bf2f9ec14fe06365e01bcda08714fc8e13640ffc Mon Sep 17 00:00:00 2001 From: veselinov-viktor <96745619+veselinovviktor@users.noreply.github.com> Date: Thu, 24 Jul 2025 17:29:26 +0300 Subject: [PATCH 04/12] Update README.md --- .../bellatrix.data.getting.started/README.md | 67 +++++++++++++++---- 1 file changed, 55 insertions(+), 12 deletions(-) diff --git a/getting-started/bellatrix.data.getting.started/README.md b/getting-started/bellatrix.data.getting.started/README.md index 75086f90..7cdc9e03 100644 --- a/getting-started/bellatrix.data.getting.started/README.md +++ b/getting-started/bellatrix.data.getting.started/README.md @@ -1,8 +1,8 @@ -# Getting Started with Bellatrix Data Module +# Bellatrix Data Module ## Overview -The Data Module simplifies data management in your tests by providing a clean, type-safe interface for API interactions. +The **Bellatrix Data Module** simplifies data management in your tests by providing a clean, type-safe interface for API interactions. ## Who Is This Guide For? @@ -10,16 +10,59 @@ Test automation engineers looking to streamline data management in their automat ## Why Use the Data Module? -**Simplicity** - Eliminate boilerplate HTTP request code and focus on test logic -**Speed** - Get started instantly without learning complex HTTP client libraries -**Type Safety** - Work with strongly-typed models instead of raw JSON responses -**Flexibility** - Begin with simple scenarios and extend later as needed +### Simplicity -## Key Features +> Eliminate boilerplate HTTP request code and focus on your test logic. -- Abstract away HTTP request complexity -- Built-in serialization and response parsing -- Repository pattern for data access -- Minimal setup required +**Traditional Approach:** +```java +HttpClient client = HttpClient.newHttpClient(); +HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create("http://localhost:3001/api/artists")) + .header("Content-Type", "application/json") + .POST(HttpRequest.BodyPublishers.ofString(gson.toJson(artist))) + .build(); -Transform complex API interactions into intuitive operations that focus on business logic, not infrastructure code. \ No newline at end of file +HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); +Artist createdArtist = gson.fromJson(response.body(), Artist.class); +``` + +**Bellatrix Data Module Approach:** + +```java +RepositoryFactory.INSTANCE.registerRepository(Artist.class, ArtistRepository.class); +Artist artist = Artist.builder().name("Artist Name").build().create(); +``` + +### Speed +> [!NOTE]\ +> Start writing tests immediately—no need to learn complex HTTP client libraries. + +**Traditional Approach:** +Requires creating an HTTP client, building a request, and then executing it with the client: + +``` java +HttpClient client = HttpClient.newHttpClient(); +HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create("http://localhost:3001/api/artists")) + .header("Content-Type", "application/json") + .POST(HttpRequest.BodyPublishers.ofString(gson.toJson(artist))) + .build(); + +HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); +``` + +**With Bellatrix:Traditional Approach:** +Just define your HTTP entity and create a repository instance - no-boilerplate required. + + +HttpEntity +Represents the data objects your API works with. Each entity corresponds to a resource (such as Artist, Album, etc.) and defines the structure and fields of that resource in your application. + +HttpRepository +Acts as the client for performing CRUD (Create, Read, Update, Delete) operations on your entities. It manages sending requests to the API and handling responses, providing a simple interface for interacting with your data source. + +```java + ArtistRepository artistRepository = new ArtistRepository(); + List artists = artistRepository.getAll(); +``` From 30556b019a1e9ced378cbbe5c22de98ba9bbd022 Mon Sep 17 00:00:00 2001 From: "veselinov.viktor" Date: Tue, 29 Jul 2025 16:21:02 +0300 Subject: [PATCH 05/12] adding new config --- .../bellatrix.data.getting.started/README.md | 87 ++++++++++- .../ReadMe.md | 116 +------------- .../template/application.properties | 0 .../template/testFrameworkSettings.test.json | 37 +++++ .../src/test/java/02_create_entity/ReadMe.md | 90 +++++++++++ .../src/test/java/02_http_context/ReadMe.md | 74 +++++++++ .../src/test/java/02_http_settings/ReadMe.md | 100 ++++++++++++ .../test/java/03_create_repository/ReadMe.md | 87 +++++++++++ .../template/testFrameworkSettings.test.json | 146 ------------------ 9 files changed, 473 insertions(+), 264 deletions(-) rename getting-started/bellatrix.data.getting.started/src/test/java/{project_setup => 01_project_setup}/ReadMe.md (55%) rename getting-started/bellatrix.data.getting.started/src/test/java/{project_setup => 01_project_setup}/template/application.properties (100%) create mode 100644 getting-started/bellatrix.data.getting.started/src/test/java/01_project_setup/template/testFrameworkSettings.test.json create mode 100644 getting-started/bellatrix.data.getting.started/src/test/java/02_create_entity/ReadMe.md create mode 100644 getting-started/bellatrix.data.getting.started/src/test/java/02_http_context/ReadMe.md create mode 100644 getting-started/bellatrix.data.getting.started/src/test/java/02_http_settings/ReadMe.md create mode 100644 getting-started/bellatrix.data.getting.started/src/test/java/03_create_repository/ReadMe.md delete mode 100644 getting-started/bellatrix.data.getting.started/src/test/java/project_setup/template/testFrameworkSettings.test.json diff --git a/getting-started/bellatrix.data.getting.started/README.md b/getting-started/bellatrix.data.getting.started/README.md index 75086f90..d65a88e0 100644 --- a/getting-started/bellatrix.data.getting.started/README.md +++ b/getting-started/bellatrix.data.getting.started/README.md @@ -11,9 +11,90 @@ Test automation engineers looking to streamline data management in their automat ## Why Use the Data Module? **Simplicity** - Eliminate boilerplate HTTP request code and focus on test logic -**Speed** - Get started instantly without learning complex HTTP client libraries -**Type Safety** - Work with strongly-typed models instead of raw JSON responses -**Flexibility** - Begin with simple scenarios and extend later as needed + +**Traditional Approach:** + +```java +HttpClient client = HttpClient.newHttpClient(); +HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create("http://localhost:3001/api/artists")) + .header("Content-Type", "application/json") + .POST(HttpRequest.BodyPublishers.ofString(gson.toJson(artist))) + .build(); + +HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); +Artist createdArtist = gson.fromJson(response.body(), Artist.class); +``` + +**Bellatrix Data Module Approach:** + +```java +RepositoryFactory.INSTANCE.registerRepository(Artist.class, ArtistRepository.class); +Artist artist = Artist.builder().name("Artist Name").build().create(); +``` + +**Speed** +Built-in infrastructure enables you to start writing tests immediately—no need to learn complex HTTP client libraries. + +Traditional Approach: +Requires creating an HTTP client, building a request, and then executing it with the client: +```java +HttpClient client = HttpClient.newHttpClient(); +HttpRequest request = HttpRequest.newBuilder() +.uri(URI.create("http://localhost:3001/api/artists")) +.header("Content-Type", "application/json") +.POST(HttpRequest.BodyPublishers.ofString(gson.toJson(artist))) +.build(); + +HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); +``` +With Bellatrix: +Just define your HTTP entity and create a repository instance—no boilerplate required. + +HttpEntity +Represents the data objects your API works with. Each entity corresponds to a resource (such as Artist, Album, etc.) and defines the structure and fields of that resource in your application. + +HttpRepository +Acts as the client for performing CRUD (Create, Read, Update, Delete) operations on your entities. It manages sending requests to the API and handling responses, providing a simple interface for interacting with your data source. + +```java + ArtistRepository artistRepository = new ArtistRepository(); + List artists = artistRepository.getAll(); +``` + +No more manual client setup or request building—just focus on your test logic. + + + +**Type Safety** +Work with strongly-typed models, with all conversions handled automatically. No more casting in tests or dealing with raw JSON responses. + +Traditional Approach: +Typically requires boilerplate code to convert response data into objects, often using a fixed library that may not be easily replaced: + +```java +HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); +Artist createdArtist = gson.fromJson(response.body(), Artist.class); +``` +With Bellatrix: + +Bellatrix provides built-in logic for converting between strings and objects, so you don’t need to depend on a specific library or write casting code. Type conversions happen behind the scenes, letting you focus on your test logic: + +```java + List artists = artistRepository.getAll(); +``` +Once the request is sent, the response is automatically handled and the data is returned in the correct type—no explicit configuration needed in your tests. + +**Flexibility** + Begin with simple scenarios and extend later as needed. +The Data Module’s greatest strength is its extensibility. You can easily customize and enhance your client (HttpRepository) and requests specific properties, or custom converters—whenever your project requirements evolve. + +You can extend: + +HttpRepository: Add custom methods or override existing CRUD operations to fit your business logic. +HttpContext: Dynamically modify request context, such as adding path parameters, headers, or query parameters. +Object Mapper (e.g., JsonConverter): Plug in your own serialization/deserialization logic for custom data formats. + ## Key Features diff --git a/getting-started/bellatrix.data.getting.started/src/test/java/project_setup/ReadMe.md b/getting-started/bellatrix.data.getting.started/src/test/java/01_project_setup/ReadMe.md similarity index 55% rename from getting-started/bellatrix.data.getting.started/src/test/java/project_setup/ReadMe.md rename to getting-started/bellatrix.data.getting.started/src/test/java/01_project_setup/ReadMe.md index 970f243f..9bcb62fb 100644 --- a/getting-started/bellatrix.data.getting.started/src/test/java/project_setup/ReadMe.md +++ b/getting-started/bellatrix.data.getting.started/src/test/java/01_project_setup/ReadMe.md @@ -23,16 +23,12 @@ Create `testFrameworkSettings.{env}.json` inside the `src/main/resources` or `sr The configuration file contains several key sections: - **dataSettings**: HTTP data source configuration for API interactions -- **webSettings**: Web automation settings (if using web testing features) -- **urlSettings**: Custom URL definitions for your application +- **httpSettings**: Nested configuration for HTTP-specific settings ### Example Configuration File ```json { - "troubleshootingSettings": { - "debugInformationEnabled": "true" - }, "dataSettings": { "dataSourceType": "HTTP", "httpSettings": { @@ -67,112 +63,6 @@ The configuration file contains several key sections: ] } } - }, - "webSettings": { - "baseUrl": "https://ecommerce-playground.lambdatest.io", - "executionType": "regular", - "defaultBrowser": "chrome", - "defaultLifeCycle": "restart everytime time", - "artificialDelayBeforeAction": "0", - "automaticallyScrollToVisible": "false", - "waitUntilReadyOnElementFound": "false", - "waitForAngular": "false", - "shouldHighlightElements": "true", - "shouldCaptureHttpTraffic": "false", - "screenshotsOnFailEnabled": "false", - "screenshotsSaveLocation": "${user.home}/BELLATRIX/Screenshots", - "videosOnFailEnabled": "false", - "videosSaveLocation": "${user.home}/BELLATRIX/Videos", - "timeoutSettings": { - "elementWaitTimeout": "30", - "pageLoadTimeout": "30", - "scriptTimeout": "1", - "waitForAjaxTimeout": "30", - "sleepInterval": "1", - "waitUntilReadyTimeout": "30", - "waitForJavaScriptAnimationsTimeout": "30", - "waitForAngularTimeout": "30", - "waitForPartialUrl": "30", - "validationsTimeout": "30", - "elementToBeVisibleTimeout": "30", - "elementToExistTimeout": "30", - "elementToNotExistTimeout": "30", - "elementToBeClickableTimeout": "30", - "elementNotToBeVisibleTimeout": "30", - "elementToHaveContentTimeout": "15" - }, - "gridSettings": [ - { - "providerName": "saucelabs", - "url": "http://ondemand.saucelabs.com:80/wd/hub", - "arguments": [ - { - "screenResolution": "1280x800", - "recordVideo": "true", - "recordScreenshots": "true", - "username": "myUserName", - "accessKey": "myPass", - "name": "bellatrix_run" - } - ] - }, - { - "providerName": "browserstack", - "url": "http://hub-cloud.browserstack.com/wd/hub/", - "arguments": [ - { - "resolution": "1280x800", - "browserstack.video": "true", - "browserstack.networkLogs": "true", - "browserstack.debug": "true", - "browserstack.console": "errors", - "browserstack.user": "myUserName", - "browserstack.key": "myPass", - "build": "bellatrix_run" - } - ] - }, - { - "providerName": "crossbrowsertesting", - "url": "http://hub.crossbrowsertesting.com:80/wd/hub", - "arguments": [ - { - "screen_resolution": "1280x800", - "record_video": "true", - "record_network": "true", - "username": "myUserName", - "password": "myPass", - "name": "bellatrix_run" - } - ] - }, - { - "providerName": "selenoid", - "url": "http://127.0.0.1:4444/wd/hub", - "arguments": [ - { - "screenResolution": "1280x800", - "enableVNC": "true", - "enableVideo": "true", - "enableLog": "true", - "name": "bellatrix_run" - } - ] - }, - { - "providerName": "grid", - "url": "http://127.0.0.1:4444/wd/hub", - "arguments": [ - { - "name": "bellatrix_run" - } - ] - } - ] - }, - "urlSettings": { - "shopUrl": "http://demos.bellatrix.solutions/cart/", - "accountUrl": "http://demos.bellatrix.solutions/account/" } } ``` @@ -195,10 +85,6 @@ Use `{env_variable_name}` syntax for sensitive data: - `{env_http_username}` - Basic auth username - `{env_http_password}` - Basic auth password -### Web Settings (Optional) - -Configure web automation if you're using Bellatrix for both API and UI testing. - ## Environment-Specific Configuration You can create multiple configuration files for different environments: diff --git a/getting-started/bellatrix.data.getting.started/src/test/java/project_setup/template/application.properties b/getting-started/bellatrix.data.getting.started/src/test/java/01_project_setup/template/application.properties similarity index 100% rename from getting-started/bellatrix.data.getting.started/src/test/java/project_setup/template/application.properties rename to getting-started/bellatrix.data.getting.started/src/test/java/01_project_setup/template/application.properties diff --git a/getting-started/bellatrix.data.getting.started/src/test/java/01_project_setup/template/testFrameworkSettings.test.json b/getting-started/bellatrix.data.getting.started/src/test/java/01_project_setup/template/testFrameworkSettings.test.json new file mode 100644 index 00000000..9c31302e --- /dev/null +++ b/getting-started/bellatrix.data.getting.started/src/test/java/01_project_setup/template/testFrameworkSettings.test.json @@ -0,0 +1,37 @@ +{ + "dataSettings": { + "dataSourceType": "HTTP", + "httpSettings": { + "baseUrl": "http://localhost:3001/", + "basePath": "/api", + "urlEncoderEnabled": "false", + "contentType": "application/json", + "headers": [ + { + "name": "Accept", + "value": "application/json" + } + ], + "authentication": { + "method": "Bearer", + "options": [ + { + "type": "Bearer", + "token": "{env_http_bearer_token}" + }, + { + "type": "Basic", + "username": "{env_http_username}", + "password": "{env_http_password}" + }, + { + "insertionOrder": "start", + "type": "QueryParameters", + "key": "{env_http_query_key}", + "token": "{env_http_query_token}" + } + ] + } + } + } +} \ No newline at end of file diff --git a/getting-started/bellatrix.data.getting.started/src/test/java/02_create_entity/ReadMe.md b/getting-started/bellatrix.data.getting.started/src/test/java/02_create_entity/ReadMe.md new file mode 100644 index 00000000..e8f285f7 --- /dev/null +++ b/getting-started/bellatrix.data.getting.started/src/test/java/02_create_entity/ReadMe.md @@ -0,0 +1,90 @@ +# HttpEntity + +`HttpEntity` is the base class for all data entity classes in your application. + +**Key Features:** + +- Validates whether the entity identifier is properly set, ensuring entities are ready for operations like getById, update, or delete +- Maintains a reference to the HTTP Response object, enabling testing of request-specific properties such as status code, headers, and response body + +All your data entities should extend this class to inherit these capabilities. + +**Example Usage:** + +Let's create an entity class that represents an artist in our music shop application: + +```java +@Data +@SuperBuilder +@EqualsAndHashCode(callSuper = true) +public class Artist extends HttpEntity { + @SerializedName("ArtistId") + private String id; + + @SerializedName("Name") + private String name; + + @Override + public String getIdentifier() { + return id; + } +} +``` + +**Key Points:** + +- The class extends `HttpEntity` where `String` is the identifier type +- `@SerializedName` annotations map JSON fields to Java properties for proper serialization +- The `getIdentifier()` method returns the unique identifier used for CRUD operations + + +# Entity Class + +`HttpEntity` extends the `Entity` class, which provides the core interface for all data entities regardless of their data source. + +**Key Features:** + +- **Direct Entity Operations**: Perform database/API operations directly on entity instances without requiring separate repository calls +- **Consistent Behavior**: Maintain uniform operation patterns across all entity types in your application +- **Flexible Identifier Types**: Support different identifier types (UUID, String, Integer, etc.) based on your data model requirements +- **Reduced Boilerplate**: Minimize code duplication by embedding CRUD operations directly within entity classes + +This architecture streamlines data management by reducing the lines of code needed to create and manage entities. You can focus on defining your data model while the framework handles the underlying HTTP interactions and operations. + +## Usage Patterns + +There are three main approaches to working with entities and repositories: + +### Option 1: Explicit Repository Usage (Verbose but Clear) + +Create a repository instance and use it explicitly for operations: + +```java +ArtistRepository artistRepository = new ArtistRepository(); +Artist artist = Artist.builder().name("Arthur Conan Doyle").build(); +Artist createdArtist = artistRepository.create(artist); +``` + +**Benefits:** Clear separation of concerns, explicit repository management + +#### Option 2: Inline Repository Usage (Concise) + +Combine repository creation and operation in a single statement: + +```java +Artist artist = new ArtistRepository().create(Artist.builder().name("J.K.Rowling").build()); +``` + +**Benefits:** Fewer lines of code, good for simple operations + +#### Option 3: Bellatrix Entity-Centric Approach + +Register repositories once and perform operations directly on entities: + +```java +RepositoryFactory.INSTANCE.registerRepository(Artist.class, ArtistRepository.class); + +Artist artist = Artist.builder().name("James Clavell").build().create(); +``` + +**Benefits:** Most concise, entity-focused design, automatic repository management \ No newline at end of file diff --git a/getting-started/bellatrix.data.getting.started/src/test/java/02_http_context/ReadMe.md b/getting-started/bellatrix.data.getting.started/src/test/java/02_http_context/ReadMe.md new file mode 100644 index 00000000..6a1b60d8 --- /dev/null +++ b/getting-started/bellatrix.data.getting.started/src/test/java/02_http_context/ReadMe.md @@ -0,0 +1,74 @@ +# Configuring HTTP Context + +## Overview + +This guide explains how to use HttpContext for dynamic configuration, and customize requests for your specific API endpoints. + + +## HttpContext Class + +The `HttpContext` class acts as a bridge between your base configuration and actual HTTP requests. It encapsulates HTTP operation settings and provides dynamic request configuration capabilities. + +### Key Capabilities + +- **URL Construction**: Combines base settings with dynamic path parameters +- **Request Customization**: Allows per-repository endpoint customization +- **Parameter Management**: Supports both path parameters and query parameters +- **Configuration Extension**: Builds upon base settings from `testFrameworksSettings.json` + +## Dynamic Configuration and URL Construction + +The `HttpContext` takes your base configuration from `testFrameworksSettings.json` and allows repository-specific customization. + +### URL Building Process + +The framework constructs URLs by combining multiple components: + +| Step | Component | Source | Example | +|------|-----------|--------|---------| +| 1 | Base URL | Configuration file | `http://localhost:3001` | +| 2 | Base Path | Configuration file | `/api` | +| 3 | Path Parameters | Dynamic via `addPathParameter()` | `/artists` | +| 4 | **Final URL** | **Combined result** | **`http://localhost:3001/api/artists`** | + +### Repository Implementation Example + +```java +public class ArtistRepository extends HttpRepository { + public ArtistRepository() { + super(Artist.class, new JsonConverter(), () -> { + // Get base HTTP settings from configuration + var httpSettings = ConfigurationService.get(DataSettings.class).getHttpSettings(); + + // Create HttpContext with base settings + var httpContext = new HttpContext(httpSettings); + + // Add repository-specific path parameter + httpContext.addPathParameter("/artists"); + + // The resulting URL will be: {baseUrl}{basePath}/artists + // Example: http://localhost:3001/api/artists + return httpContext; + }); + } +} +``` + +### Additional HttpContext Methods + +```java +// Add multiple path parameters +httpContext.addPathParameter("/artists"); +httpContext.addPathParameter("/123"); // Results in: /api/artists/123 + +// Add query parameters +httpContext.addQueryParameter("limit", "10"); +httpContext.addQueryParameter("offset", "0"); // Results in: /api/artists?limit=10&offset=0 +``` + +## Best Practices + +- **Environment Variables**: Always use environment variables for sensitive authentication data +- **Path Structure**: Keep path parameters organized and RESTful (`/resource/{id}`) +- **Error Handling**: Configure appropriate timeout and retry settings for production use +- **Security**: Use HTTPS URLs in production environments \ No newline at end of file diff --git a/getting-started/bellatrix.data.getting.started/src/test/java/02_http_settings/ReadMe.md b/getting-started/bellatrix.data.getting.started/src/test/java/02_http_settings/ReadMe.md new file mode 100644 index 00000000..4e0ca63d --- /dev/null +++ b/getting-started/bellatrix.data.getting.started/src/test/java/02_http_settings/ReadMe.md @@ -0,0 +1,100 @@ +# HTTP Settings + +## Overview + +This guide explains how to configure HTTP data sources in the Bellatrix framework. The configuration is typically placed in your `testFrameworksSettings.json` file, located in `src/main/resources`. + +## HttpSettings + +The `HttpSettings` class configures HTTP data source settings for your application. Add this configuration to your `testFrameworksSettings.json` file to define base URLs, headers, authentication methods, and other HTTP-specific settings that apply to all repository requests. + +### Configuration Example + +```json +{ + "dataSettings": { + "dataSourceType": "HTTP", + "httpSettings": { + "baseUrl": "http://localhost:3001/", + "basePath": "/api", + "urlEncoderEnabled": "false", + "contentType": "application/json", + "headers": [ + { + "name": "Accept", + "value": "application/json" + } + ], + "authentication": { + "method": "Bearer", + "options": [ + { + "type": "Bearer", + "token": "{env_http_bearer_token}" + }, + { + "type": "Basic", + "username": "{env_http_username}", + "password": "{env_http_password}" + }, + { + "insertionOrder": "start", + "type": "QueryParameters", + "key": "{env_http_query_key}", + "token": "{env_http_query_token}" + } + ] + } + } + } +} +``` + +> **Environment Variables**: Use `{env_variable_name}` syntax to reference environment variables for sensitive data like tokens and passwords. + +### Configuration Properties + +| Property | Description | Example | +|----------|-------------|---------| +| `dataSourceType` | Type of data source (currently supports "HTTP") | `"HTTP"` | +| `baseUrl` | Root URL of your API endpoint | `"http://localhost:3001/"` | +| `basePath` | Path appended to the base URL for all API requests | `"/api"` | +| `urlEncoderEnabled` | Whether to enable URL encoding for requests | `"false"` | +| `contentType` | Content type for requests | `"application/json"` | +| `authentication` | Authentication configuration with multiple method support | See authentication section below | +| `headers` | Default headers included in every request | Custom headers array | + +### Authentication Methods + +The framework supports multiple authentication methods that can be configured simultaneously: + +- **Bearer Token**: Uses authorization header with Bearer token +- **Basic Authentication**: Uses username/password with Basic auth header +- **Query Parameters**: Adds authentication parameters to the URL query string + +**Selecting Default Method:** + +To specify a default authentication method, set the **method** property in the **authentication** section to one of the supported types: "Bearer", "Basic", or "QueryParameters". The framework will apply this method to all requests in your project. + +**Example:** +To use Basic authentication, simply change the method property to "Basic": +```json + "authentication": { + "method": "Basic", + "options": [ + { + "type": "Basic", + "username": "{env_http_username}", + "password": "{env_http_password}" + } + ] + } +``` + +**Important**: + +Ensure you have set the environment variables http_username and http_password on your machine. While you can hardcode these values directly in the configuration, using environment variables is the recommended approach for security reasons. + +**Current Support:** + +The current version supports these three authentication methods. Future releases will include additional authentication types and the ability to create custom, project-specific authentication methods. \ No newline at end of file diff --git a/getting-started/bellatrix.data.getting.started/src/test/java/03_create_repository/ReadMe.md b/getting-started/bellatrix.data.getting.started/src/test/java/03_create_repository/ReadMe.md new file mode 100644 index 00000000..150cab80 --- /dev/null +++ b/getting-started/bellatrix.data.getting.started/src/test/java/03_create_repository/ReadMe.md @@ -0,0 +1,87 @@ +# HTTP Repositories + +**Getting Started** +The `HttpRepository` is the base class for all repositories that interact with your data source via Http calls. It provides methods to perform CRUD operations on the data. + +**Key Features:** + +- `` this allow you to define the type of entity that the repository will handle, ensuring type safety and consistency across your data operations +- Provides a consistent interface for data operations across different repositories +- Handles HTTP-specific details like request context and response handling + +- Provides a consistent interface for data operations across different repositories +- Handles HTTP-specific details like request context and response handling + +**How It Works:** + +The `HttpRepository` uses three core components to manage data operations: + +- **repositoryContext** (`HttpContext`): The base context for the repository, initialized in the constructor with settings specific to the data source, such as base path and resource-specific settings +- **requestContext** (`HttpContext`): The context for the current request, which can include headers, query parameters, and other request-specific settings +- **objectConverter** (`ObjectConverter`): An interface that defines methods for converting between string and Java objects. There is an out-of-the-box implementation for converting between JSON and Java objects, but you can implement your own converter if needed (for example, for XML or other formats) + +**Request Flow:** + +1. When the repository is created, `repositoryContext` saves the base context; +2. For each request, `requestContext` is used to handle request-specific parameters like headers and query parameters +3. When a response with data is received, `objectConverter` converts the response data into Java objects if applicable +4. At the end of the request, the request context is reset to the repository context + +This design enables reusing the repository context as a foundation for all requests while allowing request-specific customization through the request context. This approach allows maintaining a single repository instance for all operations, with no overlap between different requests, ensuring that each request can be tailored to its specific needs without affecting others. + +**Example Usage:** + +To demonstrate how to use the `HttpRepository`, let's create a complete example with an `Artist` entity and its corresponding repository. + +#### Step 1: Create the Entity Class +```java +@Data +@SuperBuilder +@EqualsAndHashCode(callSuper = true) +public class Artist extends HttpEntity { + @SerializedName("ArtistId") + private String id; + + @SerializedName("Name") + private String name; + + @Override + public String getIdentifier() { + return id; + } +} +``` +#### Step 2: Create the Repository Class + +Next, create a repository that extends `HttpRepository`: + +```java +public class ArtistRepository extends HttpRepository { + public ArtistRepository() { + super(Artist.class, new JsonConverter(builder -> { + builder.setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE); + }), () -> { + var httpSettings = ConfigurationService.get(DataSettings.class).getHttpSettings(); + var httpContext = new HttpContext(httpSettings); + httpContext.addPathParameter("/artists"); + return httpContext; + }); + } +} +``` + +**Constructor Parameters Explained:** + +- `Artist.class`: Specifies the entity type for type-safe operations +- `JsonConverter`: adding a custom JSON converter that handles UpperCamelCase field naming +- `HttpContext`: Configures the HTTP endpoint by combining base settings with the `/artists` path + +#### Step 3: Using the Repository + +Now you can perform CRUD operations using your repository: + +```java +ArtistRepository artistRepository = new ArtistRepository(); + +ArtistRepository artists = artistRepository.getAll(); +``` \ No newline at end of file diff --git a/getting-started/bellatrix.data.getting.started/src/test/java/project_setup/template/testFrameworkSettings.test.json b/getting-started/bellatrix.data.getting.started/src/test/java/project_setup/template/testFrameworkSettings.test.json deleted file mode 100644 index e4b630cd..00000000 --- a/getting-started/bellatrix.data.getting.started/src/test/java/project_setup/template/testFrameworkSettings.test.json +++ /dev/null @@ -1,146 +0,0 @@ -{ - "troubleshootingSettings": { - "debugInformationEnabled": "true" - }, - "dataSettings": { - "dataSourceType": "HTTP", - "httpSettings": { - "baseUrl": "http://localhost:3001/", - "basePath": "/api", - "urlEncoderEnabled": "false", - "contentType": "application/json", - "headers": [ - { - "name": "Accept", - "value": "application/json" - } - ], - "authentication": { - "method": "Basic", - "options": [ - { - "type": "Bearer", - "token": "{env_http_bearer_token}" - }, - { - "type": "Basic", - "username": "{env_http_username}", - "password": "{env_http_password}" - }, - { - "insertionOrder": "start", - "type": "QueryParameters", - "key": "{env_http_query_key}", - "token": "{env_http_query_token}" - } - ] - } - } - }, - "webSettings": { - "baseUrl": "https://ecommerce-playground.lambdatest.io", - "executionType": "regular", - "defaultBrowser": "chrome", - "defaultLifeCycle": "restart everytime time", - "artificialDelayBeforeAction": "0", - "automaticallyScrollToVisible": "false", - "waitUntilReadyOnElementFound": "false", - "waitForAngular": "false", - "shouldHighlightElements": "true", - "shouldCaptureHttpTraffic": "false", - "screenshotsOnFailEnabled": "false", - "screenshotsSaveLocation": "${user.home}/BELLATRIX/Screenshots", - "videosOnFailEnabled": "false", - "videosSaveLocation": "${user.home}/BELLATRIX/Videos", - "timeoutSettings": { - "elementWaitTimeout": "30", - "pageLoadTimeout": "30", - "scriptTimeout": "1", - "waitForAjaxTimeout": "30", - "sleepInterval": "1", - "waitUntilReadyTimeout": "30", - "waitForJavaScriptAnimationsTimeout": "30", - "waitForAngularTimeout": "30", - "waitForPartialUrl": "30", - "validationsTimeout": "30", - "elementToBeVisibleTimeout": "30", - "elementToExistTimeout": "30", - "elementToNotExistTimeout": "30", - "elementToBeClickableTimeout": "30", - "elementNotToBeVisibleTimeout": "30", - "elementToHaveContentTimeout": "15" - }, - "gridSettings": [ - { - "providerName": "saucelabs", - "url": "http://ondemand.saucelabs.com:80/wd/hub", - "arguments": [ - { - "screenResolution": "1280x800", - "recordVideo": "true", - "recordScreenshots": "true", - "username": "myUserName", - "accessKey": "myPass", - "name": "bellatrix_run" - } - ] - }, - { - "providerName": "browserstack", - "url": "http://hub-cloud.browserstack.com/wd/hub/", - "arguments": [ - { - "resolution": "1280x800", - "browserstack.video": "true", - "browserstack.networkLogs": "true", - "browserstack.debug": "true", - "browserstack.console": "errors", - "browserstack.user": "myUserName", - "browserstack.key": "myPass", - "build": "bellatrix_run" - } - ] - }, - { - "providerName": "crossbrowsertesting", - "url": "http://hub.crossbrowsertesting.com:80/wd/hub", - "arguments": [ - { - "screen_resolution": "1280x800", - "record_video": "true", - "record_network": "true", - "username": "myUserName", - "password": "myPass", - "name": "bellatrix_run" - } - ] - }, - { - "providerName": "selenoid", - "url": "http://127.0.0.1:4444/wd/hub", - "arguments": [ - { - "screenResolution": "1280x800", - "enableVNC": "true", - "enableVideo": "true", - "enableLog": "true", - "name": "bellatrix_run" - } - ] - }, - { - "providerName": "grid", - "url": "http://127.0.0.1:4444/wd/hub", - "arguments": [ - { - "name": "bellatrix_run" - } - ] - } - ] - }, - "urlSettings": { - "shopUrl": "http://demos.bellatrix.solutions/cart/", - "accountUrl": "http://demos.bellatrix.solutions/account/" - } -} \ No newline at end of file From e7db03966678a202da37b8f83de7cbc4c359d6c2 Mon Sep 17 00:00:00 2001 From: "veselinov.viktor" Date: Tue, 29 Jul 2025 16:31:08 +0300 Subject: [PATCH 06/12] added fix --- .../src/test/java/02_http_settings/ReadMe.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/getting-started/bellatrix.data.getting.started/src/test/java/02_http_settings/ReadMe.md b/getting-started/bellatrix.data.getting.started/src/test/java/02_http_settings/ReadMe.md index 4e0ca63d..25757b64 100644 --- a/getting-started/bellatrix.data.getting.started/src/test/java/02_http_settings/ReadMe.md +++ b/getting-started/bellatrix.data.getting.started/src/test/java/02_http_settings/ReadMe.md @@ -93,7 +93,7 @@ To use Basic authentication, simply change the method property to "Basic": **Important**: -Ensure you have set the environment variables http_username and http_password on your machine. While you can hardcode these values directly in the configuration, using environment variables is the recommended approach for security reasons. +Ensure you have set the environment variables `http_username` and `http_password` on your machine. While you can hardcode these values directly in the configuration, using environment variables is the recommended approach for security reasons. **Current Support:** From dcd95be3961de3050c28bd9c61c34ff1a86e567d Mon Sep 17 00:00:00 2001 From: veselinov-viktor <96745619+veselinovviktor@users.noreply.github.com> Date: Tue, 29 Jul 2025 16:34:14 +0300 Subject: [PATCH 07/12] Update ReadMe.md --- .../src/test/java/02_http_settings/ReadMe.md | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/getting-started/bellatrix.data.getting.started/src/test/java/02_http_settings/ReadMe.md b/getting-started/bellatrix.data.getting.started/src/test/java/02_http_settings/ReadMe.md index 25757b64..e05161c7 100644 --- a/getting-started/bellatrix.data.getting.started/src/test/java/02_http_settings/ReadMe.md +++ b/getting-started/bellatrix.data.getting.started/src/test/java/02_http_settings/ReadMe.md @@ -90,11 +90,8 @@ To use Basic authentication, simply change the method property to "Basic": ] } ``` +>[!CAUTION] +>Ensure you have set the environment variables `http_username` and `http_password` on your machine. While you can hardcode these values directly in the configuration, using environment variables is the recommended approach for security reasons. -**Important**: - -Ensure you have set the environment variables `http_username` and `http_password` on your machine. While you can hardcode these values directly in the configuration, using environment variables is the recommended approach for security reasons. - -**Current Support:** - -The current version supports these three authentication methods. Future releases will include additional authentication types and the ability to create custom, project-specific authentication methods. \ No newline at end of file +> [!NOTE] +> The current version supports these three authentication methods. Future releases will include additional authentication types and the ability to create custom, project-specific authentication methods. From c3f1cc216f9118e370f924b8a8b33b7f4664c459 Mon Sep 17 00:00:00 2001 From: "veselinov.viktor" Date: Tue, 29 Jul 2025 16:42:42 +0300 Subject: [PATCH 08/12] adding create entity section --- .../src/test/java/02_http_settings/ReadMe.md | 2 +- .../ReadMe.md | 15 ++++++++++----- .../ReadMe.md | 10 +--------- .../src/test/java/BaseTest.java | 1 + 4 files changed, 13 insertions(+), 15 deletions(-) rename getting-started/bellatrix.data.getting.started/src/test/java/{02_create_entity => 03_create_entity}/ReadMe.md (91%) rename getting-started/bellatrix.data.getting.started/src/test/java/{02_http_context => 03_http_context}/ReadMe.md (87%) diff --git a/getting-started/bellatrix.data.getting.started/src/test/java/02_http_settings/ReadMe.md b/getting-started/bellatrix.data.getting.started/src/test/java/02_http_settings/ReadMe.md index e05161c7..e9b32041 100644 --- a/getting-started/bellatrix.data.getting.started/src/test/java/02_http_settings/ReadMe.md +++ b/getting-started/bellatrix.data.getting.started/src/test/java/02_http_settings/ReadMe.md @@ -94,4 +94,4 @@ To use Basic authentication, simply change the method property to "Basic": >Ensure you have set the environment variables `http_username` and `http_password` on your machine. While you can hardcode these values directly in the configuration, using environment variables is the recommended approach for security reasons. > [!NOTE] -> The current version supports these three authentication methods. Future releases will include additional authentication types and the ability to create custom, project-specific authentication methods. +> The current version supports these three authentication methods. Future releases will include additional authentication types and the ability to create custom, project-specific authentication methods. \ No newline at end of file diff --git a/getting-started/bellatrix.data.getting.started/src/test/java/02_create_entity/ReadMe.md b/getting-started/bellatrix.data.getting.started/src/test/java/03_create_entity/ReadMe.md similarity index 91% rename from getting-started/bellatrix.data.getting.started/src/test/java/02_create_entity/ReadMe.md rename to getting-started/bellatrix.data.getting.started/src/test/java/03_create_entity/ReadMe.md index e8f285f7..ebc4cc36 100644 --- a/getting-started/bellatrix.data.getting.started/src/test/java/02_create_entity/ReadMe.md +++ b/getting-started/bellatrix.data.getting.started/src/test/java/03_create_entity/ReadMe.md @@ -1,4 +1,4 @@ -# HttpEntity +# Entity Classes `HttpEntity` is the base class for all data entity classes in your application. @@ -38,7 +38,7 @@ public class Artist extends HttpEntity { - The `getIdentifier()` method returns the unique identifier used for CRUD operations -# Entity Class +# Base Entity Class `HttpEntity` extends the `Entity` class, which provides the core interface for all data entities regardless of their data source. @@ -55,7 +55,7 @@ This architecture streamlines data management by reducing the lines of code need There are three main approaches to working with entities and repositories: -### Option 1: Explicit Repository Usage (Verbose but Clear) +#### Option 1: Explicit Repository Usage (Verbose but Clear) Create a repository instance and use it explicitly for operations: @@ -82,9 +82,14 @@ Artist artist = new ArtistRepository().create(Artist.builder().name("J.K.Rowling Register repositories once and perform operations directly on entities: ```java -RepositoryFactory.INSTANCE.registerRepository(Artist.class, ArtistRepository.class); - Artist artist = Artist.builder().name("James Clavell").build().create(); + +// Direct operations on the entity +artist.setName("Updated Name"); +artist.update(); // Updates via HTTP call + +// Access response information +artist.getResponse().getNativeResponse(); ``` **Benefits:** Most concise, entity-focused design, automatic repository management \ No newline at end of file diff --git a/getting-started/bellatrix.data.getting.started/src/test/java/02_http_context/ReadMe.md b/getting-started/bellatrix.data.getting.started/src/test/java/03_http_context/ReadMe.md similarity index 87% rename from getting-started/bellatrix.data.getting.started/src/test/java/02_http_context/ReadMe.md rename to getting-started/bellatrix.data.getting.started/src/test/java/03_http_context/ReadMe.md index 6a1b60d8..ec6e1e0b 100644 --- a/getting-started/bellatrix.data.getting.started/src/test/java/02_http_context/ReadMe.md +++ b/getting-started/bellatrix.data.getting.started/src/test/java/03_http_context/ReadMe.md @@ -4,7 +4,6 @@ This guide explains how to use HttpContext for dynamic configuration, and customize requests for your specific API endpoints. - ## HttpContext Class The `HttpContext` class acts as a bridge between your base configuration and actual HTTP requests. It encapsulates HTTP operation settings and provides dynamic request configuration capabilities. @@ -64,11 +63,4 @@ httpContext.addPathParameter("/123"); // Results in: /api/artists/123 // Add query parameters httpContext.addQueryParameter("limit", "10"); httpContext.addQueryParameter("offset", "0"); // Results in: /api/artists?limit=10&offset=0 -``` - -## Best Practices - -- **Environment Variables**: Always use environment variables for sensitive authentication data -- **Path Structure**: Keep path parameters organized and RESTful (`/resource/{id}`) -- **Error Handling**: Configure appropriate timeout and retry settings for production use -- **Security**: Use HTTPS URLs in production environments \ No newline at end of file +``` \ No newline at end of file diff --git a/getting-started/bellatrix.data.getting.started/src/test/java/BaseTest.java b/getting-started/bellatrix.data.getting.started/src/test/java/BaseTest.java index cce1cab5..188d88d1 100644 --- a/getting-started/bellatrix.data.getting.started/src/test/java/BaseTest.java +++ b/getting-started/bellatrix.data.getting.started/src/test/java/BaseTest.java @@ -9,5 +9,6 @@ public void getAllResources_when_sendGetAlRequest() { var artistRepository = new ArtistRepository(); Artist artist = Artist.builder().name("James Clavell").build().create(); + artist.getResponse().getNativeResponse(); } } \ No newline at end of file From b772c2df8ced813125d14fe9c6cea3cd21feb93f Mon Sep 17 00:00:00 2001 From: "veselinov.viktor" Date: Tue, 29 Jul 2025 17:10:58 +0300 Subject: [PATCH 09/12] adding getting started read me files --- .../bellatrix.data.getting.started/README.md | 87 +++++++++++++++++-- .../src/main/java/ArtistRepository.java | 2 + .../ReadMe.md | 57 +++++++----- .../ReadMe.md | 13 ++- .../test/java/06_object_converter/ReadMe.md | 84 ++++++++++++++++++ 5 files changed, 210 insertions(+), 33 deletions(-) rename getting-started/bellatrix.data.getting.started/src/test/java/{03_create_repository => 04_create_repository}/ReadMe.md (53%) rename getting-started/bellatrix.data.getting.started/src/test/java/{03_http_context => 05_http_context}/ReadMe.md (83%) create mode 100644 getting-started/bellatrix.data.getting.started/src/test/java/06_object_converter/ReadMe.md diff --git a/getting-started/bellatrix.data.getting.started/README.md b/getting-started/bellatrix.data.getting.started/README.md index 3272440b..38a26876 100644 --- a/getting-started/bellatrix.data.getting.started/README.md +++ b/getting-started/bellatrix.data.getting.started/README.md @@ -52,17 +52,86 @@ HttpRequest request = HttpRequest.newBuilder() HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString()); ``` -**With Bellatrix:Traditional Approach:** -Just define your HTTP entity and create a repository instance - no-boilerplate required. +**With Bellatrix Approach:** +Just define your HTTP entity and create a repository instance - no boilerplate required. +## Core Components -HttpEntity -Represents the data objects your API works with. Each entity corresponds to a resource (such as Artist, Album, etc.) and defines the structure and fields of that resource in your application. +### HttpEntity -HttpRepository -Acts as the client for performing CRUD (Create, Read, Update, Delete) operations on your entities. It manages sending requests to the API and handling responses, providing a simple interface for interacting with your data source. +HttpEntity represents the data objects your API works with. Each entity corresponds to a resource (such as Artist, Album, etc.) and defines the structure and fields of that resource. + +**Key Features:** +- **Type Safety**: Generic type parameters ensure compile-time type checking +- **JSON Serialization**: Built-in support for JSON field mapping with `@SerializedName` +- **Builder Pattern**: Lombok's `@SuperBuilder` enables fluent object creation + +```java +@Data +@SuperBuilder +@EqualsAndHashCode(callSuper = true) +public class Artist extends HttpEntity { + @SerializedName("ArtistId") + private String id; + + @SerializedName("Name") + private String name; + + @Override + public String getIdentifier() { + return id; + } +} +``` + +### HttpRepository + +HttpRepository acts as the client for performing CRUD operations on your entities. It manages HTTP requests and responses, providing a clean interface for data interactions. + +**Key Features:** +- **Generic CRUD Operations**: Built-in methods for Create, Read, Update, Delete +- **Configurable Conversion**: Custom JSON converters for different API formats +- **HTTP Context Management**: Flexible configuration for different endpoints + +```java +public class ArtistRepository extends HttpRepository { + public ArtistRepository() { + super(Artist.class, new JsonConverter(builder -> { + builder.setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE); + }), () -> { + var httpSettings = ConfigurationService.get(DataSettings.class).getHttpSettings(); + var httpContext = new HttpContext(httpSettings); + httpContext.addPathParameter("/artists"); + return httpContext; + }); + } +} +``` + +### Usage Example + +Once you've defined your entity and repository, you can start performing operations immediately: ```java - ArtistRepository artistRepository = new ArtistRepository(); - List artists = artistRepository.getAll(); -``` \ No newline at end of file +// Create repository instance +ArtistRepository artistRepository = new ArtistRepository(); + +// Perform CRUD operations +List artists = artistRepository.getAll(); +Artist newArtist = Artist.builder().name("New Artist").build(); +Artist created = artistRepository.create(newArtist); +``` + +## Extensibility in mind + +The Bellatrix Data Module is designed with extensibility in mind. Explore these guides to learn more: + +### Core Concepts +- **[Create Repository](src/test/java/04_create_repository/ReadMe.md)** - Learn how to create custom repositories for your data entities +- **[HTTP Context Configuration](src/test/java/05_http_context/ReadMe.md)** - Configure HTTP settings and customize requests for your API endpoints +- **[Object Converter](src/test/java/06_object_converter/ReadMe.md)** - Implement custom converters for different data formats (JSON, XML, etc.) + +### Additional Resources +- **[Project Setup](src/test/java/01_project_setup/)** - Initial project configuration +- **[HTTP Settings](src/test/java/02_http_settings/)** - Configure HTTP client settings +- **[Create Entity](src/test/java/03_create_entity/)** - Define your data entities \ No newline at end of file diff --git a/getting-started/bellatrix.data.getting.started/src/main/java/ArtistRepository.java b/getting-started/bellatrix.data.getting.started/src/main/java/ArtistRepository.java index 36dd9e4c..09df64b0 100644 --- a/getting-started/bellatrix.data.getting.started/src/main/java/ArtistRepository.java +++ b/getting-started/bellatrix.data.getting.started/src/main/java/ArtistRepository.java @@ -4,6 +4,7 @@ import solutions.bellatrix.data.http.httpContext.HttpContext; import solutions.bellatrix.data.http.infrastructure.HttpRepository; import solutions.bellatrix.data.http.infrastructure.JsonConverter; +import solutions.bellatrix.data.http.infrastructure.QueryParameter; public class ArtistRepository extends HttpRepository { public ArtistRepository() { @@ -13,6 +14,7 @@ public ArtistRepository() { var httpSettings = ConfigurationService.get(DataSettings.class).getHttpSettings(); var httpContext = new HttpContext(httpSettings); httpContext.addPathParameter("artists"); + httpContext.addQueryParameter(new QueryParameter("username", "testUser")); return httpContext; }); } diff --git a/getting-started/bellatrix.data.getting.started/src/test/java/03_create_repository/ReadMe.md b/getting-started/bellatrix.data.getting.started/src/test/java/04_create_repository/ReadMe.md similarity index 53% rename from getting-started/bellatrix.data.getting.started/src/test/java/03_create_repository/ReadMe.md rename to getting-started/bellatrix.data.getting.started/src/test/java/04_create_repository/ReadMe.md index 150cab80..ca8724e1 100644 --- a/getting-started/bellatrix.data.getting.started/src/test/java/03_create_repository/ReadMe.md +++ b/getting-started/bellatrix.data.getting.started/src/test/java/04_create_repository/ReadMe.md @@ -1,39 +1,38 @@ # HTTP Repositories -**Getting Started** -The `HttpRepository` is the base class for all repositories that interact with your data source via Http calls. It provides methods to perform CRUD operations on the data. +## Overview -**Key Features:** +The `HttpRepository` is the base class for all repositories that interact with your data source via HTTP calls. It provides methods to perform CRUD operations on your data entities. -- `` this allow you to define the type of entity that the repository will handle, ensuring type safety and consistency across your data operations -- Provides a consistent interface for data operations across different repositories -- Handles HTTP-specific details like request context and response handling +## Key Features -- Provides a consistent interface for data operations across different repositories -- Handles HTTP-specific details like request context and response handling +- **Type Safety**: Generic `` allows you to define the specific entity type the repository handles, ensuring type safety and consistency across your data operations +- **Consistent Interface**: Provides a uniform interface for data operations across different repositories +- **HTTP Management**: Handles HTTP-specific details like request context and response handling automatically -**How It Works:** +## How It Works The `HttpRepository` uses three core components to manage data operations: - **repositoryContext** (`HttpContext`): The base context for the repository, initialized in the constructor with settings specific to the data source, such as base path and resource-specific settings - **requestContext** (`HttpContext`): The context for the current request, which can include headers, query parameters, and other request-specific settings -- **objectConverter** (`ObjectConverter`): An interface that defines methods for converting between string and Java objects. There is an out-of-the-box implementation for converting between JSON and Java objects, but you can implement your own converter if needed (for example, for XML or other formats) +- **objectConverter** (`ObjectConverter`): An interface that defines methods for converting between strings and Java objects. There is an out-of-the-box implementation for JSON conversion, but you can implement your own converter for other formats (e.g., XML) -**Request Flow:** +## Request Flow -1. When the repository is created, `repositoryContext` saves the base context; -2. For each request, `requestContext` is used to handle request-specific parameters like headers and query parameters -3. When a response with data is received, `objectConverter` converts the response data into Java objects if applicable +1. When the repository is created, `repositoryContext` stores the base context +2. For each request, `requestContext` handles request-specific parameters like headers and query parameters +3. When a response with data is received, `objectConverter` converts the response data into Java objects 4. At the end of the request, the request context is reset to the repository context -This design enables reusing the repository context as a foundation for all requests while allowing request-specific customization through the request context. This approach allows maintaining a single repository instance for all operations, with no overlap between different requests, ensuring that each request can be tailored to its specific needs without affecting others. +This design enables reusing the repository context as a foundation for all requests while allowing request-specific customization. This approach maintains a single repository instance for all operations, with no overlap between different requests, ensuring that each request can be tailored to its specific needs without affecting others. -**Example Usage:** +## Example: Creating an Artist Repository To demonstrate how to use the `HttpRepository`, let's create a complete example with an `Artist` entity and its corresponding repository. -#### Step 1: Create the Entity Class +### Step 1: Create the Entity Class + ```java @Data @SuperBuilder @@ -51,7 +50,8 @@ public class Artist extends HttpEntity { } } ``` -#### Step 2: Create the Repository Class + +### Step 2: Create the Repository Class Next, create a repository that extends `HttpRepository`: @@ -73,15 +73,30 @@ public class ArtistRepository extends HttpRepository { **Constructor Parameters Explained:** - `Artist.class`: Specifies the entity type for type-safe operations -- `JsonConverter`: adding a custom JSON converter that handles UpperCamelCase field naming +- `JsonConverter`: Adds a custom JSON converter that handles UpperCamelCase field naming - `HttpContext`: Configures the HTTP endpoint by combining base settings with the `/artists` path -#### Step 3: Using the Repository +### Step 3: Using the Repository Now you can perform CRUD operations using your repository: ```java ArtistRepository artistRepository = new ArtistRepository(); -ArtistRepository artists = artistRepository.getAll(); +// Get all artists +List artists = artistRepository.getAll(); + +// Create a new artist +Artist newArtist = Artist.builder().name("The Beatles").build(); +Artist createdArtist = artistRepository.create(newArtist); + +// Get artist by ID +Artist artist = artistRepository.getById("123"); + +// Update an artist +artist.setName("The Rolling Stones"); +Artist updatedArtist = artistRepository.update(artist); + +// Delete an artist +artistRepository.delete(artist); ``` \ No newline at end of file diff --git a/getting-started/bellatrix.data.getting.started/src/test/java/03_http_context/ReadMe.md b/getting-started/bellatrix.data.getting.started/src/test/java/05_http_context/ReadMe.md similarity index 83% rename from getting-started/bellatrix.data.getting.started/src/test/java/03_http_context/ReadMe.md rename to getting-started/bellatrix.data.getting.started/src/test/java/05_http_context/ReadMe.md index ec6e1e0b..30949979 100644 --- a/getting-started/bellatrix.data.getting.started/src/test/java/03_http_context/ReadMe.md +++ b/getting-started/bellatrix.data.getting.started/src/test/java/05_http_context/ReadMe.md @@ -2,7 +2,14 @@ ## Overview -This guide explains how to use HttpContext for dynamic configuration, and customize requests for your specific API endpoints. +This guide explains how to use `HttpContext` for dynamic configuration and customize requests for your specific API endpoints. + +## Prerequisites + +Before using HttpContext, ensure you have: +- Configured your `testFrameworksSettings.json` file +- Set up your HTTP data source settings +- Created your entity and repository classes ## HttpContext Class @@ -61,6 +68,6 @@ httpContext.addPathParameter("/artists"); httpContext.addPathParameter("/123"); // Results in: /api/artists/123 // Add query parameters -httpContext.addQueryParameter("limit", "10"); -httpContext.addQueryParameter("offset", "0"); // Results in: /api/artists?limit=10&offset=0 +httpContext.addQueryParameter(new QueryParameter("username", "testUser")); + // Results in: /api/artists?username=testUser ``` \ No newline at end of file diff --git a/getting-started/bellatrix.data.getting.started/src/test/java/06_object_converter/ReadMe.md b/getting-started/bellatrix.data.getting.started/src/test/java/06_object_converter/ReadMe.md new file mode 100644 index 00000000..27a7def5 --- /dev/null +++ b/getting-started/bellatrix.data.getting.started/src/test/java/06_object_converter/ReadMe.md @@ -0,0 +1,84 @@ +# ObjectConverter + +The `ObjectConverter` is an interface that defines methods for converting between string and Java objects. The Bellatrix Data Module includes an out-of-the-box implementation for JSON conversion, but you can implement your own converter for other formats like XML. + +## JsonConverter Implementation + +The `JsonConverter` class provides a simple way to convert between Java objects and their JSON string representations using the Gson library. It offers flexible configuration through a `Consumer` parameter in its constructor. + +**Key Features:** + +- Converts objects to JSON strings with `toString()` methods +- Deserializes JSON strings back to Java objects with `fromString()` +- Supports list deserialization with `fromStringToList()` +- Includes error handling for null values and malformed JSON +- Provided default settings which can be seen in `getInstance()` method +- Mechanism for extending or overriding default settings via constructor + +**Configuration Process:** + +1. The constructor accepts a `Consumer` that allows you to customize serialization settings +2. The `getInstance` method creates a `Gson` instance with predefined default settings +3. Your custom consumer function then overrides these defaults with your specific configuration +4. The final configured `Gson` instance handles all serialization and deserialization operations + +### Implementing Custom Converters + +**Custom Configuration Example:** + +If your server returns JSON data in a different format than the default (e.g., using UpperCamelCase instead of lowercase_with_underscores), you can configure the `JsonConverter` to handle this: + +```json +{ + "ArtistId": 281, + "Name": "Artist Name" +} +``` + +### Option 1: Repository-specific Configuration + +For cases where you need to handle a unique format, configure the `JsonConverter` directly in your repository class: + +```java +protected ArtistRepository() { + super(Artist.class, new JsonConverter(builder -> { + builder.setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE); + }), () -> { + var httpSettings = ConfigurationService.get(DataSettings.class).getHttpSettings(); + var httpContext = new HttpContext(httpSettings); + httpContext.addPathParameter("/artists"); + return httpContext; + }); +} +``` + +This configuration tells the `JsonConverter` to use UpperCamelCase field naming, allowing it to properly map JSON fields like "ArtistId" and "Name" to your Java object properties. + +### Option 2: Custom Converter Class + +Create your own custom converter by extending the `JsonConverter` class. This is useful when you have specific rules applicable to multiple entities of the same type: The benefit of this approach is that you can encapsulate the conversion logic in a single class, making it reusable across different repositories as well as providing multiple options at single place. + +```java +public class ArtistsConverter extends JsonConverter { + public ArtistsConverter() { + super(builder -> { + builder.setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE); + }); + } +} +``` + +Recommended for cases where you have multiple repositories that need to handle the same JSON format. This way, you can reuse the converter across different repositories without duplicating code. + +Then use it in your repository: + +```java +public ArtistRepository() { + super(Artist.class, new ArtistsConverter(), () -> { + var httpSettings = ConfigurationService.get(DataSettings.class).getHttpSettings(); + var httpContext = new HttpContext(httpSettings); + httpContext.addPathParameter("/artists"); + return httpContext; + }); +} +``` \ No newline at end of file From b867f085d1a20755dc7f2498f3e4f8eeb07fcc00 Mon Sep 17 00:00:00 2001 From: "veselinov.viktor" Date: Tue, 5 Aug 2025 10:09:33 +0300 Subject: [PATCH 10/12] fix doc --- .../src/test/java/03_create_entity/ReadMe.md | 4 ++-- .../src/test/java/04_create_repository/ReadMe.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/getting-started/bellatrix.data.getting.started/src/test/java/03_create_entity/ReadMe.md b/getting-started/bellatrix.data.getting.started/src/test/java/03_create_entity/ReadMe.md index ebc4cc36..750dc5b1 100644 --- a/getting-started/bellatrix.data.getting.started/src/test/java/03_create_entity/ReadMe.md +++ b/getting-started/bellatrix.data.getting.started/src/test/java/03_create_entity/ReadMe.md @@ -17,7 +17,7 @@ Let's create an entity class that represents an artist in our music shop applica @Data @SuperBuilder @EqualsAndHashCode(callSuper = true) -public class Artist extends HttpEntity { +public class Artist extends HttpEntity { @SerializedName("ArtistId") private String id; @@ -33,7 +33,7 @@ public class Artist extends HttpEntity { **Key Points:** -- The class extends `HttpEntity` where `String` is the identifier type +- The class extends `HttpEntity` - `@SerializedName` annotations map JSON fields to Java properties for proper serialization - The `getIdentifier()` method returns the unique identifier used for CRUD operations diff --git a/getting-started/bellatrix.data.getting.started/src/test/java/04_create_repository/ReadMe.md b/getting-started/bellatrix.data.getting.started/src/test/java/04_create_repository/ReadMe.md index ca8724e1..217ce16d 100644 --- a/getting-started/bellatrix.data.getting.started/src/test/java/04_create_repository/ReadMe.md +++ b/getting-started/bellatrix.data.getting.started/src/test/java/04_create_repository/ReadMe.md @@ -37,7 +37,7 @@ To demonstrate how to use the `HttpRepository`, let's create a complete example @Data @SuperBuilder @EqualsAndHashCode(callSuper = true) -public class Artist extends HttpEntity { +public class Artist extends HttpEntity { @SerializedName("ArtistId") private String id; @@ -56,7 +56,7 @@ public class Artist extends HttpEntity { Next, create a repository that extends `HttpRepository`: ```java -public class ArtistRepository extends HttpRepository { +public class ArtistRepository extends HttpRepository { public ArtistRepository() { super(Artist.class, new JsonConverter(builder -> { builder.setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE); From 69b5c1c7c59923610faaf6492406d61bdc558dbb Mon Sep 17 00:00:00 2001 From: "veselinov.viktor" Date: Thu, 7 Aug 2025 13:54:26 +0300 Subject: [PATCH 11/12] fix maven build --- framework-tests/bellatrix.data.tests/pom.xml | 1 + .../src/test/java/04_create_repository/ReadMe.md | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/framework-tests/bellatrix.data.tests/pom.xml b/framework-tests/bellatrix.data.tests/pom.xml index fe8e93f8..e438f9e9 100644 --- a/framework-tests/bellatrix.data.tests/pom.xml +++ b/framework-tests/bellatrix.data.tests/pom.xml @@ -7,6 +7,7 @@ solutions.bellatrix bellatrix 1.0-SNAPSHOT + ../../pom.xml bellatrix.data.tests diff --git a/getting-started/bellatrix.data.getting.started/src/test/java/04_create_repository/ReadMe.md b/getting-started/bellatrix.data.getting.started/src/test/java/04_create_repository/ReadMe.md index 217ce16d..0dffd2b2 100644 --- a/getting-started/bellatrix.data.getting.started/src/test/java/04_create_repository/ReadMe.md +++ b/getting-started/bellatrix.data.getting.started/src/test/java/04_create_repository/ReadMe.md @@ -56,7 +56,7 @@ public class Artist extends HttpEntity { Next, create a repository that extends `HttpRepository`: ```java -public class ArtistRepository extends HttpRepository { +public class ArtistRepository extends HttpRepository<¡Artist> { public ArtistRepository() { super(Artist.class, new JsonConverter(builder -> { builder.setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE); From ef86e14dd1f0872ec6c3f9849147d95f0b8c28e5 Mon Sep 17 00:00:00 2001 From: "veselinov.viktor" Date: Thu, 7 Aug 2025 13:56:47 +0300 Subject: [PATCH 12/12] fix data.getting.started pom.xml --- getting-started/bellatrix.data.getting.started/pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/getting-started/bellatrix.data.getting.started/pom.xml b/getting-started/bellatrix.data.getting.started/pom.xml index f62c7516..89b73cc0 100644 --- a/getting-started/bellatrix.data.getting.started/pom.xml +++ b/getting-started/bellatrix.data.getting.started/pom.xml @@ -7,6 +7,7 @@ solutions.bellatrix bellatrix 1.0-SNAPSHOT + ../../pom.xml bellatrix.data.getting.started