diff --git a/Dockerfile b/Dockerfile index 4a953c3..e99f48c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -25,4 +25,4 @@ EXPOSE 8081 # Define the command to run when the container starts # This runs the Spring Boot application with an active Kubernetes profile -ENTRYPOINT ["java", "-Dspring.profiles.active=k8s", "-jar", "linkedin-tool.jar"] \ No newline at end of file +ENTRYPOINT ["java", "-Dspring.profiles.active=prod", "-jar", "linkedin-tool.jar"] \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 054e32e..2806a49 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -19,12 +19,33 @@ services: ports: - "8081:8081" environment: - SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/linkedin - SPRING_DATASOURCE_USERNAME: root - SPRING_DATASOURCE_PASSWORD: Admin@10525597 + - SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/linkedin + - SPRING_DATASOURCE_USERNAME=root + - SPRING_DATASOURCE_PASSWORD=Admin@10525597 + - REMOTE_WEBDRIVER_URL=http://selenium-hub:4444 + - REMOTE_WEBDRIVER_USERNAME=admin + - REMOTE_WEBDRIVER_PASSWORD=vmo@123 volumes: - backend_data:/app/data # Mount a volume for application data - + node-docker: + image: selenium/node-docker:latest + volumes: + - ./volume/assets:/opt/selenium/assets + - ./volume/config.toml:/opt/bin/config.toml + - /var/run/docker.sock:/var/run/docker.sock + depends_on: + - selenium-hub + environment: + - SE_EVENT_BUS_HOST=selenium-hub + - SE_EVENT_BUS_PUBLISH_PORT=4442 + - SE_EVENT_BUS_SUBSCRIBE_PORT=4443 + selenium-hub: + image: selenium/hub:latest + container_name: selenium-hub + ports: + - "4442:4442" + - "4443:4443" + - "4444:4444" volumes: mysql_data: # Define the volume for MySQL data backend_data: # Define the volume for application data \ No newline at end of file diff --git a/kubernetes-deployments/linkedin-tool-deployment.yml b/kubernetes-deployments/linkedin-tool-deployment.yml deleted file mode 100644 index b5944af..0000000 --- a/kubernetes-deployments/linkedin-tool-deployment.yml +++ /dev/null @@ -1,30 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: linkedin-tool-deployment -spec: - replicas: 3 - selector: - matchLabels: - app: linkedin-tool - template: - metadata: - labels: - app: linkedin-tool - spec: - containers: - - name: linkedin-tool - image: 10525597/linkedin-tool:latest - ports: - - containerPort: 8081 - env: - - name: MYSQL_HOST - value: mysql-service - - name: MYSQL_PORT - value: "3306" - - name: MYSQL_USERNAME - value: root - - name: MYSQL_PASSWORD - value: Admin@10525597 - - name: AUTHOR - value: teahan \ No newline at end of file diff --git a/kubernetes-deployments/linkedin-tool-service.yml b/kubernetes-deployments/linkedin-tool-service.yml deleted file mode 100644 index 57f315e..0000000 --- a/kubernetes-deployments/linkedin-tool-service.yml +++ /dev/null @@ -1,13 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: linkedin-tool-service -spec: - type: NodePort - selector: - app: linkedin-tool - ports: - - protocol: TCP - port: 8081 - targetPort: 8081 - nodePort: 30005 \ No newline at end of file diff --git a/kubernetes-deployments/mysql-deployment.yml b/kubernetes-deployments/mysql-deployment.yml deleted file mode 100644 index 6dffe8e..0000000 --- a/kubernetes-deployments/mysql-deployment.yml +++ /dev/null @@ -1,24 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: mysql-deployment -spec: - replicas: 1 - selector: - matchLabels: - app: mysql - template: - metadata: - labels: - app: mysql - spec: - containers: - - name: mysql - image: mysql:latest - env: - - name: MYSQL_ROOT_PASSWORD - value: Admin@10525597 # Set your desired root password here - - name: MYSQL_DATABASE - value: linkedin - ports: - - containerPort: 3306 \ No newline at end of file diff --git a/kubernetes-deployments/mysql-service.yml b/kubernetes-deployments/mysql-service.yml deleted file mode 100644 index 842c546..0000000 --- a/kubernetes-deployments/mysql-service.yml +++ /dev/null @@ -1,13 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: mysql-service -spec: - type: NodePort - selector: - app: mysql - ports: - - protocol: TCP - port: 3306 - targetPort: 3306 - nodePort: 30306 \ No newline at end of file diff --git a/pom.xml b/pom.xml index ec84e09..a169afc 100644 --- a/pom.xml +++ b/pom.xml @@ -1,121 +1,119 @@ - 4.0.0 - - org.springframework.boot - spring-boot-starter-parent - 3.2.1 - - - com.hanstack - linkedin-tool - 0.0.1-SNAPSHOT - linkedin-tool - linkedin-tool - - 17 - - - - org.springframework.boot - spring-boot-starter-data-jpa - - - - - - - org.springframework.boot - spring-boot-starter-security - - - org.springframework.boot - spring-boot-starter-thymeleaf - - - org.springframework.boot - spring-boot-starter-validation - - - org.springframework.boot - spring-boot-starter-web - - - org.thymeleaf.extras - thymeleaf-extras-springsecurity6 - + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.2.1 + + + com.hanstack + linkedin-tool + 0.0.1-SNAPSHOT + linkedin-tool + linkedin-tool + + 17 + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + + + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.boot + spring-boot-starter-thymeleaf + + + org.springframework.boot + spring-boot-starter-validation + + + org.springframework.boot + spring-boot-starter-web + + + org.thymeleaf.extras + thymeleaf-extras-springsecurity6 + com.hierynomus sshj 0.38.0 - - org.springframework.boot - spring-boot-devtools - runtime - true - - - com.mysql - mysql-connector-j - runtime - - - org.springframework.boot - spring-boot-starter-test - test - - - org.junit.vintage - junit-vintage-engine - - - - - org.springframework.security - spring-security-test - test - - - org.seleniumhq.selenium - selenium-java - 4.17.0 - - - io.github.bonigarcia - webdrivermanager - 5.6.3 - - - - org.projectlombok - lombok - 1.18.24 - provided - - + + org.springframework.boot + spring-boot-devtools + runtime + true + + + com.mysql + mysql-connector-j + 8.2.0 + + + org.springframework.boot + spring-boot-starter-test + test + + + org.springframework.security + spring-security-test + test + + + org.seleniumhq.selenium + selenium-java + 4.18.1 + + + io.github.bonigarcia + webdrivermanager + 5.7.0 + + + + org.projectlombok + lombok + 1.18.24 + provided + + + org.springframework.boot + spring-boot-starter-actuator + + - - linkedin-tool - - - org.springframework.boot - spring-boot-maven-plugin - - - linkedin-tool-v1.1.0 - - - - org.projectlombok - lombok - - - - - - + + linkedin-tool + + + org.springframework.boot + spring-boot-maven-plugin + + + linkedin-tool-v1.1.0 + + + + org.projectlombok + lombok + + + + + + diff --git a/src/main/java/com/hanstack/linkedintool/LinkedinToolApplication.java b/src/main/java/com/hanstack/linkedintool/LinkedinToolApplication.java index 234a8b1..32bd00b 100644 --- a/src/main/java/com/hanstack/linkedintool/LinkedinToolApplication.java +++ b/src/main/java/com/hanstack/linkedintool/LinkedinToolApplication.java @@ -1,13 +1,88 @@ package com.hanstack.linkedintool; +import com.hanstack.linkedintool.enums.ProfileEnum; +import io.github.bonigarcia.wdm.WebDriverManager; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.openqa.selenium.Platform; +import org.openqa.selenium.UsernameAndPassword; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.chrome.ChromeDriver; +import org.openqa.selenium.chrome.ChromeOptions; +import org.openqa.selenium.remote.Browser; +import org.openqa.selenium.remote.CapabilityType; +import org.openqa.selenium.remote.HttpCommandExecutor; +import org.openqa.selenium.remote.RemoteWebDriver; +import org.openqa.selenium.remote.http.ClientConfig; +import org.openqa.selenium.support.ui.Wait; +import org.openqa.selenium.support.ui.WebDriverWait; +import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.Resource; + +import java.io.IOException; +import java.net.URL; +import java.time.Duration; +import java.util.Base64; @SpringBootApplication +@Configuration +@Slf4j public class LinkedinToolApplication { - public static void main(String[] args) { - SpringApplication.run(LinkedinToolApplication.class, args); - } + @Value("classpath:static/drx/j2team-cookies-ext.crx") + Resource drx; + + @Value("${remote.web-driver.url}") + private String rwDriverUrl; + + @Value("${remote.web-driver.username}") + private String rwDriverUsername; + + @Value("${remote.web-driver.password}") + private String rwDriverPassword; + + @Value("${spring.profiles.active:}") + private String env; + + public static void main(String[] args) { + SpringApplication.run(LinkedinToolApplication.class, args); + WebDriverManager.chromedriver().setup(); + } + + @Bean + public WebDriver getDriverInstance() { + WebDriver driver = null; + try { + var chromeOptions = new ChromeOptions() + .addEncodedExtensions(Base64.getEncoder().encodeToString(drx.getContentAsByteArray())); + + if (StringUtils.equals(env, ProfileEnum.DEV.getName())) { + driver = new ChromeDriver(chromeOptions); + } else { + ClientConfig clientConfig = ClientConfig.defaultConfig() + .baseUrl(new URL(rwDriverUrl)) + .authenticateAs(new UsernameAndPassword(rwDriverUsername, rwDriverPassword)); + HttpCommandExecutor executor = new HttpCommandExecutor(clientConfig); + + chromeOptions.setCapability(CapabilityType.BROWSER_NAME, Browser.CHROME.browserName()); + chromeOptions.setCapability(CapabilityType.PLATFORM_NAME, Platform.LINUX.name()); + driver = new RemoteWebDriver(executor, chromeOptions); + } + } catch (IOException ex) { + log.error("There is an error when init the webdriver instance", ex.getCause()); + } + + return driver; + } + + @Bean + public Wait getWaitDriverInstance() { + WebDriver driver = getDriverInstance(); + return new WebDriverWait(driver, Duration.ofSeconds(2)); + } } diff --git a/src/main/java/com/hanstack/linkedintool/config/SeleniumFactory.java b/src/main/java/com/hanstack/linkedintool/config/SeleniumFactory.java deleted file mode 100644 index ca069c7..0000000 --- a/src/main/java/com/hanstack/linkedintool/config/SeleniumFactory.java +++ /dev/null @@ -1,100 +0,0 @@ -package com.hanstack.linkedintool.config; - -import com.hanstack.linkedintool.dto.FilterDTO; -import jakarta.servlet.http.HttpSession; -import lombok.AllArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.openqa.selenium.*; -import org.openqa.selenium.support.ui.ExpectedConditions; -import org.openqa.selenium.support.ui.Wait; -import org.springframework.web.multipart.MultipartFile; - -import java.io.File; - -@Slf4j -@AllArgsConstructor -public class SeleniumFactory { - - private final WebDriver driver; - private final Wait wait; - - public void startLinkedin() { - driver.get("https://www.linkedin.com"); - } - - - public void deleteAndImportCookies(MultipartFile cookieFile) throws Exception { - driver.manage().deleteAllCookies(); - String originalWindow = driver.getWindowHandle(); - Thread.sleep(1000); - driver.switchTo().newWindow(WindowType.TAB); - driver.get("chrome-extension://okpidcojinmlaakglciglbpcpajaibco/popup.html?url=aHR0cHM6Ly93d3cubGlua2VkaW4uY29tLw%3D%3D"); - WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]")); - File tempFile = File.createTempFile("temp", null); - cookieFile.transferTo(tempFile); - fileInput.sendKeys(tempFile.toString()); - for (String windowHandle : driver.getWindowHandles()) { - if (originalWindow.contentEquals(windowHandle)) { - driver.switchTo().window(windowHandle); - driver.navigate().refresh(); - } - } - -// JSONParser parser = new JSONParser(cookieFile.getInputStream()); -// var lstLinkHashMap = (ArrayList) ((LinkedHashMap) parser.parse()).get("cookies"); -// for (Object o : lstLinkHashMap) { -// var linkedHashMap = (LinkedHashMap) o; -// String name = linkedHashMap.get("name").toString(); -// String value = linkedHashMap.get("value").toString(); -//// String domain = linkedHashMap.get("domain").toString(); -// String domain = ".linkedin.com"; -// String path = linkedHashMap.get("path").toString(); -// Date expirationDate = new Date(); -// if (Objects.nonNull(linkedHashMap.get("expirationDate"))) { -// logger.info("TIME OF expirationDate: {}", linkedHashMap.get("expirationDate")); -// try { -// expirationDate.setTime(((BigDecimal) linkedHashMap.get("expirationDate")).longValue()); -// } catch ( Exception e) { -// expirationDate.setTime(Long.parseLong(linkedHashMap.get("expirationDate").toString())); -// } -// } -// boolean isSecure = Boolean.parseBoolean(linkedHashMap.get("secure").toString()); -// boolean isHttpOnly = Boolean.parseBoolean(linkedHashMap.get("httpOnly").toString()); -// String sameSite = linkedHashMap.get("sameSite").toString(); -// Cookie cookie = new Cookie(name, value, domain, path, expirationDate, isSecure, isHttpOnly, sameSite); -// try { -// driver.manage().addCookie(cookie); -// } catch (Exception e) { -// logger.info("Error in {}", cookie.toString()); -// logger.error(e.getMessage()); -// } -// -// } - } - - public void searchByFilter(FilterDTO filterDTO, HttpSession httpSession) throws Exception { - By byGlobalSearch = By.className("search-global-typeahead__input"); - wait.until(ExpectedConditions.presenceOfElementLocated(byGlobalSearch)); - - WebElement searchBarInp = driver.findElement(By.className("search-global-typeahead__input")); - searchBarInp.sendKeys(filterDTO.getGlobalNavSearch()); - Thread.sleep(1000); - searchBarInp.sendKeys(Keys.ENTER); - - String dynamicXpath = String.format("//button[@aria-pressed='false'][normalize-space()='%s']", filterDTO.getFilterBarGrouping().getName()); - By byGroupFilter = By.xpath(dynamicXpath); - wait.until(ExpectedConditions.presenceOfElementLocated(byGroupFilter)); - - driver.findElement(byGroupFilter).click(); - } - - public void allFilter(FilterDTO filterDTO) { - By byAllFilter = By.xpath("//button[@aria-pressed='false'][normalize-space()='People]\"(//button[normalize-space()='All filters'])[1]\"undefined"); - wait.until(ExpectedConditions.presenceOfElementLocated(byAllFilter)); - - driver.findElement(byAllFilter).click(); - - } - - -} diff --git a/src/main/java/com/hanstack/linkedintool/controller/SeleniumController.java b/src/main/java/com/hanstack/linkedintool/controller/SeleniumController.java index b3e42ea..da84919 100644 --- a/src/main/java/com/hanstack/linkedintool/controller/SeleniumController.java +++ b/src/main/java/com/hanstack/linkedintool/controller/SeleniumController.java @@ -1,57 +1,42 @@ package com.hanstack.linkedintool.controller; -import com.hanstack.linkedintool.config.SeleniumFactory; import com.hanstack.linkedintool.dto.FilterDTO; import com.hanstack.linkedintool.dto.LinkedinDTO; import com.hanstack.linkedintool.dto.LoginDTO; import com.hanstack.linkedintool.enums.ToolbarEnum; -import io.github.bonigarcia.wdm.WebDriverManager; +import com.hanstack.linkedintool.service.SeleniumService; import jakarta.servlet.http.HttpSession; +import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.openqa.selenium.WebDriver; -import org.openqa.selenium.chrome.ChromeDriver; -import org.openqa.selenium.chrome.ChromeOptions; -import org.openqa.selenium.support.ui.Wait; -import org.openqa.selenium.support.ui.WebDriverWait; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.core.io.Resource; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; -import java.time.Duration; -import java.util.Base64; - @Controller @Slf4j @RequestMapping("/selenium") +@AllArgsConstructor public class SeleniumController { - @Value("classpath:static/drx/j2team-cookies-ext.crx") - Resource drx; - + private final SeleniumService seleniumService; @PostMapping public String process(@ModelAttribute LinkedinDTO linkedinDTO, HttpSession httpSession, Model model) throws Exception { FilterDTO filterDTO = linkedinDTO.getFilterDTO(); LoginDTO loginDTO = linkedinDTO.getLoginDTO(); - WebDriverManager.chromedriver().setup(); - String base64 = Base64.getEncoder().encodeToString(drx.getContentAsByteArray()); -// WebDriver driver = new ChromeDriver(new ChromeOptions().addArguments("--incognito")); - WebDriver driver = new ChromeDriver(new ChromeOptions().addEncodedExtensions(base64)); - driver.manage().timeouts().implicitlyWait(Duration.ofMinutes(1)); - Wait wait = new WebDriverWait(driver, Duration.ofSeconds(10)); try { - SeleniumFactory seleniumFactory = new SeleniumFactory(driver, wait); - seleniumFactory.startLinkedin(); - seleniumFactory.deleteAndImportCookies(linkedinDTO.getLoginDTO().getCookieFile()); - seleniumFactory.searchByFilter(filterDTO, httpSession); + seleniumService.startLinkedin(); + seleniumService.deleteAndImportCookies(linkedinDTO.getLoginDTO().getCookieFile()); + seleniumService.searchByFilter(filterDTO); model.addAttribute("lstFilterBarGrouping", ToolbarEnum.values()); model.addAttribute(httpSession.getAttribute("linkedinDTO")); + } catch (Exception ex) { + log.error("ERROR: ", ex.getCause()); } finally { -// driver.quit(); + log.info("Close only the current browser window"); + seleniumService.close(); } return "index"; } diff --git a/src/main/java/com/hanstack/linkedintool/enums/ProfileEnum.java b/src/main/java/com/hanstack/linkedintool/enums/ProfileEnum.java new file mode 100644 index 0000000..3e606a4 --- /dev/null +++ b/src/main/java/com/hanstack/linkedintool/enums/ProfileEnum.java @@ -0,0 +1,11 @@ +package com.hanstack.linkedintool.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@AllArgsConstructor +@Getter +public enum ProfileEnum { + PROD("prod"), DEV("dev"); + private final String name; +} diff --git a/src/main/java/com/hanstack/linkedintool/service/SeleniumService.java b/src/main/java/com/hanstack/linkedintool/service/SeleniumService.java new file mode 100644 index 0000000..76d1e47 --- /dev/null +++ b/src/main/java/com/hanstack/linkedintool/service/SeleniumService.java @@ -0,0 +1,19 @@ +package com.hanstack.linkedintool.service; + +import com.hanstack.linkedintool.dto.FilterDTO; +import org.springframework.web.multipart.MultipartFile; + +public interface SeleniumService { + + void startLinkedin(); + + void deleteAndImportCookies(MultipartFile cookieFile) throws InterruptedException; + + void searchByFilter(FilterDTO filterDTO); + + void allFilter(FilterDTO filterDTO); + + void quit(); + + void close(); +} diff --git a/src/main/java/com/hanstack/linkedintool/service/impl/SeleniumServiceImpl.java b/src/main/java/com/hanstack/linkedintool/service/impl/SeleniumServiceImpl.java new file mode 100644 index 0000000..1f0e63e --- /dev/null +++ b/src/main/java/com/hanstack/linkedintool/service/impl/SeleniumServiceImpl.java @@ -0,0 +1,103 @@ +package com.hanstack.linkedintool.service.impl; + +import com.hanstack.linkedintool.dto.FilterDTO; +import com.hanstack.linkedintool.enums.ProfileEnum; +import com.hanstack.linkedintool.service.SeleniumService; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.openqa.selenium.*; +import org.openqa.selenium.remote.LocalFileDetector; +import org.openqa.selenium.remote.RemoteWebDriver; +import org.openqa.selenium.support.ui.Wait; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import java.io.File; +import java.io.IOException; + +@Service +@Slf4j +public class SeleniumServiceImpl implements SeleniumService { + + private final String env; + private final WebDriver driver; + private final Wait wait; + + public SeleniumServiceImpl( + @Value("${spring.profiles.active:}") String env, + WebDriver driver, + Wait wait + ) { + this.env = env; + this.driver = driver; + this.wait = wait; + } + + @Override + public void startLinkedin() { + driver.get("https://www.linkedin.com"); + } + + @Override + public void deleteAndImportCookies(MultipartFile cookieFile) throws InterruptedException { + try { + driver.manage().deleteAllCookies(); + String originalWindow = driver.getWindowHandle(); + Thread.sleep(1000); + driver.switchTo().newWindow(WindowType.TAB); + driver.get("chrome-extension://okpidcojinmlaakglciglbpcpajaibco/popup.html?url=aHR0cHM6Ly93d3cubGlua2VkaW4uY29tLw%3D%3D"); + if (StringUtils.equals(env, ProfileEnum.PROD.getName())) { + ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector()); + } + WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]")); + File tempFile = File.createTempFile("temp", null); + cookieFile.transferTo(tempFile); + fileInput.sendKeys(tempFile.getAbsolutePath()); + for (String windowHandle : driver.getWindowHandles()) { + if (originalWindow.contentEquals(windowHandle)) { + driver.switchTo().window(windowHandle); + driver.navigate().refresh(); + } + } + } catch (IOException e) { + throw new RuntimeException(e); + } + + } + + @Override + public void searchByFilter(FilterDTO filterDTO) { + WebElement searchBarInp = driver.findElement(By.className("search-global-typeahead__input")); + wait.until(d -> searchBarInp.isDisplayed()); + + searchBarInp.sendKeys(filterDTO.getGlobalNavSearch()); + searchBarInp.sendKeys(Keys.ENTER); + + String dynamicXpath = String.format("//button[@aria-pressed='false'][normalize-space()='%s']", filterDTO.getFilterBarGrouping().getName()); + WebElement weGroupFilter = driver.findElement(By.xpath(dynamicXpath)); + wait.until(d -> weGroupFilter.isDisplayed()); + + weGroupFilter.click(); + + } + + @Override + public void allFilter(FilterDTO filterDTO) { + WebElement allFilter = driver.findElement(By.xpath("//button[@aria-pressed='false'][normalize-space()='People]\"(//button[normalize-space()='All filters'])[1]\"undefined")); + wait.until(d -> allFilter.isDisplayed()); + + allFilter.click(); + + } + + @Override + public void quit() { + driver.quit(); + } + + @Override + public void close() { + driver.close(); + } +} diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index 5ab15e2..52dd2da 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -13,4 +13,9 @@ spring: cache: false output: ansi: - enabled: always \ No newline at end of file + enabled: always +remote: + web-driver: + url: http://localhost:4444 + username: admin + password: vmo@123 \ No newline at end of file diff --git a/src/main/resources/application-k8s.yml b/src/main/resources/application-k8s.yml deleted file mode 100644 index 51261be..0000000 --- a/src/main/resources/application-k8s.yml +++ /dev/null @@ -1,16 +0,0 @@ -spring: - datasource: - url: jdbc:mysql://mysql-service:3306/linkedin - username: root - password: Admin@10525597 - jpa: - properties: - hibernate: - dialect: org.hibernate.dialect.MySQLDialect - hibernate: - ddl-auto: update - thymeleaf: - cache: false - output: - ansi: - enabled: always \ No newline at end of file diff --git a/src/main/resources/application-prod.yml b/src/main/resources/application-prod.yml new file mode 100644 index 0000000..8121f72 --- /dev/null +++ b/src/main/resources/application-prod.yml @@ -0,0 +1,21 @@ +spring: + datasource: + url: ${SPRING_DATASOURCE_URL} + username: ${SPRING_DATASOURCE_USERNAME} + password: ${SPRING_DATASOURCE_PASSWORD} + jpa: + properties: + hibernate: + dialect: org.hibernate.dialect.MySQLDialect + hibernate: + ddl-auto: update + thymeleaf: + cache: false + output: + ansi: + enabled: always +remote: + web-driver: + url: ${REMOTE_WEBDRIVER_URL} + username: ${REMOTE_WEBDRIVER_USERNAME} + password: ${REMOTE_WEBDRIVER_PASSWORD} \ No newline at end of file diff --git a/volume/config.toml b/volume/config.toml new file mode 100644 index 0000000..d29d46c --- /dev/null +++ b/volume/config.toml @@ -0,0 +1,29 @@ +[docker] +# Configs have a mapping between the Docker image to use and the capabilities that need to be matched to +# start a container with the given image. +configs = [ + # "selenium/standalone-firefox:4.18.1-20240224", '{"browserName": "firefox", "platformName": "linux"}', + "selenium/standalone-chrome:latest", '{"browserName": "chrome", "platformName": "linux"}', + # "selenium/standalone-edge:4.18.1-20240224", '{"browserName": "MicrosoftEdge", "platformName": "linux"}' +] + +# URL for connecting to the docker daemon +# host.docker.internal works for macOS and Windows. +# Linux could use --net=host in the `docker run` instruction or 172.17.0.1 in the URI below. +# To have Docker listening through tcp on macOS, install socat and run the following command +# socat -4 TCP-LISTEN:2375,fork UNIX-CONNECT:/var/run/docker.sock +#linux +#url = "http://127.0.0.1:2375" +#macos +url = "http://host.docker.internal:2375" +# Docker image used for video recording +video-image = "selenium/video:latest" + +# Uncomment the following section if you are running the node on a separate VM +# Fill out the placeholders with appropriate values +#[server] +#host = +#port = +[route] +username = "admin" +password = "vmo@123" \ No newline at end of file