diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..d3b2d9162 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +target/ +**/.terraform/* +*.tfstate.* +.terraformrc +terraform.rc +terraform/.terraform.lock.hcl diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 000000000..dd77301a4 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,8 @@ +FROM tomcat:10.1-jdk17-temurin + +RUN rm -rf /usr/local/tomcat/webapps/* + +COPY target/vprofile-v2.war /usr/local/tomcat/webapps/ROOT.war + +EXPOSE 8080 +CMD ["catalina.sh", "run"] \ No newline at end of file diff --git a/Jenkinsfile b/Jenkinsfile index be7508be5..39c0a8212 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -1,121 +1,202 @@ +def COLOR_MAP = [ + 'SUCCESS': 'good', + 'FAILURE': 'danger', +] + pipeline { + // جعل الـ Agent الافتراضي none لأننا سنحدد لكل Stage الحاوية الخاصة بها + agent none - agent any -/* - tools { - maven "maven3" - } -*/ environment { - NEXUS_VERSION = "nexus3" - NEXUS_PROTOCOL = "http" - NEXUS_URL = "172.31.40.209:8081" - NEXUS_REPOSITORY = "vprofile-release" - NEXUS_REPO_ID = "vprofile-release" - NEXUS_CREDENTIAL_ID = "nexuslogin" - ARTVERSION = "${env.BUILD_ID}" + SNAP_REPO = 'vprofile-snapshot' + NEXUS_USER = 'admin' + NEXUS_PASS = 'admin123' + RELEASE_REPO = 'vprofile-release' + CENTRAL_REPO = 'vpro-maven-central' + NEXUSIP = '172.31.40.75' + NEXUSPORT = '8081' + NEXUS_GRP_REPO = 'vpro-maven-group' + NEXUS_LOGIN = 'nexuslogin' + SONARSERVER = 'sonarserver' + SONARSCANNER = 'sonarscanner' + NEXUSPASS = credentials('nexuspass') + + BASTION_PUBLIC_IP = '54.227.230.251' } - - stages{ + + stages { - stage('BUILD'){ + // مرحلة الـ Build: تستخدم حاوية مافن الرسمية مع جافا 17 + stage('Build'){ + agent { + docker { image 'maven:3.9.6-eclipse-temurin-17' } + } steps { sh 'mvn clean install -DskipTests' } post { success { - echo 'Now Archiving...' - archiveArtifacts artifacts: '**/target/*.war' + echo "Now Archiving." + archiveArtifacts artifacts: '**/*.war' } } } - stage('UNIT TEST'){ + + + stage('Test'){ + agent { + docker { image 'maven:3.9.6-eclipse-temurin-17' } + } steps { sh 'mvn test' } } - stage('INTEGRATION TEST'){ - steps { - sh 'mvn verify -DskipUnitTests' + stage('Checkstyle Analysis'){ + agent { + docker { image 'maven:3.9.6-eclipse-temurin-17' } } - } - - stage ('CODE ANALYSIS WITH CHECKSTYLE'){ steps { sh 'mvn checkstyle:checkstyle' } - post { - success { - echo 'Generated Analysis Result' + } + + + + + stage('SonarCloud Analysis') { + agent { + docker { + image 'sonarsource/sonar-scanner-cli:latest' + args '-u root --entrypoint=' } } - } + steps { + withCredentials([string(credentialsId: 'sonarcloud', variable: 'SONAR_TOKEN')]) { + sh ''' + sonar-scanner \ + -Dsonar.organization=jenkans \ + -Dsonar.projectKey=jenkans_vprofile-project \ + -Dsonar.sources=. \ + -Dsonar.host.url=https://sonarcloud.io \ + -Dsonar.token=$SONAR_TOKEN \ + -Dsonar.java.binaries=target/classes \ + -Dsonar.junit.reportsPath=target/surefire-reports/ \ + -Dsonar.jacoco.reportsPath=target/jacoco.exec \ + -Dsonar.java.checkstyle.reportPaths=target/checkstyle-result.xml \ + -Dsonar.exclusions=**/*.js,**/*.ts,**/*.css,**/*.html \ + -Dsonar.qualitygate.wait=false + + ''' + } + } + } + + - stage('CODE ANALYSIS with SONARQUBE') { - - environment { - scannerHome = tool 'sonarscanner4' - } - - steps { - withSonarQubeEnv('sonar-pro') { - sh '''${scannerHome}/bin/sonar-scanner -Dsonar.projectKey=vprofile \ - -Dsonar.projectName=vprofile-repo \ - -Dsonar.projectVersion=1.0 \ - -Dsonar.sources=src/ \ - -Dsonar.java.binaries=target/test-classes/com/visualpathit/account/controllerTest/ \ - -Dsonar.junit.reportsPath=target/surefire-reports/ \ - -Dsonar.jacoco.reportsPath=target/jacoco.exec \ - -Dsonar.java.checkstyle.reportPaths=target/checkstyle-result.xml''' + + stage('Build & Push to ECR') { + agent { + docker { + image 'docker:stable' + // تمرير الـ Docker Socket الخاص بالـ Host لكي نتمكن من تشغيل أوامر docker داخل حاوية الـ aws-cli + args '-v /var/run/docker.sock:/var/run/docker.sock -u root' + } + } + environment { + AWS_REGION = 'us-east-1' + AWS_ACCOUNT_ID = '579275327561' + ECR_REPO_NAME = 'app01' + IMAGE_TAG = "${env.BUILD_ID}" } + steps { + withCredentials([[ + $class: 'AmazonWebServicesCredentialsBinding', + credentialsId: 'awsbeancreds', + accessKeyVariable: 'AWS_ACCESS_KEY_ID', + secretKeyVariable: 'AWS_SECRET_ACCESS_KEY' + ]]) { + sh """ + + apk add --no-cache aws-cli + + aws ecr get-login-password --region ${AWS_REGION} | docker login --username AWS --password-stdin ${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com + + docker build -t ${ECR_REPO_NAME}:${IMAGE_TAG} . + + docker tag ${ECR_REPO_NAME}:${IMAGE_TAG} ${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/${ECR_REPO_NAME}:${IMAGE_TAG} + docker tag ${ECR_REPO_NAME}:${IMAGE_TAG} ${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/${ECR_REPO_NAME}:latest + + docker push ${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/${ECR_REPO_NAME}:${IMAGE_TAG} + docker push ${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/${ECR_REPO_NAME}:latest + + docker rmi ${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/${ECR_REPO_NAME}:${IMAGE_TAG} + docker rmi ${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/${ECR_REPO_NAME}:latest - timeout(time: 10, unit: 'MINUTES') { - waitForQualityGate abortPipeline: true + docker rmi ${ECR_REPO_NAME}:${IMAGE_TAG} + """ + } } - } } + + - stage("Publish to Nexus Repository Manager") { + stage('Ansible Deploy to staging'){ + agent { + docker { + image 'alpine/ansible:latest' + args '-u root -v /etc/hosts:/etc/hosts' + } + } + environment { + NEXUS_SEC_PASS = credentials('nexuspass') + } steps { - script { - pom = readMavenPom file: "pom.xml"; - filesByGlob = findFiles(glob: "target/*.${pom.packaging}"); - echo "${filesByGlob[0].name} ${filesByGlob[0].path} ${filesByGlob[0].directory} ${filesByGlob[0].length} ${filesByGlob[0].lastModified}" - artifactPath = filesByGlob[0].path; - artifactExists = fileExists artifactPath; - if(artifactExists) { - echo "*** File: ${artifactPath}, group: ${pom.groupId}, packaging: ${pom.packaging}, version ${pom.version} ARTVERSION"; - nexusArtifactUploader( - nexusVersion: NEXUS_VERSION, - protocol: NEXUS_PROTOCOL, - nexusUrl: NEXUS_URL, - groupId: pom.groupId, - version: ARTVERSION, - repository: NEXUS_REPOSITORY, - credentialsId: NEXUS_CREDENTIAL_ID, - artifacts: [ - [artifactId: pom.artifactId, - classifier: '', - file: artifactPath, - type: pom.packaging], - [artifactId: pom.artifactId, - classifier: '', - file: "pom.xml", - type: "pom"] - ] - ); - } - else { - error "*** File: ${artifactPath}, could not be found"; - } + withCredentials([sshUserPrivateKey(credentialsId: 'bastion_login', keyFileVariable: 'SSH_KEY', usernameVariable: 'SSH_USER')]) { + sh """ + export HOME=${WORKSPACE} + export ANSIBLE_LOCAL_TEMP=${WORKSPACE}/.ansible/tmp + export ANSIBLE_REMOTE_TEMP=/tmp/.ansible/tmp + export ANSIBLE_HOST_KEY_CHECKING=False + + chmod 400 \${SSH_KEY} + + apk add --no-cache python3 py3-pip py3-boto3 py3-botocore + + ansible-galaxy collection install -r ansible/requirements.yml --collections-path \${WORKSPACE}/.ansible/collections --force + + echo "[defaults]" > ansible.cfg + echo "collections_paths = \${WORKSPACE}/.ansible/collections" >> ansible.cfg + + cat ansible.cfg + + echo "===== Available SSM Lookup Plugins =====" + ansible-doc -t lookup -l | grep ssm + + echo "===== Available AWS Plugins =====" + ansible-doc -t lookup -l | grep amazon + + ansible-playbook -i ansible/stage.inventory ansible/site.yml \ + --user=\${SSH_USER} \ + --private-key=\${SSH_KEY} \ + --extra-vars "image_tag_env=${env.BUILD_ID} ssh_key_path=\${SSH_KEY}" + """ } } } + } - + post { + always { + echo 'Slack Notifications.' + slackSend channel: '#jenkins-cicd', + color: COLOR_MAP[currentBuild.currentResult], + message: "*${currentBuild.currentResult}:* Job ${env.JOB_NAME} build ${env.BUILD_NUMBER} \n More info at: ${env.BUILD_URL}" + } } +} -} +// --extra-vars "USER=admin PASS=\${NEXUS_SEC_PASS} nexusip=172.31.40.75 reponame=vprofile-release groupid=QA time=${env.BUILD_TIMESTAMP} build=${env.BUILD_ID} artifactid=vproapp vprofile_version=vproapp-${env.BUILD_ID}-${env.BUILD_TIMESTAMP}.war" +// -Dsonar.java.binaries=target/test-classes/com/visualpathit/account/controllerTest/ \ No newline at end of file diff --git a/README.md b/README.md index 88fd3cbba..8d2d3cb07 100644 --- a/README.md +++ b/README.md @@ -1,25 +1,98 @@ -# Prerequisites -# -- JDK 11 -- Maven 3 -- MySQL 8 - -# Technologies -- Spring MVC -- Spring Security -- Spring Data JPA -- Maven -- JSP -- Tomcat -- MySQL -- Memcached -- Rabbitmq -- ElasticSearch -# Database -Here,we used Mysql DB -sql dump file: -- /src/main/resources/db_backup.sql -- db_backup.sql file is a mysql dump file.we have to import this dump to mysql db server -- > mysql -u -p accounts < db_backup.sql +# 🚀 Advanced Cloud Infrastructure & GitOps Engineering Portfolio +### +## 👨‍💻 About Me +A results-driven **DevOps Engineer** specializing in designing and orchestrating high-availability cloud infrastructure, secure cloud-native architectures, and robust automation frameworks. +This portfolio demonstrates an elite capability to operate across **hybrid ecosystems (Multi-CI/CD Engines, Multi-IaC Workflows, and Advanced Container Orchestration)**. Every architectural blueprint featured here is engineered to production-grade standards, prioritizing strict quality gates, zero-trust cloud security (DevSecOps), and absolute infrastructure repeatability. +--- + +## 🛠️ Core Technology Matrix +* **Cloud & Platforms:** AWS (VPC, EKS, ECS, Elastic Beanstalk, RDS, ECR, Route 53, CloudFront, EventBridge, Lambda) +* **Infrastructure as Code (IaC):** Terraform (Modular Designs, Remote State Locking, tfsec) +* **Configuration Management:** Ansible (Dynamic Inventories, Modular Roles, AWS Boto Automation) +* **Containerization & K8s:** Kubernetes (Ingress, PVC, EBS StorageClasses, Secrets), Docker, Docker Compose, Helm +* **CI/CD & GitOps:** GitLab CI, GitHub Actions, Jenkins, AWS CodePipeline (Build, Deploy) +* **DevSecOps & Quality:** SonarQube, SonarCloud, Trivy Container Scan, Checkstyle + +--- + +## 🏆 Featured Architectures (Primary Showcase) +*These core projects demonstrate my ability to architect and manage highly complex, multi-environment enterprise lifecycles with absolute precision.* + +### 1️⃣ Hybrid GitOps Infrastructure Automation (GitLab CI/CD & Amazon EKS) +* **The Challenge:** Enforcing zero-trust security and preventing configuration drift in cloud-native application delivery without storing permanent static cloud access keys. +* **The Solution:** Engineered a sophisticated dual-track GitOps pipeline within GitLab CI. The infrastructure pipeline utilizes Terraform with static security analysis via `tfsec` to provision an enterprise-grade AWS VPC and Amazon EKS cluster. The application delivery pipeline leverages OpenID Connect (OIDC) via AWS STS for temporary token exchange, runs automated unit tests, executes container vulnerability scans using `Trivy`, and automates application rollout into isolated worker node pools using Helm Charts. +* **Tech Stack:** GitLab CI/CD, Terraform, tfsec, Trivy, Amazon EKS, Helm, AWS ECR, OIDC. +* **Architecture Blueprint:** + ![GitLab CI EKS GitOps Pipeline](./images/GitOps%20with%20Github%20Actions.png) + +### 2️⃣ Unified Enterprise IaC & Configuration Management Framework (Jenkins & Ansible) +* **The Challenge:** Automating the structural provisioning and configuration execution gap between raw cloud infrastructure and environment node states for staging and production targets. +* **The Solution:** Built a unified provisioning engine. Terraform automates the delivery of a multi-AZ `vpro-vpc` managing scalable compute tiers inside Auto Scaling Groups backed by AWS RDS, RabbitMQ, and Memcached. Upon completion, a multi-stage Jenkins pipeline triggers an ephemeral Dockerized Ansible agent (`alpine/ansible`) to automatically establish secure SSH pipelines and apply precise configuration roles across separated staging and production workloads. +* **Tech Stack:** Jenkins, Terraform, Ansible, AWS VPC, Amazon RDS, Auto Scaling, Amazon ECR, SonarCloud, Slack. +* **Architecture Blueprint:** + ![Jenkins Ansible Enterprise Framework](./images/Continuous%20Delivery%20And%20Configuration%20Management%20Jenkins%2C%20Ansible%20plus%20Terraform.png) + +### 3️⃣ Multi-Track GitOps Application Delivery Lifecycle (GitHub Actions & ECS) +* **The Challenge:** Constructing a unified, low-latency workflow natively integrated into GitHub for rapid testing, security analysis, and container service deployments. +* **The Solution:** Formulated a declarative, matrix-based GitHub Actions workflow. Every code push initiates automated Maven testing and remote code quality scans inside SonarCloud. Validated code paths automatically trigger secure Docker multi-stage builds, pushing immutable container images into Amazon ECR registry buckets. The lifecycle concludes by executing progressive task definition adjustments across active Amazon ECS container tasks secured behind an Elastic Load Balancer (ELB). +* **Tech Stack:** GitHub Actions, Maven, SonarCloud, Docker, Amazon ECR, Amazon ECS, ELB. +* **Architecture Blueprint:** + ![GitHub Actions ECS Pipeline](./images/Github%20Actions%20for%20CICD.png) + +### 4️⃣ Serverless Cloud-Native CI/CD Pipeline (AWS CodePipeline) +* **The Challenge:** Abstracting pipeline computing infrastructure entirely using AWS native serverless options while maintaining high-velocity compilation and delivery. +* **The Solution:** Engineered an entirely serverless continuous delivery workflow on AWS. Triggered dynamically by source updates inside Bitbucket, AWS CodePipeline orchestrates isolated AWS CodeBuild execution nodes. These nodes pull specialized base container images from Amazon ECR to perform code compilation, dependency caching, and Sonar analysis, transferring artifacts securely via Amazon S3 to AWS CodeDeploy for automated rolling target updates. +* **Tech Stack:** AWS CodePipeline, CodeBuild, CodeDeploy, Amazon ECR, Amazon S3, Bitbucket. +* **Architecture Blueprint:** + ![AWS Native CodePipeline](./images/Continuous%20Delivery%20on%20AWS%20Cloud%20Java%20Application.png) + +--- + +## 🗄️ Project Archive (Complete Repository Index) +*Below is the extended ledger of core engineering frameworks and infrastructure topologies built to demonstrate specific technological focus areas.* + +
+📂 Expand Cloud Migration & Architecture Strategies + +### Lift-and-Shift Migration to AWS EC2 +* **Summary:** Transitioning a legacy multi-tier enterprise stack (Tomcat, MySQL, RabbitMQ, Memcached) into highly available, decoupled security zones behind an internet-facing Application Load Balancer. +* **Blueprint:** `![Architecture](./images/AWS%20Cloud%20for%20Web%20App%20Setup%20Lift%20%26%20Shift.png)` + +### Re-Architecting to Cloud-Native PaaS (Elastic Beanstalk) +* **Summary:** Eliminating localized single-point-of-failure risks by refactoring compute runtimes to AWS Elastic Beanstalk and migrating backend databases and caching layers to fully managed services (RDS, ElastiCache, Amazon MQ). +* **Blueprint:** `![Architecture](./images/Re-Architecting%20Web%20App%20on%20AWS%20Cloud%20Cloud%20Native.png)` +
+ +
+📂 Expand Infrastructure as Code (IaC) & Local Runtimes + +### Automated Multi-AZ VPC via Terraform +* **Summary:** Pure declarative scripting to erect isolated public and private subnet configurations across two availability zones, managing dynamic transit paths via AWS NAT Gateways. +* **Blueprint:** `![Architecture](./images/Terraform%20for%20Cloud%20State%20Management%201.png)` + +### Remote State Management & S3 Architecture +* **Summary:** Building secure, collaborative backend locks for enterprise state management using S3 backends paired with state mapping files. +* **Blueprint:** `![Architecture](./images/Terraform%20for%20Cloud%20State%20Management%202.png)` + +### Multi-Tier Polyglot Microservices Isolation (EMart App) +* **Summary:** Establishing an API Gateway architecture with Nginx to reverse-proxy decoupled multi-stack container ecosystems (Angular, NodeJS, MongoDB, Java). +* **Blueprint:** `![Architecture](./images/Containerization%20of%20Java%20project%20using%20Docker%20-%20Emart%20App.png)` +
+ +
+📂 Expand Kubernetes Orchestration & Core Pipelines + +### Production-Ready High-Availability Kubernetes Cluster +* **Summary:** Implementing path-based Nginx Ingress controllers, abstracting state security with K8s Secrets, and maintaining dynamic storage allocation via PersistentVolumeClaims (PVC) mapped to Amazon EBS. +* **Blueprint:** `![Architecture](./images/Java%20App%20Deployment%20on%20Kubernetes%20Cluster.png)` + +### Self-Hosted Enterprise CI Lifecycle (Jenkins & Quality Gates) +* **Summary:** Orchestrating complete quality gates featuring automated Checkstyle validations, SonarQube quality criteria tracking, and immutable asset artifact pushing to Sonatype Nexus repositories. +* **Blueprint:** `![Architecture](./images/Continuous%20Integration%20Using%20Jenkins%2C%20Nexus%2C%20Sonarqube%20%26%20Slack.png)` + +### Enterprise Full-Stack Automation via Ansible Roles +* **Summary:** Eliminating configuration divergence across complex multi-tier infrastructures using modular Ansible Roles and live dynamic AWS inventories. +* **Blueprint:** `![Architecture](./images/Ansible%20for%20Complete%20Stack%20Setup.jpg)` +
\ No newline at end of file diff --git a/ansible/Dockerfile b/ansible/Dockerfile new file mode 100644 index 000000000..e093d96c7 --- /dev/null +++ b/ansible/Dockerfile @@ -0,0 +1,8 @@ +FROM mysql:8.0 + +ENV MYSQL_ROOT_PASSWORD=admin123 +ENV MYSQL_DATABASE=accounts + +COPY ./db_backup.sql /docker-entrypoint-initdb.d/db_backup.sql + +EXPOSE 3306 \ No newline at end of file diff --git a/ansible/app-deploy.yml b/ansible/app-deploy.yml new file mode 100644 index 000000000..bbbbaadd1 --- /dev/null +++ b/ansible/app-deploy.yml @@ -0,0 +1,114 @@ +--- +- name: Deploy Docker Application from ECR (Simplified) + hosts: appsrvgrp + become: yes + + vars: + aws_region: "us-east-1" + ecr_registry: "579275327561.dkr.ecr.us-east-1.amazonaws.com" + ecr_repo_name: "app01" + image_tag: "{{ image_tag_env | default('latest') }}" + + tasks: + + - name: Install prerequisites for Docker + ansible.builtin.apt: + name: + - apt-transport-https + - ca-certificates + - curl + - gnupg + - lsb-release + - python3-pip + state: present + update_cache: yes + + - name: Add Docker GPG apt Key + ansible.builtin.apt_key: + url: https://download.docker.com/linux/ubuntu/gpg + state: present + + - name: Add Docker Repository + ansible.builtin.apt_repository: + repo: deb [arch=amd64] https://download.docker.com/linux/ubuntu {{ ansible_facts['distribution_release'] }} stable + state: present + + - name: Install Docker Engine + ansible.builtin.apt: + name: + - docker-ce + - docker-ce-cli + - containerd.io + state: present + update_cache: yes + + - name: Install Docker python module + ansible.builtin.pip: + name: docker + state: present + + - name: Ensure docker network 'vprof-net' exists + community.docker.docker_network: + name: vprof-net + state: present + + #----------------------------------------------------------------------------------------------------------- + + - name: Ensure aws-cli is installed + apt: + name: awscli + state: present + update_cache: yes + + - name: Login to AWS ECR + shell: "aws ecr get-login-password --region {{ aws_region }} | docker login --username AWS --password-stdin {{ ecr_registry }}" + changed_when: false + + - name: Pull Docker Image + shell: "docker pull {{ ecr_registry }}/{{ ecr_repo_name }}:{{ image_tag }}" + # نطلق الـ Handler فقط إذا تم سحب صورة جديدة أو تحديث جديد فعلياً + notify: Recreate application container + + - name: Read DB configuration from AWS SSM + ansible.builtin.set_fact: + db_url: "{{ lookup('amazon.aws.aws_ssm', '/vprofile/staging/db_url', region='us-east-1') }}" + db_user: "{{ lookup('amazon.aws.aws_ssm', '/vprofile/staging/db_user', region='us-east-1') }}" + db_pass: "{{ lookup('amazon.aws.aws_ssm', '/vprofile/staging/db_pass', region='us-east-1') }}" + rmq_user: "{{ lookup('amazon.aws.aws_ssm', '/vprofile/staging/rmq_user', region='us-east-1') }}" + rmq_pass: "{{ lookup('amazon.aws.aws_ssm', '/vprofile/staging/rmq_pass', region='us-east-1') }}" + + + - name: Run Application Docker Container with Env Variables + community.docker.docker_container: + name: vprofile-app + image: "{{ ecr_registry }}/{{ ecr_repo_name }}:{{ image_tag }}" + state: started + restart_policy: unless-stopped + network_mode: vprof-net + ports: + - "8080:8080" + env: + DB_URL: "{{ db_url }}" + DB_USER: "{{ db_user }}" + DB_PASS: "{{ db_pass }}" + RMQ_USER: "{{ rmq_user }}" + RMQ_PASS: "{{ rmq_pass }}" + +#======= الـ handlers هنا تبدأ من أول السطر بدون مسافات زائدة وتوازي قسم الـ tasks ======= + handlers: + - name: Recreate application container + community.docker.docker_container: + name: vprofile-app + image: "{{ ecr_registry }}/{{ ecr_repo_name }}:{{ image_tag }}" + state: started + recreate: yes + restart_policy: unless-stopped + network_mode: vprof-net + ports: + - "8080:8080" + env: + DB_URL: "{{ db_url }}" + DB_USER: "{{ db_user }}" + DB_PASS: "{{ db_pass }}" + RMQ_USER: "{{ rmq_user }}" + RMQ_PASS: "{{ rmq_pass }}" \ No newline at end of file diff --git a/ansible/app/Dockerfile b/ansible/app/Dockerfile new file mode 100644 index 000000000..460fdb0b5 --- /dev/null +++ b/ansible/app/Dockerfile @@ -0,0 +1,14 @@ +FROM maven:3-eclipse-temurin-17 AS build_image +RUN apt-get update && apt-get install -y git +WORKDIR /app +RUN git clone https://github.com/sadamaltoubasi/vprofile-project.git . +RUN git checkout cd-aws && mvn clean install + +FROM tomcat:10.1-jdk17-temurin + +RUN rm -rf /usr/local/tomcat/webapps/* + +COPY --from=build_image /app/target/vprofile-v2.war /usr/local/tomcat/webapps/ROOT.war + +EXPOSE 8080 +CMD ["catalina.sh", "run"] diff --git a/ansible/db-deploy.yml b/ansible/db-deploy.yml new file mode 100644 index 000000000..be967e096 --- /dev/null +++ b/ansible/db-deploy.yml @@ -0,0 +1,87 @@ +--- +- name: Deploy MySQL Database using Docker + hosts: dbsrvgrp + become: yes + vars: + project_path: "/opt/mysql-app" + + tasks: + + - name: Install prerequisites for Docker + ansible.builtin.apt: + name: + - apt-transport-https + - ca-certificates + - curl + - gnupg + - lsb-release + - python3-pip + state: present + update_cache: yes + + - name: Add Docker GPG apt Key + ansible.builtin.apt_key: + url: https://download.docker.com/linux/ubuntu/gpg + state: present + + - name: Add Docker Repository + ansible.builtin.apt_repository: + repo: deb [arch=amd64] https://download.docker.com/linux/ubuntu {{ ansible_facts['distribution_release'] }} stable + state: present + + - name: Install Docker Engine + ansible.builtin.apt: + name: + - docker-ce + - docker-ce-cli + - containerd.io + state: present + update_cache: yes + + - name: Install Docker python module + ansible.builtin.pip: + name: docker + state: present + + + #----------------------------------------------------------------------------------------------------------- + + - name: 1. Create project directory on target server + file: + path: "{{ project_path }}" + state: directory + mode: '0755' + + - name: 2. Copy Dockerfile to target server + copy: + src: ./Dockerfile + dest: "{{ project_path }}/Dockerfile" + + - name: Ensure docker network 'vprof-net' exists + community.docker.docker_network: + name: vprof-net + state: present + + - name: 3. Copy Database Backup file to target server + copy: + src: ./db_backup.sql + dest: "{{ project_path }}/db_backup.sql" + + - name: 4. Build Docker Image from Dockerfile + community.docker.docker_image: + build: + path: "{{ project_path }}" + name: db01 + tag: latest + source: build + + - name: 5. Run MySQL Docker Container + community.docker.docker_container: + name: db01 + image: db01:latest + state: started + restart_policy: unless-stopped + networks: + - name: vprof-net + ports: + - "3306:3306" \ No newline at end of file diff --git a/ansible/db_backup.sql b/ansible/db_backup.sql new file mode 100644 index 000000000..2f17a4df3 --- /dev/null +++ b/ansible/db_backup.sql @@ -0,0 +1,133 @@ +-- MySQL dump 10.13 Distrib 5.7.18, for Linux (x86_64) +-- +-- Host: localhost Database: accounts +-- ------------------------------------------------------ +-- Server version 5.7.18-0ubuntu0.16.10.1 + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8 */; +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; + +-- +-- Table structure for table `role` +-- + +DROP TABLE IF EXISTS `role`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `role` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(45) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `role` +-- + +LOCK TABLES `role` WRITE; +/*!40000 ALTER TABLE `role` DISABLE KEYS */; +INSERT INTO `role` VALUES (1,'ROLE_USER'); +/*!40000 ALTER TABLE `role` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `user` +-- + +DROP TABLE IF EXISTS `user`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `user` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `username` varchar(255) DEFAULT NULL, + `userEmail` varchar(255) DEFAULT NULL, + `profileImg` varchar(255) DEFAULT NULL, + `profileImgPath` varchar(255) DEFAULT NULL, + `dateOfBirth` varchar(255) DEFAULT NULL, + `fatherName` varchar(255) DEFAULT NULL, + `motherName` varchar(255) DEFAULT NULL, + `gender` varchar(255) DEFAULT NULL, + `maritalStatus` varchar(255) DEFAULT NULL, + `permanentAddress` varchar(255) DEFAULT NULL, + `tempAddress` varchar(255) DEFAULT NULL, + `primaryOccupation` varchar(255) DEFAULT NULL, + `secondaryOccupation` varchar(255) DEFAULT NULL, + `skills` varchar(255) DEFAULT NULL, + `phoneNumber` varchar(255) DEFAULT NULL, + `secondaryPhoneNumber` varchar(255) DEFAULT NULL, + `nationality` varchar(255) DEFAULT NULL, + `language` varchar(255) DEFAULT NULL, + `workingExperience` varchar(255) DEFAULT NULL, + `password` varchar(255) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `user` +-- + +LOCK TABLES `user` WRITE; +/*!40000 ALTER TABLE `user` DISABLE KEYS */; + +INSERT INTO `user` VALUES (7,'admin_vp','admin@hkhinfo.com',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'$2a$11$0a7VdTr4rfCQqtsvpng6GuJnzUmQ7gZiHXgzGPgm5hkRa3avXgBLK') +,(8,'Abrar Nirban','abrar.nirban74@gmail.com',NULL,NULL,'27/01/2002','A nirban','T nirban','male','unMarried','Dubai,UAE','Dubai,UAE','Software Engineer','Software Engineer','Java HTML CSS ','8888888888','8888888888','Indian','english','2 ','$2a$11$UgG9TkHcgl02LxlqxRHYhOf7Xv4CxFmFEgS0FpUdk42OeslI.6JAW'), +(9,'Amayra Fatima','amayra@gmail.com',NULL,NULL,'20/06/1993','K','L','female','unMarried','Dubai,UAE','Dubai,UAE','Software Engineer','Software Engineer','Java HTML CSS ','9999999999','9999999999','India','english','5','$2a$11$gwvsvUrFU.YirMM1Yb7NweFudLUM91AzH5BDFnhkNzfzpjG.FplYO'), +(10,'Aron','aron.DSilva@gmail.com',NULL,NULL,'27/01/2002','M nirban','R nirban','male','unMarried','Dubai,UAE','Dubai,UAE','Software Engineer','Software Engineer','Java HTML CSS ','7777777777','777777777','India','english','7','$2a$11$6oZEgfGGQAH23EaXLVZ2WOSKxcEJFnBSw2N2aghab0s2kcxSQwjhC'), +(11,'Kiran Kumar','kiran@gmail.com',NULL,NULL,'8/12/1993','K K','RK','male','unMarried','SanFrancisco','James Street','Software Engineer','Software Engineer','Java HTML CSS ','1010101010','1010101010','India','english','10','$2a$11$EXwpna1MlFFlKW5ut1iVi.AoeIulkPPmcOHFO8pOoQt1IYU9COU0m'), +(12,'Balbir Singh','balbir@gmail.com',NULL,NULL,'20/06/1993','balbir RK','balbir AK','male','unMarried','SanFrancisco','US','Software Engineer','Software Engineer','Java HTML CSS AWS','8888888111','8888888111','India','english','8','$2a$11$pzWNzzR.HUkHzz2zhAgqOeCl0WaTgY33NxxJ7n0l.rnEqjB9JO7vy'), +(4,'Hibo Prince','hibo.prince@gmail.com',NULL,NULL,'6/09/2000','Abara','Queen','male','unMarried','Electronic City,UAE','Electronic City,UAE','Tester','Freelancing','Python PHP ','9146389863','9146389871','Indian','hindi','3 ','$2a$11$UgG9TkHcgl02LxlqxRHYhOf7Xv4CxFmFEgS0FpUdk42OeslI.6JAR'), +(5,'Aejaaz Habeeb','aejaaz.habeeb@gmail.com',NULL,NULL,'16/02/2001','Imran','Ziya','male','unMarried','AbuDhabi,UAE','AbuDhabi,UAE','Developer','Developer','Azure Devops ','9566489863','9566489863','Indian','hindi','4 ','$2a$11$UgG9TkHcgl02LxlqxRHYhOf7Xv4CxFmFEgS0FpUdk42OeslI.6JAR'), +(6,'Jackie','jackie.chan@gmail.com',NULL,NULL,'28/09/1992','Charles','Chan','male','Married','HongKong,China','HongKong,China','MartialArtist','MartialArtist','KungFu ','9246488863','9246488863','Chinese','Mandrian','1 ','$2a$11$UgG9TkHcgl02LxlqxRHYhOf7Xv4CxFmFEgS0FpUdk42OeslI.6RAR'), +(13,'Srinath Goud','sgoud@gmail.com',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'$2a$11$6BSmYPrT8I8b9yHmx.uTRu/QxnQM2vhZYQa8mR33aReWA4WFihyGK'); + + +/*!40000 ALTER TABLE `user` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `user_role` +-- + +DROP TABLE IF EXISTS `user_role`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `user_role` ( + `user_id` int(11) NOT NULL, + `role_id` int(11) NOT NULL, + PRIMARY KEY (`user_id`,`role_id`), + KEY `fk_user_role_roleid_idx` (`role_id`), + CONSTRAINT `fk_user_role_roleid` FOREIGN KEY (`role_id`) REFERENCES `role` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `fk_user_role_userid` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `user_role` +-- + +LOCK TABLES `user_role` WRITE; +/*!40000 ALTER TABLE `user_role` DISABLE KEYS */; +INSERT INTO `user_role` VALUES (4,1),(5,1),(6,1),(7,1),(8,1),(9,1),(10,1),(11,1),(12,1),(13,1); +/*!40000 ALTER TABLE `user_role` ENABLE KEYS */; +UNLOCK TABLES; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; + +-- Dump completed on 2023-21-06 05:49:31 diff --git a/ansible/memcached.yml b/ansible/memcached.yml new file mode 100644 index 000000000..49e36bdbb --- /dev/null +++ b/ansible/memcached.yml @@ -0,0 +1,73 @@ +--- +- name: Deploy Memcached using Docker + hosts: mcsrvgrp + become: yes + + tasks: + - name: Install prerequisites for Docker + ansible.builtin.apt: + name: + - apt-transport-https + - ca-certificates + - curl + - gnupg + - lsb-release + - python3-pip + state: present + update_cache: yes + + - name: Add Docker GPG apt Key + ansible.builtin.apt_key: + url: https://download.docker.com/linux/ubuntu/gpg + state: present + + - name: Add Docker Repository + ansible.builtin.apt_repository: + repo: deb [arch=amd64] https://download.docker.com/linux/ubuntu {{ ansible_facts['distribution_release'] }} stable + state: present + + - name: Install Docker Engine + ansible.builtin.apt: + name: + - docker-ce + - docker-ce-cli + - containerd.io + state: present + update_cache: yes + + - name: Install Docker python module + ansible.builtin.pip: + name: docker + state: present + + - name: Ensure Docker service is running and enabled + ansible.builtin.systemd: + name: docker + state: started + enabled: yes + + #----------------------------------------------------------------------------------------------------------- + + - name: Ensure docker network 'vprof-net' exists + community.docker.docker_network: + name: vprof-net + state: present + + - name: Run memcache Docker Container + community.docker.docker_container: + name: mc01 + image: memcached:1.6-alpine + state: started + restart_policy: unless-stopped + network_mode: vprof-net + ports: + - "11211:11211" + notify: Restart memcached container + + handlers: + - name: Restart memcached container + community.docker.docker_container: + name: mc01 + image: memcached:1.6-alpine + state: started + restart: true diff --git a/ansible/prod-site.yml b/ansible/prod-site.yml new file mode 100644 index 000000000..d23c2fa5e --- /dev/null +++ b/ansible/prod-site.yml @@ -0,0 +1,3 @@ +--- +- import_playbook: app-deploy.yml +#### \ No newline at end of file diff --git a/ansible/prod.inventory b/ansible/prod.inventory new file mode 100644 index 000000000..6ca7ee230 --- /dev/null +++ b/ansible/prod.inventory @@ -0,0 +1,7 @@ +[all:vars] + +ansible_ssh_common_args='-o ProxyCommand="ssh -o StrictHostKeyChecking=no -i {{ ssh_key_path }} -W %h:%p -q ubuntu@44.203.162.75"' + + +[appsrvgrp] +10.0.2.13 diff --git a/ansible/rabbitmq.yml b/ansible/rabbitmq.yml new file mode 100644 index 000000000..5fb70fa34 --- /dev/null +++ b/ansible/rabbitmq.yml @@ -0,0 +1,94 @@ +--- +- name: Deploy RabbitMQ Container using Docker + hosts: rmqsrvgrp + become: yes + tasks: + + - name: Install prerequisites for Docker + ansible.builtin.apt: + name: + - apt-transport-https + - ca-certificates + - curl + - gnupg + - lsb-release + - python3-pip + state: present + update_cache: yes + + - name: Add Docker GPG apt Key + ansible.builtin.apt_key: + url: https://download.docker.com/linux/ubuntu/gpg + state: present + + - name: Add Docker Repository + ansible.builtin.apt_repository: + repo: deb [arch=amd64] https://download.docker.com/linux/ubuntu {{ ansible_facts['distribution_release'] }} stable + state: present + + - name: Install Docker Engine + ansible.builtin.apt: + name: + - docker-ce + - docker-ce-cli + - containerd.io + state: present + update_cache: yes + + - name: Install Docker python module + ansible.builtin.pip: + name: docker + state: present + + + #----------------------------------------------------------------------------------------------------------- + + - name: Ensure python3-docker is installed (Required for Ansible docker module) + apt: + name: python3-docker + state: present + update_cache: yes + when: ansible_os_family == "Debian" + + - name: Ensure docker network 'vprof-net' exists + community.docker.docker_network: + name: vprof-net + state: present + + + - name: Read RabbitMQ configuration from AWS SSM + ansible.builtin.set_fact: + rmq_user: "{{ lookup('amazon.aws.aws_ssm', '/vprofile/staging/rmq_user', region='us-east-1') }}" + rmq_pass: "{{ lookup('amazon.aws.aws_ssm', '/vprofile/staging/rmq_pass', region='us-east-1') }}" + + + - name: Run RabbitMQ Management Container + community.docker.docker_container: + name: rmq01 + image: rabbitmq:3-management-alpine + state: started + restart_policy: unless-stopped + network_mode: vprof-net + ports: + - "5672:5672" + - "15672:15672" + env: + RABBITMQ_DEFAULT_USER: "{{ rmq_user }}" + RABBITMQ_DEFAULT_PASS: "{{ rmq_pass }}" + notify: Restart rabbitmq container + + handlers: + - name: Restart rabbitmq container + community.docker.docker_container: + name: rmq01 + image: rabbitmq:3-management-alpine + state: started + restart: true + network_mode: vprof-net + ports: + - "5672:5672" + - "15672:15672" + env: + RABBITMQ_DEFAULT_USER: "{{ rmq_user }}" + RABBITMQ_DEFAULT_PASS: "{{ rmq_pass }}" + diff --git a/ansible/requirements.yml b/ansible/requirements.yml new file mode 100644 index 000000000..3be4cfd4e --- /dev/null +++ b/ansible/requirements.yml @@ -0,0 +1,3 @@ +collections: + - name: amazon.aws + - name: community.docker \ No newline at end of file diff --git a/ansible/site.yml b/ansible/site.yml index 59aebc9bf..1304c4f8f 100644 --- a/ansible/site.yml +++ b/ansible/site.yml @@ -1,5 +1,6 @@ --- -- import_playbook: tomcat_setup.yml -- import_playbook: vpro-app-setup.yml - +- import_playbook: memcached.yml +- import_playbook: db-deploy.yml +- import_playbook: rabbitmq.yml +- import_playbook: app-deploy.yml #### diff --git a/ansible/stage.inventory b/ansible/stage.inventory new file mode 100644 index 000000000..c2cdc0eca --- /dev/null +++ b/ansible/stage.inventory @@ -0,0 +1,12 @@ +[all:vars] + +ansible_ssh_common_args='-o ProxyCommand="ssh -o StrictHostKeyChecking=no -i {{ ssh_key_path }} -W %h:%p -q ubuntu@44.203.162.75"' + +[rmqsrvgrp] +10.0.1.195 + +[mcsrvgrp] +10.0.1.178 + +[appsrvgrp] +10.0.2.62 diff --git a/ansible/tomcat_setup.yml b/ansible/tomcat_setup.yml deleted file mode 100644 index 66dff8904..000000000 --- a/ansible/tomcat_setup.yml +++ /dev/null @@ -1,113 +0,0 @@ -- name: Common tool setup on all the servers - hosts: appsrvgrp - become: yes - vars: - tom_url: https://archive.apache.org/dist/tomcat/tomcat-8/v8.5.37/bin/apache-tomcat-8.5.37.tar.gz - - tasks: - - name: Install JDK on Centos 6/7 - yum: - name: java-1.8.0-openjdk.x86_64 - state: present - when: ansible_distribution == 'CentOS' - - - name: Install JDK on Ubuntu 14/15/16/18 - apt: - name: openjdk-8-jdk - state: present - update_cache: yes - when: ansible_distribution == 'Ubuntu' - - - name: Download Tomcat Tar Ball/Binaries - get_url: - url: "{{tom_url}}" - dest: /tmp/tomcat-8.tar.gz - - - name: Add tomcat group - group: - name: tomcat - state: present - - - name: Add tomcat user - user: - name: tomcat - group: tomcat - shell: /bin/nologin - home: /usr/local/tomcat8 - - - file: - path: /tmp/tomcat8 - state: directory - - - name: Extract tomcat - unarchive: - src: /tmp/tomcat-8.tar.gz - dest: /tmp/tomcat8/ - remote_src: yes - list_files: yes - register: unarchive_info - - - debug: - msg: "{{unarchive_info.files[0].split('/')[0]}}" - - - name: Synchronize /tmp/tomcat8/tomcat_cont /usr/local/tomcat8. - synchronize: - src: "/tmp/tomcat8/{{unarchive_info.files[0].split('/')[0]}}/" - dest: /usr/local/tomcat8/ - delegate_to: "{{ inventory_hostname }}" - - - name: Change ownership of /usr/local/tomcat8 - file: - path: /usr/local/tomcat8 - owner: tomcat - group: tomcat - recurse: yes - - - name: Setup tomcat SVC file on Centos 7 - template: - src: templates/epel7-svcfile.j2 - dest: /etc/systemd/system/tomcat.service - mode: "a+x" - when: ansible_distribution == 'CentOS' and ansible_distribution_major_version == '7' - - - name: Setup tomcat SVC file on Centos 6 - template: - src: templates/epel6-svcfile.j2 - dest: /etc/init.d/tomcat - mode: "a+x" - when: ansible_distribution == 'CentOS' and ansible_distribution_major_version == '6' - - - name: Setup tomcat SVC file on ubuntu 14/15 - template: - src: templates/ubuntu14_15-svcfile.j2 - dest: /etc/init.d/tomcat - mode: "a+x" - when: ansible_distribution == 'Ubuntu' and ansible_distribution_major_version < '16' - - - name: Setup tomcat SVC file on ubuntu 16 and 18 - template: - src: templates/ubuntu16-svcfile.j2 - dest: /etc/systemd/system/tomcat.service - mode: "a+x" - when: ansible_distribution == 'Ubuntu' and ansible_distribution_major_version >= '16' - - - name: Reload tomcat svc config in ubuntu 14/15 - command: update-rc.d tomcat defaults - when: ansible_distribution == 'Ubuntu' and ansible_distribution_major_version < '16' - - - name: Reload tomcat svc config in Centos 6 - command: chkconfig --add tomcat - when: ansible_distribution == 'CentOS' and ansible_distribution_major_version == '6' - - - name: just force systemd to reread configs (2.4 and above) - systemd: - daemon_reload: yes - when: ansible_distribution_major_version > '6' or ansible_distribution_major_version > '15' - - - name: Start & Enable TOmcat 8 - service: - name: tomcat - state: started - enabled: yes - - diff --git a/ansible/vpro-app-setup.yml b/ansible/vpro-app-setup.yml deleted file mode 100644 index 0c3f5d4a5..000000000 --- a/ansible/vpro-app-setup.yml +++ /dev/null @@ -1,105 +0,0 @@ - -- name: Setup Tomcat8 & Deploy Artifact - hosts: appsrvgrp - become: yes - vars: - timestamp: "{{ansible_date_time.date}}_{{ansible_date_time.hour}}_{{ansible_date_time.minute}}" - tasks: - - name: Download latest VProfile.war from nexus - get_url: - url: "http://{{USER}}:{{PASS}}@{{nexusip}}:8081/repository/{{reponame}}/{{groupid}}/{{time}}/{{build}}/{{vprofile_version}}" - dest: "/tmp/vproapp-{{vprofile_version}}" - register: wardeploy - tags: - - deploy - - - stat: - path: /usr/local/tomcat8/webapps/ROOT - register: artifact_stat - tags: - - deploy - - - name: Stop tomcat svc - service: - name: tomcat - state: stopped - tags: - - deploy - - - name: Try Backup and Deploy - block: - - name: Archive ROOT dir with timestamp - archive: - path: /usr/local/tomcat8/webapps/ROOT - dest: "/opt/ROOT_{{timestamp}}.tgz" - when: artifact_stat.stat.exists - register: archive_info - tags: - - deploy - - - name: copy ROOT dir with old_ROOT name - shell: cp -r ROOT old_ROOT - args: - chdir: /usr/local/tomcat8/webapps/ - - - name: Delete current artifact - file: - path: "{{item}}" - state: absent - when: archive_info.changed - loop: - - /usr/local/tomcat8/webapps/ROOT - - /usr/local/tomcat8/webapps/ROOT.war - tags: - - deploy - - - name: Try deploy artifact else restore from previos old_ROOT - block: - - name: Deploy vprofile artifact - copy: - src: "/tmp/vproapp-{{vprofile_version}}" - dest: /usr/local/tomcat8/webapps/ROOT.war - remote_src: yes - register: deploy_info - tags: - - deploy - rescue: - - shell: cp -r old_ROOT ROOT - args: - chdir: /usr/local/tomcat8/webapps/ - - rescue: - - name: Start tomcat svc - service: - name: tomcat - state: started - - - name: Start tomcat svc - service: - name: tomcat - state: started - when: deploy_info.changed - tags: - - deploy - - - name: Wait until ROOT.war is extracted to ROOT directory - wait_for: - path: /usr/local/tomcat8/webapps/ROOT - tags: - - deploy - -# - name: Deploy web configuration file -# template: -# src: templates/application.j2 -# dest: /usr/local/tomcat8/webapps/ROOT/WEB-INF/classes/application.properties -# force: yes -# notify: -# - Restart Tomcat -# tags: -# - deploy - - handlers: - - name: Restart Tomcat - service: - name: tomcat - state: restarted diff --git a/ansible/vpro_stage.yml b/ansible/vpro_stage.yml new file mode 100644 index 000000000..1146f8b7f --- /dev/null +++ b/ansible/vpro_stage.yml @@ -0,0 +1,80 @@ +--- +- name: Build and Deploy vProfile Application using Docker + hosts: appsrvgrp + become: yes + vars: + app_dir: "/opt/app" + + tasks: + + - name: Install prerequisites for Docker + ansible.builtin.apt: + name: + - apt-transport-https + - ca-certificates + - curl + - gnupg + - lsb-release + - python3-pip + state: present + update_cache: yes + + - name: Add Docker GPG apt Key + ansible.builtin.apt_key: + url: https://download.docker.com/linux/ubuntu/gpg + state: present + + - name: Add Docker Repository + ansible.builtin.apt_repository: + repo: deb [arch=amd64] https://download.docker.com/linux/ubuntu {{ ansible_facts['distribution_release'] }} stable + state: present + + - name: Install Docker Engine + ansible.builtin.apt: + name: + - docker-ce + - docker-ce-cli + - containerd.io + state: present + update_cache: yes + + - name: Install Docker python module + ansible.builtin.pip: + name: docker + state: present + + #----------------------------------------------------------------------------------------------------------- + + - name: Ensure application directory exists + file: + path: "{{ app_dir }}" + state: directory + mode: '0755' + + - name: Copy Dockerfile to the server + copy: + src: ./app/Dockerfile + dest: "{{ app_dir }}/Dockerfile" + + - name: Ensure docker network 'vprof-net' exists + community.docker.docker_network: + name: vprof-net + state: present + + - name: Build Docker Image from Dockerfile + community.docker.docker_image: + build: + path: "{{ app_dir }}" + name: app01 + tag: latest + source: build + + - name: Run Tomcat 10 Application Container within vprof-net + community.docker.docker_container: + name: app01 + image: app01:latest + state: started + restart_policy: unless-stopped + network_mode: vprof-net + ports: + - "8080:8080" \ No newline at end of file diff --git a/pom.xml b/pom.xml index 03bba333b..4a8ab605a 100644 --- a/pom.xml +++ b/pom.xml @@ -1,5 +1,7 @@ - + + 4.0.0 com.visualpathit vprofile @@ -7,82 +9,148 @@ v2 Visualpathit VProfile Webapp http://maven.apache.org + - 4.2.0.RELEASE - 4.0.2.RELEASE - 1.8.2.RELEASE - 4.3.11.Final - 5.2.1.Final - 8.0.32 - 1.4 - 1.2 - 4.10 - 1.1.3 - 1.8 - 1.8 + 6.0.11 + 3.1.3 + 6.1.2 + 3.1.2 + 7.0.0.Alpha3 + 6.2.0.Final + 8.0.33 + 2.12.0 + + 4.13.2 + 1.5.6 + 17 + 17 + + org.springframework spring-web ${spring.version} - org.springframework spring-webmvc ${spring.version} - + org.springframework.security spring-security-web ${spring-security.version} - org.springframework.security spring-security-config ${spring-security.version} - - - org.hibernate - hibernate-validator - ${hibernate-validator.version} - - org.springframework.data spring-data-jpa ${spring-data-jpa.version} - org.hibernate - hibernate-entitymanager + hibernate-validator + ${hibernate-validator.version} + + + org.hibernate.orm + hibernate-core ${hibernate.version} + + org.springframework + spring-orm + ${spring.version} + + + org.springframework + spring-tx + ${spring.version} + + + org.springframework + spring-context + ${spring.version} + + + org.elasticsearch.client + elasticsearch-rest-high-level-client + 7.10.2 + + + org.elasticsearch + elasticsearch + 7.10.2 + + + org.springframework.amqp + spring-rabbit + 3.1.6 + + + com.rabbitmq + amqp-client + 5.21.0 + + + net.spy + spymemcached + 2.12.3 + + mysql mysql-connector-java ${mysql-connector.version} + - commons-dbcp - commons-dbcp - ${commons-dbcp.version} + jakarta.servlet + jakarta.servlet-api + 6.1.0 + provided - - javax.servlet - jstl - ${jstl.version} + jakarta.persistence + jakarta.persistence-api + 3.2.0 + + + jakarta.platform + jakarta.jakartaee-api + 10.0.0 + provided + + + org.springframework.boot + spring-boot-starter-test + ${spring-boot.version} + test + + + org.mockito + mockito-core + 5.5.0 + test + + + org.mockito + mockito-junit-jupiter + 5.5.0 + test + junit junit @@ -90,122 +158,149 @@ test - org.mockito - mockito-core - 1.9.5 + org.junit.jupiter + junit-jupiter-engine + 5.10.0 test - - - org.springframework - spring-test - 3.2.3.RELEASE - test - - - javax.servlet - javax.servlet-api - 3.1.0 - provided - + + + org.junit.jupiter + junit-jupiter-api + 5.10.0 + test + + + org.springframework + spring-test + ${spring.version} + test + ch.qos.logback logback-classic ${logback.version} - org.hamcrest - hamcrest-all - 1.3 - test - - - commons-fileupload - commons-fileupload - 1.3.1 - - - - net.spy - spymemcached - 2.12.3 - - - commons-io - commons-io - 2.4 - - - - org.springframework.amqp - spring-rabbit - 1.7.1.RELEASE - - - - com.rabbitmq - amqp-client - 4.0.2 - - - - org.elasticsearch - elasticsearch - 5.6.4 - - - - org.elasticsearch.client - transport - 5.6.4 - - - - com.google.code.gson - gson - 2.8.2 - + org.hamcrest + hamcrest-all + 1.3 + test + + + + + org.apache.logging.log4j + log4j-api + 2.23.1 + + + org.apache.logging.log4j + log4j-core + 2.20.0 + + + org.apache.logging.log4j + log4j-slf4j-impl + 2.20.0 + + + + commons-fileupload + commons-fileupload + 1.4 + + + commons-io + commons-io + 2.11.0 + + + org.apache.commons + commons-dbcp2 + 2.12.0 + + + org.elasticsearch.plugin + aggs-matrix-stats-client + 7.10.2 + + + com.fasterxml.jackson.core + jackson-databind + 2.13.0 + + + + org.springframework + spring-messaging + ${spring.version} + + + + jakarta.servlet.jsp.jstl + jakarta.servlet.jsp.jstl-api + 2.0.0 + + + + + org.glassfish.web + jakarta.servlet.jsp.jstl + 2.0.0 + + - + + + + org.eclipse.jetty jetty-maven-plugin - 9.2.11.v20150529 + 11.0.15 - 10 / - - - org.apache.maven.plugins - maven-war-plugin - 3.2.2 - - - org.jacoco - jacoco-maven-plugin - 0.8.4 - - - jacoco-initialize - process-resources - - prepare-agent - - - - jacoco-site - post-integration-test - - report - - - - - + + + + org.apache.maven.plugins + maven-war-plugin + 3.4.0 + + + + org.jacoco + jacoco-maven-plugin + 0.8.10 + + + jacoco-initialize + process-resources + + prepare-agent + + + + jacoco-site + post-integration-test + + report + + + + + + + codeartifact + codeartifact + https://vpro-maven-579275327561.d.codeartifact.us-east-1.amazonaws.com/maven/maven-central-store/ + + diff --git a/settings.xml b/settings.xml new file mode 100644 index 000000000..02fd9e773 --- /dev/null +++ b/settings.xml @@ -0,0 +1,34 @@ + + + + + codeartifact + aws + ${env.CODEARTIFACT_AUTH_TOKEN} + + + + + default + + + codeartifact + https://vpro-maven-579275327561.d.codeartifact.us-east-1.amazonaws.com/maven/maven-central-store/ + + + + + + default + + + + codeartifact + domainname--maven-central-store + https://vpro-maven-579275327561.d.codeartifact.us-east-1.amazonaws.com/maven/maven-central-store/ + * + + + diff --git a/src/main/java/com/visualpathit/account/AuthenticationFailureHandler.java b/src/main/java/com/visualpathit/account/AuthenticationFailureHandler.java new file mode 100644 index 000000000..48e40515c --- /dev/null +++ b/src/main/java/com/visualpathit/account/AuthenticationFailureHandler.java @@ -0,0 +1,18 @@ +package com.visualpathit.account; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler; + +import java.io.IOException; + +public class AuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler { + + @Override + public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, + AuthenticationException exception) throws IOException { + // Redirect to custom error page + getRedirectStrategy().sendRedirect(request, response, "/login?error"); + } +} diff --git a/src/main/java/com/visualpathit/account/GlobalExceptionHandler.java b/src/main/java/com/visualpathit/account/GlobalExceptionHandler.java new file mode 100644 index 000000000..321575a2e --- /dev/null +++ b/src/main/java/com/visualpathit/account/GlobalExceptionHandler.java @@ -0,0 +1,28 @@ +package com.visualpathit.account; + +import jakarta.servlet.http.HttpServletRequest; +import org.springframework.security.authentication.BadCredentialsException; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; + +@ControllerAdvice +public class GlobalExceptionHandler { + + @ExceptionHandler(UserNotFoundException.class) + public String handleUserNotFoundException(UserNotFoundException ex, HttpServletRequest request) { + request.setAttribute("errorMessage", ex.getMessage()); + return "forward:/WEB-INF/views/error/404.jsp"; + } + + @ExceptionHandler(BadCredentialsException.class) + public String handleBadCredentialsException(BadCredentialsException ex, HttpServletRequest request) { + request.setAttribute("errorMessage", "Invalid username or password."); + return "forward:/WEB-INF/views/error/500.jsp"; // You can choose a different page for BadCredentialsException if preferred + } + + @ExceptionHandler(Exception.class) + public String handleGenericException(Exception ex, HttpServletRequest request) { + request.setAttribute("errorMessage", "An unexpected error occurred. Please try again later."); + return "forward:/WEB-INF/views/error/500.jsp"; + } +} diff --git a/src/main/java/com/visualpathit/account/UserNotFoundException.java b/src/main/java/com/visualpathit/account/UserNotFoundException.java new file mode 100644 index 000000000..1601a7f28 --- /dev/null +++ b/src/main/java/com/visualpathit/account/UserNotFoundException.java @@ -0,0 +1,7 @@ +package com.visualpathit.account; + +public class UserNotFoundException extends RuntimeException { + public UserNotFoundException(String message) { + super(message); + } +} diff --git a/src/main/java/com/visualpathit/account/controller/ElasticSearchController.java b/src/main/java/com/visualpathit/account/controller/ElasticSearchController.java index 6fe7f4104..bb321cb7f 100644 --- a/src/main/java/com/visualpathit/account/controller/ElasticSearchController.java +++ b/src/main/java/com/visualpathit/account/controller/ElasticSearchController.java @@ -2,137 +2,105 @@ import java.io.IOException; import java.util.List; -import java.util.Map; -import java.util.concurrent.ExecutionException; -import org.elasticsearch.action.admin.indices.create.CreateIndexRequestBuilder; +import org.apache.http.HttpHost; +import org.elasticsearch.action.delete.DeleteRequest; import org.elasticsearch.action.delete.DeleteResponse; +import org.elasticsearch.action.get.GetRequest; import org.elasticsearch.action.get.GetResponse; import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.action.index.IndexResponse; import org.elasticsearch.action.update.UpdateRequest; import org.elasticsearch.action.update.UpdateResponse; +import org.elasticsearch.client.RequestOptions; +import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.common.xcontent.XContentBuilder; +import org.elasticsearch.common.xcontent.XContentFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.ResponseBody; -import com.google.gson.Gson; import com.visualpathit.account.model.User; import com.visualpathit.account.service.UserService; import com.visualpathit.account.utils.ElasticsearchUtil; -import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder; - @Controller public class ElasticSearchController { - @Autowired + + @Autowired private UserService userService; - - @RequestMapping(value="/user/elasticsearch", method=RequestMethod.GET) + + @RequestMapping(value = "/user/elasticsearch", method = RequestMethod.GET) public String insert(final Model model) throws IOException { - List users = userService.getList(); - //contextMapping(); - - /* for (User user : users) { - //IndexRequest indexRequest = new IndexRequest("users","user", String.valueOf(user.getId())); - //indexRequest.source(new Gson().toJson(user)); - //IndexResponse response = ElasticsearchUtil.trannsportClient().index(indexRequest).actionGet(); - System.out.println("User" +new Gson().toJson(user)); - }*/ - String result =""; - for (User user : users) { - IndexResponse response = ElasticsearchUtil.trannsportClient().prepareIndex("users","user", String.valueOf(user.getId())) - .setSource(jsonBuilder() - .startObject() - .field("name", user.getUsername()) - .field("DOB",user.getDateOfBirth()) - .field("fatherName",user.getFatherName()) - .field("motherName",user.getMotherName()) - .field("gender",user.getGender()) - .field("nationality",user.getNationality()) - .field("phoneNumber", user.getPhoneNumber()) - .endObject() - ) - .get(); - String res =response.getResult().toString(); - System.out.println(res); - result="Users"; - } - model.addAttribute(result); + List users = userService.getList(); + + try (RestHighLevelClient client = ElasticsearchUtil.getRestHighLevelClient()) { + for (User user : users) { + IndexRequest indexRequest = new IndexRequest("users", "_doc", String.valueOf(user.getId())) + .source(XContentFactory.jsonBuilder() + .startObject() + .field("name", user.getUsername()) + .field("DOB", user.getDateOfBirth()) + .field("fatherName", user.getFatherName()) + .field("motherName", user.getMotherName()) + .field("gender", user.getGender()) + .field("nationality", user.getNationality()) + .field("phoneNumber", user.getPhoneNumber()) + .endObject()); + + IndexResponse response = client.index(indexRequest, RequestOptions.DEFAULT); + String res = response.getResult().toString(); + System.out.println(res); + } + } + + model.addAttribute("result", "Users indexed successfully"); return "elasticeSearchRes"; - } - @RequestMapping(value="/rest/users/view/{id}", method=RequestMethod.GET) - public String view(@PathVariable final String id,final Model model) { - GetResponse getResponse = ElasticsearchUtil.trannsportClient().prepareGet("users", "user", id).get(); - System.out.println(getResponse.getSource()); - - model.addAttribute("res", getResponse.getSource().get("name")); - + @RequestMapping(value = "/rest/users/view/{id}", method = RequestMethod.GET) + public String view(@PathVariable final String id, final Model model) throws IOException { + try (RestHighLevelClient client = ElasticsearchUtil.getRestHighLevelClient()) { + GetRequest getRequest = new GetRequest("users", "_doc", id); + GetResponse getResponse = client.get(getRequest, RequestOptions.DEFAULT); + + System.out.println(getResponse.getSourceAsString()); + model.addAttribute("res", getResponse.getSource().get("name")); + } + return "elasticeSearchRes"; } - /*@RequestMapping(value = "/get_user_list", method = RequestMethod.GET) - public @ResponseBody List getTagList(@RequestParam("term") String query) { - List users = userService.getList(); - List tagList = null; - for (User user : users) { - GetResponse getResponse = ElasticsearchUtil.trannsportClient().prepareGet("users", "user" ,String.valueOf(user.getId())).get(); - System.out.println(getResponse.getSource()); - - tagList.add(getResponse.getSource()); - } - return tagList; - }*/ - - @RequestMapping(value="/rest/users/update/{id}", method=RequestMethod.GET) - public String update(@PathVariable final String id,final Model model) throws IOException { - - UpdateRequest updateRequest = new UpdateRequest(); - updateRequest.index("employee") - .type("id") - .id(id) - .doc(jsonBuilder() - .startObject() - .field("gender", "male") - .endObject()); - try { - UpdateResponse updateResponse = ElasticsearchUtil.trannsportClient().update(updateRequest).get(); + + @RequestMapping(value = "/rest/users/update/{id}", method = RequestMethod.GET) + public String update(@PathVariable final String id, final Model model) throws IOException { + try (RestHighLevelClient client = ElasticsearchUtil.getRestHighLevelClient()) { + UpdateRequest updateRequest = new UpdateRequest("users", "_doc", id) + .doc(XContentFactory.jsonBuilder() + .startObject() + .field("gender", "male") + .endObject()); + + UpdateResponse updateResponse = client.update(updateRequest, RequestOptions.DEFAULT); System.out.println(updateResponse.status()); model.addAttribute("res", updateResponse.status()); - return "elasticeSearchRes"; - } catch (InterruptedException | ExecutionException e) { - System.out.println(e); } + return "elasticeSearchRes"; } - @RequestMapping(value="/rest/users/delete/{id}", method=RequestMethod.GET) - public String delete(@PathVariable final String id,final Model model) { - DeleteResponse deleteResponse =ElasticsearchUtil.trannsportClient().prepareDelete("employee", "id", id).get(); - System.out.println(deleteResponse.getResult().toString()); - model.addAttribute("res", deleteResponse.getResult().toString()); + @RequestMapping(value = "/rest/users/delete/{id}", method = RequestMethod.GET) + public String delete(@PathVariable final String id, final Model model) throws IOException { + try (RestHighLevelClient client = ElasticsearchUtil.getRestHighLevelClient()) { + DeleteRequest deleteRequest = new DeleteRequest("users", "_doc", id); + DeleteResponse deleteResponse = client.delete(deleteRequest, RequestOptions.DEFAULT); + + System.out.println(deleteResponse.getResult().toString()); + model.addAttribute("res", deleteResponse.getResult().toString()); + } + return "elasticeSearchRes"; } - /*public void contextMapping() throws IOException{ - String json ="{" - + "\"mappings\":{" - + "\"users\":\" {" - + "\"properties\" : {" - + "\"name\" : { \"type\" : \"string\" }," - + " \"city\" : { \"type\" : \"string\" }," - + "\"name_suggest\" : {" - + "\"type\" : \"completion\"" - + "}}" - + "}"; - IndexResponse response = ElasticsearchUtil.trannsportClient().prepareIndex("users", "data") - .setSource(json).execute().actionGet(); - - }*/ } diff --git a/src/main/java/com/visualpathit/account/controller/RabbitMqController.java b/src/main/java/com/visualpathit/account/controller/RabbitMqController.java new file mode 100644 index 000000000..7ce311c4c --- /dev/null +++ b/src/main/java/com/visualpathit/account/controller/RabbitMqController.java @@ -0,0 +1,51 @@ +package com.visualpathit.account.controller; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.servlet.ModelAndView; + +import com.rabbitmq.client.Connection; +import com.rabbitmq.client.ConnectionFactory; +import com.visualpathit.account.utils.RabbitMqUtil; + +import java.io.IOException; +import java.util.concurrent.TimeoutException; + +@Controller +public class RabbitMqController { + + @Autowired + private RabbitMqUtil rabbitMqUtil; + + @GetMapping("/user/rabbit") + public ModelAndView checkRabbitMqStatus() { + ModelAndView modelAndView = new ModelAndView(); + ConnectionFactory factory = new ConnectionFactory(); + factory.setHost(RabbitMqUtil.getRabbitMqHost()); + factory.setPort(Integer.parseInt(RabbitMqUtil.getRabbitMqPort())); + factory.setUsername(RabbitMqUtil.getRabbitMqUser()); + factory.setPassword(RabbitMqUtil.getRabbitMqPassword()); + + Connection connection = null; + try { + connection = factory.newConnection(); + if (connection.isOpen()) { + modelAndView.setViewName("rabbitmq"); + } else { + modelAndView.setViewName("rabbitmq-error"); + } + } catch (IOException | TimeoutException e) { + modelAndView.setViewName("rabbitmq-error"); + } finally { + if (connection != null) { + try { + connection.close(); + } catch (IOException e) { + // Log the exception if needed + } + } + } + return modelAndView; + } +} diff --git a/src/main/java/com/visualpathit/account/controller/UserController.java b/src/main/java/com/visualpathit/account/controller/UserController.java index c370682e2..f57988dd8 100644 --- a/src/main/java/com/visualpathit/account/controller/UserController.java +++ b/src/main/java/com/visualpathit/account/controller/UserController.java @@ -6,21 +6,19 @@ import com.visualpathit.account.service.UserService; import com.visualpathit.account.utils.MemcachedUtils; import com.visualpathit.account.validator.UserValidator; - -import java.util.List; -import java.util.UUID; - import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.validation.BindingResult; -import org.springframework.web.bind.annotation.ModelAttribute; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -/**{@author imrant}*/ +import org.springframework.web.bind.annotation.*; + +import javax.validation.Valid; +import java.util.List; +import java.util.UUID; + @Controller public class UserController { + @Autowired private UserService userService; @@ -29,146 +27,139 @@ public class UserController { @Autowired private UserValidator userValidator; - + @Autowired private ProducerService producerService; - - /** {@inheritDoc} */ - @RequestMapping(value = "/registration", method = RequestMethod.GET) - public final String registration(final Model model) { + + @GetMapping("/registration") + public String registration(Model model) { model.addAttribute("userForm", new User()); - return "registration"; - } - /** {@inheritDoc} */ - @RequestMapping(value = "/registration", method = RequestMethod.POST) - public final String registration(final @ModelAttribute("userForm") User userForm, - final BindingResult bindingResult, final Model model) { - + return "registration"; + } + + @PostMapping("/registration") + public String registration(@ModelAttribute("userForm") @Valid User userForm, BindingResult bindingResult, Model model) { userValidator.validate(userForm, bindingResult); + if (bindingResult.hasErrors()) { return "registration"; } - System.out.println("User PWD:"+userForm.getPassword()); - userService.save(userForm); - securityService.autologin(userForm.getUsername(), userForm.getPasswordConfirm()); + userService.save(userForm); + boolean loginSuccessful = securityService.autologin(userForm.getUsername(), userForm.getPasswordConfirm()); + if (!loginSuccessful) { + return "redirect:/login?error"; + } return "redirect:/welcome"; } - /** {@inheritDoc} */ - @RequestMapping(value = "/login", method = RequestMethod.GET) - public final String login(final Model model, final String error, final String logout) { - System.out.println("Model data"+model.toString()); - if (error != null){ + + @GetMapping("/") + public String login(Model model, @RequestParam(value = "error", required = false) String error, + @RequestParam(value = "logout", required = false) String logout) { + if (error != null) { model.addAttribute("error", "Your username and password is invalid."); } - if (logout != null){ + if (logout != null) { model.addAttribute("message", "You have been logged out successfully."); } return "login"; } - /** {@inheritDoc} */ - @RequestMapping(value = { "/", "/welcome"}, method = RequestMethod.GET) - public final String welcome(final Model model) { + + @PostMapping("/login") + public String loginPost(@ModelAttribute("user") User user, Model model) { + boolean loginSuccessful = securityService.autologin(user.getUsername(), user.getPassword()); + if (!loginSuccessful) { + model.addAttribute("error", "Your username and password is invalid."); + return "login"; + } + return "redirect:/welcome"; + } + + @GetMapping("/welcome") + public String welcome(Model model) { return "welcome"; } - /** {@inheritDoc} */ - @RequestMapping(value = { "/index"} , method = RequestMethod.GET) - public final String indexHome(final Model model) { + + @GetMapping("/index") + public String indexHome(Model model) { return "index_home"; } - @RequestMapping(value = "/users", method = RequestMethod.GET) - public String getAllUsers(Model model) - { - + + @GetMapping("/users") + public String getAllUsers(Model model) { List users = userService.getList(); - //JSONObject jsonObject - System.out.println("All User Data:::" + users); model.addAttribute("users", users); return "userList"; } - - @RequestMapping(value = "/users/{id}", method = RequestMethod.GET) - public String getOneUser(@PathVariable(value="id") String id,Model model) - { - String Result =""; - try{ - if( id != null && MemcachedUtils.memcachedGetData(id)!= null){ - User userData = MemcachedUtils.memcachedGetData(id); - Result ="Data is From Cache"; - System.out.println("--------------------------------------------"); - System.out.println("Data is From Cache !!"); - System.out.println("--------------------------------------------"); - System.out.println("Father ::: "+userData.getFatherName()); - model.addAttribute("user", userData); - model.addAttribute("Result", Result); - } - else{ - User user = userService.findById(Long.parseLong(id)); - Result = MemcachedUtils.memcachedSetData(user,id); - if(Result == null ){ - Result ="Memcached Connection Failure !!"; - } - System.out.println("--------------------------------------------"); - System.out.println("Data is From Database"); - System.out.println("--------------------------------------------"); - System.out.println("Result ::: "+ Result); - model.addAttribute("user", user); - model.addAttribute("Result", Result); - } - } catch (Exception e) { - System.out.println( e.getMessage() ); - } + + @GetMapping("/users/{id}") + public String getOneUser(@PathVariable("id") String id, Model model) { + String result; + try { + User userData = MemcachedUtils.memcachedGetData(id); + if (userData != null) { + result = "Data is From Cache"; + model.addAttribute("user", userData); + } else { + User user = userService.findById(Long.parseLong(id)); + result = MemcachedUtils.memcachedSetData(user, id); + if (result == null) { + result = "Memcached Connection Failure !!"; + } + model.addAttribute("user", user); + } + model.addAttribute("Result", result); + } catch (Exception e) { + e.printStackTrace(); + } return "user"; } - - /** {@inheritDoc} */ - @RequestMapping(value = { "/user/{username}"} , method = RequestMethod.GET) - public final String userUpdate(@PathVariable(value="username") String username,final Model model) { - User user = userService.findByUsername(username); - System.out.println("User Data:::" + user); - model.addAttribute("user", user); - return "userUpdate"; + + @GetMapping("/user/{username}") + public String userUpdate(@PathVariable("username") String username, Model model) { + User user = userService.findByUsername(username); + model.addAttribute("user", user); + return "userUpdate"; } - @RequestMapping(value = { "/user/{username}"} , method = RequestMethod.POST) - public final String userUpdateProfile(@PathVariable(value="username") String username,final @ModelAttribute("user") User userForm,final Model model) { - User user = userService.findByUsername(username); - user.setUsername(userForm.getUsername()); - user.setUserEmail(userForm.getUserEmail()); - user.setDateOfBirth(userForm.getDateOfBirth()); - user.setFatherName(userForm.getFatherName()); - user.setMotherName(userForm.getMotherName()); - user.setGender(userForm.getGender()); - user.setLanguage(userForm.getLanguage()); - user.setMaritalStatus(userForm.getMaritalStatus()); - user.setNationality(userForm.getNationality()); - user.setPermanentAddress(userForm.getPermanentAddress()); - user.setTempAddress(userForm.getTempAddress()); - user.setPhoneNumber(userForm.getPhoneNumber()); - user.setSecondaryPhoneNumber(userForm.getSecondaryPhoneNumber()); - user.setPrimaryOccupation(userForm.getPrimaryOccupation()); - user.setSecondaryOccupation(userForm.getSecondaryOccupation()); - user.setSkills(userForm.getSkills()); - user.setWorkingExperience(userForm.getWorkingExperience()); - userService.save(user); - /*model.addAttribute("user", user);*/ - return "welcome"; + + @PostMapping("/user/{username}") + public String userUpdateProfile(@PathVariable("username") String username, @ModelAttribute("user") User userForm) { + User user = userService.findByUsername(username); + updateUserDetails(user, userForm); + userService.save(user); + return "welcome"; } - - @RequestMapping(value={"/user/rabbit"}, method={RequestMethod.GET}) - public String rabbitmqSetUp() { - System.out.println("Rabbit mq method is callled!!!"); - for (int i = 0; i < 20; i++) { - producerService.produceMessage(generateString()); - } - return "rabbitmq"; + +// @GetMapping("/user/rabbit") +// public String rabbitmqSetUp() { +// for (int i = 0; i < 20; i++) { +// producerService.produceMessage(generateString()); +// } +// return "rabbitmq"; +// } + + private void updateUserDetails(User user, User userForm) { + user.setUsername(userForm.getUsername()); + user.setUserEmail(userForm.getUserEmail()); + user.setDateOfBirth(userForm.getDateOfBirth()); + user.setFatherName(userForm.getFatherName()); + user.setMotherName(userForm.getMotherName()); + user.setGender(userForm.getGender()); + user.setLanguage(userForm.getLanguage()); + user.setMaritalStatus(userForm.getMaritalStatus()); + user.setNationality(userForm.getNationality()); + user.setPermanentAddress(userForm.getPermanentAddress()); + user.setTempAddress(userForm.getTempAddress()); + user.setPhoneNumber(userForm.getPhoneNumber()); + user.setSecondaryPhoneNumber(userForm.getSecondaryPhoneNumber()); + user.setPrimaryOccupation(userForm.getPrimaryOccupation()); + user.setSecondaryOccupation(userForm.getSecondaryOccupation()); + user.setSkills(userForm.getSkills()); + user.setWorkingExperience(userForm.getWorkingExperience()); } - + private static String generateString() { - String uuid = UUID.randomUUID().toString(); - return "uuid = " + uuid; + return "uuid = " + UUID.randomUUID().toString(); } - - - } diff --git a/src/main/java/com/visualpathit/account/model/Role.java b/src/main/java/com/visualpathit/account/model/Role.java index af821ad0e..1914f2149 100644 --- a/src/main/java/com/visualpathit/account/model/Role.java +++ b/src/main/java/com/visualpathit/account/model/Role.java @@ -1,6 +1,7 @@ package com.visualpathit.account.model; -import javax.persistence.*; +import jakarta.persistence.*; + import java.util.Set; /**{@author imrant} !*/ @Entity @@ -14,7 +15,7 @@ public class Role { private Set users; /** {@inheritDoc}} !*/ @Id - @GeneratedValue(strategy = GenerationType.AUTO) + @GeneratedValue(strategy = GenerationType.IDENTITY) /** * {@link Role#id} !*/ diff --git a/src/main/java/com/visualpathit/account/model/User.java b/src/main/java/com/visualpathit/account/model/User.java index 23050ce94..ffe522abc 100644 --- a/src/main/java/com/visualpathit/account/model/User.java +++ b/src/main/java/com/visualpathit/account/model/User.java @@ -1,7 +1,7 @@ package com.visualpathit.account.model; -import javax.persistence.*; +import jakarta.persistence.*; import java.io.Serializable; import java.util.Set; @@ -44,7 +44,7 @@ public class User implements Serializable { private Set roles; /** {@inheritDoc}} !*/ @Id - @GeneratedValue(strategy = GenerationType.AUTO) + @GeneratedValue(strategy = GenerationType.IDENTITY) /** {@link User#id} */ public Long getId() { return id; diff --git a/src/main/java/com/visualpathit/account/service/SecurityService.java b/src/main/java/com/visualpathit/account/service/SecurityService.java index dbd4d9bc5..534171f90 100644 --- a/src/main/java/com/visualpathit/account/service/SecurityService.java +++ b/src/main/java/com/visualpathit/account/service/SecurityService.java @@ -5,5 +5,5 @@ public interface SecurityService { /** {@inheritDoc}} !*/ String findLoggedInUsername(); - void autologin(String username, String password); + boolean autologin(String username, String password); } diff --git a/src/main/java/com/visualpathit/account/service/SecurityServiceImpl.java b/src/main/java/com/visualpathit/account/service/SecurityServiceImpl.java index 14fee640d..5c826f066 100644 --- a/src/main/java/com/visualpathit/account/service/SecurityServiceImpl.java +++ b/src/main/java/com/visualpathit/account/service/SecurityServiceImpl.java @@ -4,49 +4,45 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.authentication - .UsernamePasswordAuthenticationToken; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.stereotype.Service; -/** {@author imrant} !*/ + @Service public class SecurityServiceImpl implements SecurityService { - /** authenticationManager !*/ - @Autowired + @Autowired private AuthenticationManager authenticationManager; - /** userDetailsService !*/ + @Autowired private UserDetailsService userDetailsService; - /** Logger creation !*/ - private static final Logger logger = LoggerFactory - .getLogger(SecurityServiceImpl.class); + private static final Logger logger = LoggerFactory.getLogger(SecurityServiceImpl.class); @Override public String findLoggedInUsername() { - Object userDetails = SecurityContextHolder.getContext() - .getAuthentication().getDetails(); + Object userDetails = SecurityContextHolder.getContext().getAuthentication().getDetails(); if (userDetails instanceof UserDetails) { return ((UserDetails) userDetails).getUsername(); } - return null; } @Override - public void autologin(final String username, final String password) { + public boolean autologin(final String username, final String password) { UserDetails userDetails = userDetailsService.loadUserByUsername(username); - UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = - new UsernamePasswordAuthenticationToken(userDetails, password, userDetails.getAuthorities()); + UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = + new UsernamePasswordAuthenticationToken(userDetails, password, userDetails.getAuthorities()); authenticationManager.authenticate(usernamePasswordAuthenticationToken); if (usernamePasswordAuthenticationToken.isAuthenticated()) { - SecurityContextHolder.getContext() - .setAuthentication(usernamePasswordAuthenticationToken); + SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken); logger.debug(String.format("Auto login %s successfully!", username)); + return true; } + logger.debug(String.format("Auto login %s failed!", username)); + return false; } } diff --git a/src/main/java/com/visualpathit/account/service/UserDetailsServiceImpl.java b/src/main/java/com/visualpathit/account/service/UserDetailsServiceImpl.java index 04c68ae80..f2bbb1bad 100644 --- a/src/main/java/com/visualpathit/account/service/UserDetailsServiceImpl.java +++ b/src/main/java/com/visualpathit/account/service/UserDetailsServiceImpl.java @@ -3,18 +3,20 @@ import com.visualpathit.account.model.Role; import com.visualpathit.account.model.User; import com.visualpathit.account.repository.UserRepository; - import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.HashSet; import java.util.Set; + /** {@author imrant} !*/ +@Service public class UserDetailsServiceImpl implements UserDetailsService { @Autowired /** userRepository !*/ @@ -22,16 +24,18 @@ public class UserDetailsServiceImpl implements UserDetailsService { @Override @Transactional(readOnly = true) - public UserDetails loadUserByUsername(final String username) - throws UsernameNotFoundException { + public UserDetails loadUserByUsername(final String username) throws UsernameNotFoundException { User user = userRepository.findByUsername(username); + if (user == null) { + throw new UsernameNotFoundException("User not found with username: " + username); + } + Set grantedAuthorities = new HashSet<>(); for (Role role : user.getRoles()) { grantedAuthorities.add(new SimpleGrantedAuthority(role.getName())); } - return new org.springframework.security.core - .userdetails.User(user.getUsername(), user.getPassword(), grantedAuthorities); + return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), grantedAuthorities); } } diff --git a/src/main/java/com/visualpathit/account/service/UserServiceImpl.java b/src/main/java/com/visualpathit/account/service/UserServiceImpl.java index 2426b853f..fd48cd3c7 100644 --- a/src/main/java/com/visualpathit/account/service/UserServiceImpl.java +++ b/src/main/java/com/visualpathit/account/service/UserServiceImpl.java @@ -42,6 +42,6 @@ public List getList() { } @Override public User findById(long id){ - return userRepository.findOne(id); + return userRepository.findById(id); } } diff --git a/src/main/java/com/visualpathit/account/utils/ElasticsearchUtil.java b/src/main/java/com/visualpathit/account/utils/ElasticsearchUtil.java index 838fa536e..b4d08685a 100644 --- a/src/main/java/com/visualpathit/account/utils/ElasticsearchUtil.java +++ b/src/main/java/com/visualpathit/account/utils/ElasticsearchUtil.java @@ -1,48 +1,45 @@ package com.visualpathit.account.utils; +import java.io.IOException; import java.net.InetSocketAddress; -import org.elasticsearch.client.transport.TransportClient; -import org.elasticsearch.common.settings.Settings; -import org.elasticsearch.common.transport.InetSocketTransportAddress; -import org.elasticsearch.transport.client.PreBuiltTransportClient; +import org.apache.http.HttpHost; +import org.elasticsearch.client.RequestOptions; +import org.elasticsearch.client.RestClient; +import org.elasticsearch.client.RestHighLevelClient; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.visualpathit.account.beans.Components; + @Service public class ElasticsearchUtil { - - private static Components object; + + private static Components object; + @Autowired - public void setComponents(Components object){ - ElasticsearchUtil.object = object; - + public void setComponents(Components object) { + ElasticsearchUtil.object = object; } - public static TransportClient trannsportClient() { - System.out.println(" elasticsearch client"); - String elasticsearchHost =object.getElasticsearchHost(); - String elasticsearchPort =object.getElasticsearchPort(); - String elasticsearchCluster =object.getElasticsearchCluster(); - String elasticsearchNode =object.getElasticsearchNode(); - System.out.println(" elasticsearchHost ........"+ elasticsearchHost); - System.out.println(" elasticsearchHost ........"+ elasticsearchPort); - TransportClient client = null; - try { - Settings settings = Settings.builder() - .put("cluster.name",elasticsearchCluster) - .put("node.name",elasticsearchNode) - .build(); - client = new PreBuiltTransportClient(settings) - .addTransportAddress( - new InetSocketTransportAddress( - new InetSocketAddress(elasticsearchHost, Integer.parseInt(elasticsearchPort)))); + public static RestHighLevelClient getRestHighLevelClient() { + System.out.println("Creating Elasticsearch client..."); + String elasticsearchHost = object.getElasticsearchHost(); + String elasticsearchPort = object.getElasticsearchPort(); - } - catch (Exception e) { - e.printStackTrace(); - } - return client; - } + System.out.println("Elasticsearch Host: " + elasticsearchHost); + System.out.println("Elasticsearch Port: " + elasticsearchPort); + + RestHighLevelClient client = null; + try { + client = new RestHighLevelClient( + RestClient.builder( + new HttpHost(elasticsearchHost, Integer.parseInt(elasticsearchPort), "http") + ) + ); + } catch (Exception e) { + e.printStackTrace(); + } + return client; + } } diff --git a/src/main/resources/accountsdb.sql b/src/main/resources/accountsdb.sql index d224d810f..8aedbfd85 100644 --- a/src/main/resources/accountsdb.sql +++ b/src/main/resources/accountsdb.sql @@ -26,7 +26,7 @@ CREATE TABLE `role` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(45) DEFAULT NULL, PRIMARY KEY (`id`) -) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8; +) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -36,6 +36,7 @@ CREATE TABLE `role` ( LOCK TABLES `role` WRITE; /*!40000 ALTER TABLE `role` DISABLE KEYS */; INSERT INTO `role` VALUES (1,'ROLE_USER'); +INSERT INTO `role` VALUES (2,'ROLE_ADMIN'); /*!40000 ALTER TABLE `role` ENABLE KEYS */; UNLOCK TABLES; @@ -44,8 +45,8 @@ UNLOCK TABLES; -- DROP TABLE IF EXISTS `user`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET @saved_cs_client = @@CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_CLIENT = utf8 */; CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(255) DEFAULT NULL, @@ -53,7 +54,7 @@ CREATE TABLE `user` ( `password` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8; -/*!40101 SET character_set_client = @saved_cs_client */; +/*!40101 SET CHARACTER_SET_CLIENT = @saved_cs_client */; -- -- Dumping data for table `user` @@ -70,8 +71,8 @@ UNLOCK TABLES; -- DROP TABLE IF EXISTS `user_role`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; +/*!40101 SET @saved_cs_client = @@CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_CLIENT = utf8 */; CREATE TABLE `user_role` ( `user_id` int(11) NOT NULL, `role_id` int(11) NOT NULL, @@ -80,7 +81,7 @@ CREATE TABLE `user_role` ( CONSTRAINT `fk_user_role_roleid` FOREIGN KEY (`role_id`) REFERENCES `role` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT `fk_user_role_userid` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -/*!40101 SET character_set_client = @saved_cs_client */; +/*!40101 SET CHARACTER_SET_CLIENT = @saved_cs_client */; -- -- Dumping data for table `user_role` @@ -88,7 +89,8 @@ CREATE TABLE `user_role` ( LOCK TABLES `user_role` WRITE; /*!40000 ALTER TABLE `user_role` DISABLE KEYS */; -INSERT INTO `user_role` VALUES (4,1); +INSERT INTO `user_role` VALUES (4,1); -- ROLE_USER +INSERT INTO `user_role` VALUES (4,2); -- ROLE_ADMIN /*!40000 ALTER TABLE `user_role` ENABLE KEYS */; UNLOCK TABLES; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index c04343d72..3fb5ab422 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,25 +1,58 @@ #JDBC Configutation for Database Connection -jdbc.driverClassName=com.mysql.jdbc.Driver -jdbc.url=jdbc:mysql://db01:3306/accounts?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull -jdbc.username=admin -jdbc.password=admin123 +jdbc.driverClassName=com.mysql.cj.jdbc.Driver +#jdbc.url=jdbc:mysql://db01:3306/accounts?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull +jdbc.url=${DB_URL} +jdbc.username=${DB_USER} +jdbc.password=${DB_PASS} #Memcached Configuration For Active and StandBy Host #For Active Host -memcached.active.host=mc01 +memcached.active.host=mc01.vpro.internal memcached.active.port=11211 #For StandBy Host memcached.standBy.host=127.0.0.2 memcached.standBy.port=11211 #RabbitMq Configuration -rabbitmq.address=rmq01 +rabbitmq.address=rmq01.vpro.internal rabbitmq.port=5672 -rabbitmq.username=test -rabbitmq.password=test +rabbitmq.username=${RMQ_USER} +rabbitmq.password=${RMQ_PASS} #Elasticesearch Configuration -elasticsearch.host =192.168.1.85 -elasticsearch.port =9300 +elasticsearch.host=localhost +elasticsearch.port=9300 elasticsearch.cluster=vprofile elasticsearch.node=vprofilenode + + +spring.servlet.multipart.max-file-size=128KB +spring.servlet.multipart.max-request-size=128KB + +logging.level.org.springframework.security=DEBUG + + +# application.properties +spring.security.user.name=admin_vp +spring.security.user.password=admin_vp +spring.security.user.roles=ADMIN + + +spring.mvc.view.prefix=/WEB-INF/views/ +spring.mvc.view.suffix=.jsp + +#logging.level.root=OFF +#logging.level.org.springframework.web=OFF +#spring.main.banner-mode=OFF + +# Hibernate SQL Queries +spring.jpa.show-sql=false +spring.jpa.properties.hibernate.format_sql=false +logging.level.org.hibernate.SQL=OFF +logging.level.org.hibernate.type=OFF + + +# Debug Logging for SecurityServiceImpl +logging.level.com.visualpathit.account.service.SecurityServiceImpl=OFF + + diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml index 35b81df4d..37959912a 100644 --- a/src/main/resources/logback.xml +++ b/src/main/resources/logback.xml @@ -1,24 +1,24 @@ - + - - - %date{HH:mm:ss.SSS} [%thread] %-5level %logger{15}#%line %msg\n - - + + + %date{HH:mm:ss.SSS} [%thread] %-5level %logger{15}#%line %msg%n + + - - - + + + + + + - - - + + + + + - - - - - - \ No newline at end of file + diff --git a/src/main/webapp/META-INF/MANIFEST.MF b/src/main/webapp/META-INF/MANIFEST.MF new file mode 100644 index 000000000..59499bce4 --- /dev/null +++ b/src/main/webapp/META-INF/MANIFEST.MF @@ -0,0 +1,2 @@ +Manifest-Version: 1.0 + diff --git a/src/main/webapp/WEB-INF/appconfig-data.xml b/src/main/webapp/WEB-INF/appconfig-data.xml index 7be0032b5..18d9dbafd 100644 --- a/src/main/webapp/WEB-INF/appconfig-data.xml +++ b/src/main/webapp/WEB-INF/appconfig-data.xml @@ -1,54 +1,45 @@ - - - + xsi:schemaLocation=" + http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd + http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd + http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> - - - - - + + + + + - - + + - + - org.hibernate.dialect.MySQL5Dialect + org.hibernate.dialect.MySQLDialect true - - + + - - - - + + - - + + + diff --git a/src/main/webapp/WEB-INF/appconfig-mvc.xml b/src/main/webapp/WEB-INF/appconfig-mvc.xml index 58f404dc5..c8efd8bda 100644 --- a/src/main/webapp/WEB-INF/appconfig-mvc.xml +++ b/src/main/webapp/WEB-INF/appconfig-mvc.xml @@ -1,32 +1,32 @@ + xmlns:mvc="http://www.springframework.org/schema/mvc" + xmlns="http://www.springframework.org/schema/beans" + xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd + http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> - + - - - - - - classpath:validation - - - - - - /WEB-INF/views/ - - - .jsp - - - - - + + + + + classpath:validation + + + + + + /WEB-INF/views/ + + + .jsp + + + + \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/appconfig-rabbitmq.xml b/src/main/webapp/WEB-INF/appconfig-rabbitmq.xml index 989faec37..2fadbead6 100644 --- a/src/main/webapp/WEB-INF/appconfig-rabbitmq.xml +++ b/src/main/webapp/WEB-INF/appconfig-rabbitmq.xml @@ -1,28 +1,30 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:beans="http://www.springframework.org/schema/beans" + xmlns:context="http://www.springframework.org/schema/context" + xmlns:mvc="http://www.springframework.org/schema/mvc" + xmlns:rabbit="http://www.springframework.org/schema/rabbit" + xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd + http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd + http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd + http://www.springframework.org/schema/rabbit http://www.springframework.org/schema/rabbit/spring-rabbit.xsd"> - + - + - + - + - - - - - + + + + + \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/appconfig-root.xml b/src/main/webapp/WEB-INF/appconfig-root.xml index 064cc5e7a..aa7ae8728 100644 --- a/src/main/webapp/WEB-INF/appconfig-root.xml +++ b/src/main/webapp/WEB-INF/appconfig-root.xml @@ -1,20 +1,19 @@ - http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> + - + + + - - - - - - - - + + + \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/appconfig-security.xml b/src/main/webapp/WEB-INF/appconfig-security.xml index 5e2acf137..797eff774 100644 --- a/src/main/webapp/WEB-INF/appconfig-security.xml +++ b/src/main/webapp/WEB-INF/appconfig-security.xml @@ -1,30 +1,31 @@ + xmlns:beans="http://www.springframework.org/schema/beans" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd + http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd"> - - - - - - - + + + + + + + - - - - - + + + + + - + - - - + + + diff --git a/src/main/webapp/WEB-INF/views/error/404.jsp b/src/main/webapp/WEB-INF/views/error/404.jsp new file mode 100644 index 000000000..a3cd4eddc --- /dev/null +++ b/src/main/webapp/WEB-INF/views/error/404.jsp @@ -0,0 +1,32 @@ +<%@ page contentType="text/html;charset=UTF-8" language="java" %> + + + + + + User Not Found + + + + +

User Not Found

+

The user you are looking for does not exist. Please try again or go back to the login page.

+ + diff --git a/src/main/webapp/WEB-INF/views/error/500.jsp b/src/main/webapp/WEB-INF/views/error/500.jsp new file mode 100644 index 000000000..41874b50a --- /dev/null +++ b/src/main/webapp/WEB-INF/views/error/500.jsp @@ -0,0 +1,63 @@ +<%@ page contentType="text/html;charset=UTF-8" language="java" %> + + + + User Not Found + + + + + + +
+
+ +
+

User Not Found

+

It seems we couldn't find your account. You can create a new account if you don't have one.

+
+ + diff --git a/src/main/webapp/WEB-INF/views/error/database-error.jsp b/src/main/webapp/WEB-INF/views/error/database-error.jsp new file mode 100644 index 000000000..a99b1418e --- /dev/null +++ b/src/main/webapp/WEB-INF/views/error/database-error.jsp @@ -0,0 +1,44 @@ +<%@ page contentType="text/html;charset=UTF-8" language="java" %> + + + + Database Connection Error + + + + +
+

Database Connection Error

+

We are currently unable to connect to the database. Please check your database server and credentials.

+

If the problem persists, please contact support.

+

Back to Home

+
+ + diff --git a/src/main/webapp/WEB-INF/views/index_home.jsp b/src/main/webapp/WEB-INF/views/index_home.jsp index 4579f61fe..b0d981839 100644 --- a/src/main/webapp/WEB-INF/views/index_home.jsp +++ b/src/main/webapp/WEB-INF/views/index_home.jsp @@ -10,53 +10,41 @@ -
-
-
- Architecture -
-

DevOps

-
+ Architecture

Keep Learning ..

-

Learning is a Treasure that will follow it's Owner Everywhere..

+

Learning is a Treasure that will follow it's Owner Everywhere..

@@ -69,8 +57,8 @@
- DevOps -
+ DevOps +
@@ -97,7 +85,7 @@
- DevOps + DevOps
@@ -115,20 +103,32 @@

ABOUT

-
-

VisualPath is an IT Educational Institute.Established in 2001,and Institute offers world class quality of education and wide range of courses.VisualPath Institute has a dedicated placement team to help students get job placement in various IT job roles with major companies. -

-

Address: Flat no: 205, 2nd Floor,NILGIRI Block,Aditya Encalve,Ameerpet, Hyderabad-16

-

Ph No: +91-9704455959,9618245689

-

E-Mail ID : visualpath999@gmail.com

+
+

+ HKH Infotech is a dynamic software company dedicated to delivering innovative technology solutions. Founded with a mission to leverage cutting-edge technology and unparalleled expertise, we specialize in creating high-quality software solutions that drive business success. +

+

+ Our team is led by seasoned DevOps experts with many years of industry experience. They bring a wealth of knowledge in automating and optimizing the software development lifecycle, ensuring that our projects are efficient, reliable, and scalable. +

+

+ At HKH Infotech, we focus on understanding our clients' unique needs and providing tailored solutions that meet their objectives. Whether it's custom software development, system integration, or ongoing support, we are committed to excellence and client satisfaction. +

+

+ With a commitment to staying ahead of technological trends and a passion for innovation, HKH Infotech is your trusted partner in navigating the digital landscape and achieving your business goals. +

+

Address: Punjagutta Colony Ameerpet, Hyderabad

+

Phone: +91-8001234567

+

Email: contact@hkhinfotech.com

- +
+

CONTACT

+

Lets get in touch and talk about your and our next project.

-
+ @@ -137,16 +137,12 @@ SEND MESSAGE
+
- + -
- - diff --git a/src/main/webapp/WEB-INF/views/login.jsp b/src/main/webapp/WEB-INF/views/login.jsp index 0a41ac1c4..82480a75a 100644 --- a/src/main/webapp/WEB-INF/views/login.jsp +++ b/src/main/webapp/WEB-INF/views/login.jsp @@ -7,89 +7,159 @@ - - + Login + - - - + + + + + + + + + + + + + + + + + + + + + + + + + - LOGIN +
+
+
+
+ + Login + - - + + +
+ +
+
- - - - Welcome - - - - - +
+ Username + + +
+ +
+ Password + + +
- + -
-
- -
- - -

WELCOME!

- -
- ${message} - - - ${error} - - -

SIGN UP

+
+ + Don't have an account? + + + + Sign Up + +
+
+
+
- + + + + + + + + + + + + + + + + + + -
- - - diff --git a/src/main/webapp/WEB-INF/views/rabbitmq-error.jsp b/src/main/webapp/WEB-INF/views/rabbitmq-error.jsp new file mode 100644 index 000000000..b0d94014b --- /dev/null +++ b/src/main/webapp/WEB-INF/views/rabbitmq-error.jsp @@ -0,0 +1,28 @@ +<%@ page language="java" contentType="text/html; charset=UTF-8" + pageEncoding="UTF-8"%> + + + + + RabbitMQ Error + + + +

RabbitMQ Error

+

RabbitMQ server is off. Please start the RabbitMQ server and try again.

+ + diff --git a/src/main/webapp/WEB-INF/views/rabbitmq.jsp b/src/main/webapp/WEB-INF/views/rabbitmq.jsp index 2220694d4..70ece377f 100644 --- a/src/main/webapp/WEB-INF/views/rabbitmq.jsp +++ b/src/main/webapp/WEB-INF/views/rabbitmq.jsp @@ -1,14 +1,35 @@ <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> - - + + - -Rabbitmq + + RabbitMQ + -

Rabbitmq initiated

-

Generated 2 Connections

-

6 Chanels 1 Exchage and 2 Que

+ <% + int connections = (int) (Math.random() * 10) + 1; + int channels = (int) (Math.random() * 10) + 1; + int exchange = (int) (Math.random() * 10) + 1; + int queues = (int) (Math.random() * 10) + 1; + %> +

RabbitMQ Initiated

+

Generated <%= connections %> Connections

+

<%= channels %> Channels, <%= exchange %> Exchange, and <%= queues %> Queues

- \ No newline at end of file + diff --git a/src/main/webapp/WEB-INF/views/registration.jsp b/src/main/webapp/WEB-INF/views/registration.jsp index be726ccd9..37779c4d0 100644 --- a/src/main/webapp/WEB-INF/views/registration.jsp +++ b/src/main/webapp/WEB-INF/views/registration.jsp @@ -1,112 +1,139 @@ +<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> <%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> -<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> - - + Sign Up + - - - + + + + + + + + + + + + + + + + - - - +
+
+
+ + Sign Up - -
-
- -
-
+ +
+ Username + + + +
-
+
- -
+ -
- - - + + + + + + + + + diff --git a/src/main/webapp/WEB-INF/views/upload.jsp b/src/main/webapp/WEB-INF/views/upload.jsp index 3e52f833a..628f866a8 100644 --- a/src/main/webapp/WEB-INF/views/upload.jsp +++ b/src/main/webapp/WEB-INF/views/upload.jsp @@ -43,7 +43,7 @@
- +
diff --git a/src/main/webapp/WEB-INF/views/user.jsp b/src/main/webapp/WEB-INF/views/user.jsp index 480bf6e24..a16774482 100644 --- a/src/main/webapp/WEB-INF/views/user.jsp +++ b/src/main/webapp/WEB-INF/views/user.jsp @@ -1,163 +1,167 @@ <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> - <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> - - +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> + + UserData - + + - - - - - - + + + + + + - -
-
-