[{"data":1,"prerenderedAt":3848},["ShallowReactive",2],{"post-terraform":3,"rel-terraform":637,"sib-terraform":3776},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"date":10,"layout":11,"subtitle":12,"image":13,"optimized_image":13,"category":14,"tags":15,"author":18,"paginate":6,"body":19,"_type":631,"_id":632,"_source":633,"_file":634,"_stem":635,"_extension":636},"/posts/terraform","posts",false,"","Unleashing the Power of Infrastructure as Code (IaC)","Unleashing the Power of Infrastructure as Code (IaC) with Terraform","2023-09-24 18:00:00","post","with Terraform","/assets/img/uploads/infrastructure.jpg","code",[16,17],"sre","IaC","jaimedearcos",{"type":20,"children":21,"toc":625},"root",[22,30,37,42,48,53,281,286,292,297,310,481,486,491,535,540,545,550,556,561,614,619],{"type":23,"tag":24,"props":25,"children":26},"element","p",{},[27],{"type":28,"value":29},"text","In the rapidly evolving landscape of software development, Infrastructure as Code (IaC) has emerged as a pivotal paradigm. It revolutionizes the way we manage and provision infrastructure, and at the forefront of this revolution stands Terraform. In this post, we will embark on a practical journey to demystify IaC, understand Terraform's role, and explore essential Terraform concepts, culminating in a hands-on example of provisioning an S3 bucket using this powerful tool.",{"type":23,"tag":31,"props":32,"children":34},"h3",{"id":33},"what-is-infrastructure-as-code-iac",[35],{"type":28,"value":36},"What is Infrastructure as Code (IaC)?",{"type":23,"tag":24,"props":38,"children":39},{},[40],{"type":28,"value":41},"Infrastructure as Code (IaC) is a methodology that treats infrastructure provisioning and management as software development. Instead of manually configuring servers, networks, and other resources, IaC allows you to define infrastructure components in code. This code is version-controlled, tested, and deployed like any other software. The benefits are numerous: consistency, repeatability, scalability, and improved collaboration among development and operations teams.",{"type":23,"tag":31,"props":43,"children":45},{"id":44},"understanding-terraform-concepts",[46],{"type":28,"value":47},"Understanding Terraform Concepts",{"type":23,"tag":24,"props":49,"children":50},{},[51],{"type":28,"value":52},"Terraform operates on several fundamental concepts that are essential to grasp as you start working with this Infrastructure as Code (IaC) tool. Let's break them down with brief explanations:",{"type":23,"tag":54,"props":55,"children":56},"ul",{},[57,93,124,155,186,217,250],{"type":23,"tag":58,"props":59,"children":60},"li",{},[61,67,69],{"type":23,"tag":14,"props":62,"children":64},{"className":63},[],[65],{"type":28,"value":66},"Providers",{"type":28,"value":68},":",{"type":23,"tag":54,"props":70,"children":71},{},[72,83],{"type":23,"tag":58,"props":73,"children":74},{},[75,81],{"type":23,"tag":76,"props":77,"children":78},"strong",{},[79],{"type":28,"value":80},"What Are They?:",{"type":28,"value":82},"  Providers are responsible for bridging the gap between Terraform and various infrastructure platforms, such as cloud providers (AWS, Azure, GCP), on-premises environments, or third-party services.",{"type":23,"tag":58,"props":84,"children":85},{},[86,91],{"type":23,"tag":76,"props":87,"children":88},{},[89],{"type":28,"value":90},"How They Work:",{"type":28,"value":92}," Each provider has a set of configuration settings to authenticate and interact with a specific platform. Terraform uses these settings to establish connections and manage resources on the chosen platform.",{"type":23,"tag":58,"props":94,"children":95},{},[96,102,103],{"type":23,"tag":14,"props":97,"children":99},{"className":98},[],[100],{"type":28,"value":101},"Resources",{"type":28,"value":68},{"type":23,"tag":54,"props":104,"children":105},{},[106,115],{"type":23,"tag":58,"props":107,"children":108},{},[109,113],{"type":23,"tag":76,"props":110,"children":111},{},[112],{"type":28,"value":80},{"type":28,"value":114},"  Resources are individual infrastructure components that you want to create, manage, or delete using Terraform. They can represent anything from virtual machines and databases to networking elements and security groups.",{"type":23,"tag":58,"props":116,"children":117},{},[118,122],{"type":23,"tag":76,"props":119,"children":120},{},[121],{"type":28,"value":90},{"type":28,"value":123}," Resources are defined within provider blocks in your Terraform configuration. You specify the resource type, a unique name, and configuration settings to define the desired state of the resource.",{"type":23,"tag":58,"props":125,"children":126},{},[127,133,134],{"type":23,"tag":14,"props":128,"children":130},{"className":129},[],[131],{"type":28,"value":132},"Variables",{"type":28,"value":68},{"type":23,"tag":54,"props":135,"children":136},{},[137,146],{"type":23,"tag":58,"props":138,"children":139},{},[140,144],{"type":23,"tag":76,"props":141,"children":142},{},[143],{"type":28,"value":80},{"type":28,"value":145},"  Variables allow you to parameterize your Terraform configurations. They provide a way to input values that might change depending on the environment or use case.",{"type":23,"tag":58,"props":147,"children":148},{},[149,153],{"type":23,"tag":76,"props":150,"children":151},{},[152],{"type":28,"value":90},{"type":28,"value":154}," You define variables in your configuration, and they can be used throughout your Terraform code. Variables can be assigned default values or provided by external input files.",{"type":23,"tag":58,"props":156,"children":157},{},[158,164,165],{"type":23,"tag":14,"props":159,"children":161},{"className":160},[],[162],{"type":28,"value":163},"Data Sources",{"type":28,"value":68},{"type":23,"tag":54,"props":166,"children":167},{},[168,177],{"type":23,"tag":58,"props":169,"children":170},{},[171,175],{"type":23,"tag":76,"props":172,"children":173},{},[174],{"type":28,"value":80},{"type":28,"value":176},"  Data sources allow you to retrieve information from external sources and use it in your Terraform configurations. This could include data from AWS EC2 instances, DNS records, or even remote databases.",{"type":23,"tag":58,"props":178,"children":179},{},[180,184],{"type":23,"tag":76,"props":181,"children":182},{},[183],{"type":28,"value":90},{"type":28,"value":185}," You declare a data source in your configuration, specify its type and configuration settings, and then reference the data source's attributes in other parts of your code.",{"type":23,"tag":58,"props":187,"children":188},{},[189,195,196],{"type":23,"tag":14,"props":190,"children":192},{"className":191},[],[193],{"type":28,"value":194},"Outputs",{"type":28,"value":68},{"type":23,"tag":54,"props":197,"children":198},{},[199,208],{"type":23,"tag":58,"props":200,"children":201},{},[202,206],{"type":23,"tag":76,"props":203,"children":204},{},[205],{"type":28,"value":80},{"type":28,"value":207},"  Outputs allow you to expose specific values or attributes of resources or data sources for easy access after provisioning infrastructure. They are useful for sharing information with other parts of your system.",{"type":23,"tag":58,"props":209,"children":210},{},[211,215],{"type":23,"tag":76,"props":212,"children":213},{},[214],{"type":28,"value":90},{"type":28,"value":216}," You define output blocks in your Terraform configuration, specifying what values you want to expose. After applying the configuration, you can retrieve these values using terraform output.",{"type":23,"tag":58,"props":218,"children":219},{},[220,226,227],{"type":23,"tag":14,"props":221,"children":223},{"className":222},[],[224],{"type":28,"value":225},"State",{"type":28,"value":68},{"type":23,"tag":54,"props":228,"children":229},{},[230,240],{"type":23,"tag":58,"props":231,"children":232},{},[233,238],{"type":23,"tag":76,"props":234,"children":235},{},[236],{"type":28,"value":237},"What Is It?:",{"type":28,"value":239}," Terraform maintains a state file that records the current state of your managed infrastructure. This state file is crucial for tracking changes, enabling Terraform to understand what changes are necessary to achieve the desired state.",{"type":23,"tag":58,"props":241,"children":242},{},[243,248],{"type":23,"tag":76,"props":244,"children":245},{},[246],{"type":28,"value":247},"How It Works:",{"type":28,"value":249}," Terraform creates and manages the state file, which includes resource mappings and dependencies. It's stored locally by default but can be managed remotely for team collaboration.",{"type":23,"tag":58,"props":251,"children":252},{},[253,259,260],{"type":23,"tag":14,"props":254,"children":256},{"className":255},[],[257],{"type":28,"value":258},"Modules",{"type":28,"value":68},{"type":23,"tag":54,"props":261,"children":262},{},[263,272],{"type":23,"tag":58,"props":264,"children":265},{},[266,270],{"type":23,"tag":76,"props":267,"children":268},{},[269],{"type":28,"value":80},{"type":28,"value":271},"  Modules enable you to encapsulate and reuse parts of your Terraform configurations. They are like building blocks that help you structure and modularize your infrastructure code.",{"type":23,"tag":58,"props":273,"children":274},{},[275,279],{"type":23,"tag":76,"props":276,"children":277},{},[278],{"type":28,"value":90},{"type":28,"value":280}," You create modules by defining a set of resources, variables, and outputs within a directory. You can then reuse these modules across different projects, promoting code reuse and maintainability.",{"type":23,"tag":24,"props":282,"children":283},{},[284],{"type":28,"value":285},"These core Terraform concepts form the foundation of your Infrastructure as Code journey. Understanding how to use and manipulate them effectively will enable you to manage infrastructure efficiently and consistently, regardless of its complexity or scale.",{"type":23,"tag":31,"props":287,"children":289},{"id":288},"example-provisioning-an-s3-bucket-with-terraform",[290],{"type":28,"value":291},"Example: Provisioning an S3 Bucket with Terraform",{"type":23,"tag":24,"props":293,"children":294},{},[295],{"type":28,"value":296},"Now, let's get our hands dirty by provisioning an S3 bucket using Terraform. First, ensure you have Terraform installed on your machine.",{"type":23,"tag":24,"props":298,"children":299},{},[300,302,308],{"type":28,"value":301},"Create a Terraform configuration file, e.g., ",{"type":23,"tag":14,"props":303,"children":305},{"className":304},[],[306],{"type":28,"value":307},"main.tf",{"type":28,"value":309},", and add the following code:",{"type":23,"tag":311,"props":312,"children":316},"pre",{"className":313,"code":314,"language":315,"meta":7,"style":7},"language-hcl shiki shiki-themes github-dark github-light","# Specify the AWS provider\nprovider \"aws\" {\n  region = \"us-east-1\"  # Choose your desired region\n}\n\n# Define an S3 bucket resource\nresource \"aws_s3_bucket\" \"example_bucket\" {\n  bucket = \"my-unique-bucket-name\"\n  acl    = \"private\"  # You can adjust access control here\n}\n","hcl",[317],{"type":23,"tag":14,"props":318,"children":319},{"__ignoreMap":7},[320,332,354,380,389,399,408,431,449,473],{"type":23,"tag":321,"props":322,"children":325},"span",{"class":323,"line":324},"line",1,[326],{"type":23,"tag":321,"props":327,"children":329},{"style":328},"--shiki-default:#6A737D;--shiki-light:#6A737D",[330],{"type":28,"value":331},"# Specify the AWS provider\n",{"type":23,"tag":321,"props":333,"children":335},{"class":323,"line":334},2,[336,342,348],{"type":23,"tag":321,"props":337,"children":339},{"style":338},"--shiki-default:#B392F0;--shiki-light:#6F42C1",[340],{"type":28,"value":341},"provider",{"type":23,"tag":321,"props":343,"children":345},{"style":344},"--shiki-default:#79B8FF;--shiki-light:#005CC5",[346],{"type":28,"value":347}," \"aws\"",{"type":23,"tag":321,"props":349,"children":351},{"style":350},"--shiki-default:#E1E4E8;--shiki-light:#24292E",[352],{"type":28,"value":353}," {\n",{"type":23,"tag":321,"props":355,"children":357},{"class":323,"line":356},3,[358,363,369,375],{"type":23,"tag":321,"props":359,"children":360},{"style":350},[361],{"type":28,"value":362},"  region",{"type":23,"tag":321,"props":364,"children":366},{"style":365},"--shiki-default:#F97583;--shiki-light:#D73A49",[367],{"type":28,"value":368}," =",{"type":23,"tag":321,"props":370,"children":372},{"style":371},"--shiki-default:#9ECBFF;--shiki-light:#032F62",[373],{"type":28,"value":374}," \"us-east-1\"",{"type":23,"tag":321,"props":376,"children":377},{"style":328},[378],{"type":28,"value":379},"  # Choose your desired region\n",{"type":23,"tag":321,"props":381,"children":383},{"class":323,"line":382},4,[384],{"type":23,"tag":321,"props":385,"children":386},{"style":350},[387],{"type":28,"value":388},"}\n",{"type":23,"tag":321,"props":390,"children":392},{"class":323,"line":391},5,[393],{"type":23,"tag":321,"props":394,"children":396},{"emptyLinePlaceholder":395},true,[397],{"type":28,"value":398},"\n",{"type":23,"tag":321,"props":400,"children":402},{"class":323,"line":401},6,[403],{"type":23,"tag":321,"props":404,"children":405},{"style":328},[406],{"type":28,"value":407},"# Define an S3 bucket resource\n",{"type":23,"tag":321,"props":409,"children":411},{"class":323,"line":410},7,[412,417,422,427],{"type":23,"tag":321,"props":413,"children":414},{"style":338},[415],{"type":28,"value":416},"resource",{"type":23,"tag":321,"props":418,"children":419},{"style":344},[420],{"type":28,"value":421}," \"aws_s3_bucket\"",{"type":23,"tag":321,"props":423,"children":424},{"style":344},[425],{"type":28,"value":426}," \"example_bucket\"",{"type":23,"tag":321,"props":428,"children":429},{"style":350},[430],{"type":28,"value":353},{"type":23,"tag":321,"props":432,"children":434},{"class":323,"line":433},8,[435,440,444],{"type":23,"tag":321,"props":436,"children":437},{"style":350},[438],{"type":28,"value":439},"  bucket",{"type":23,"tag":321,"props":441,"children":442},{"style":365},[443],{"type":28,"value":368},{"type":23,"tag":321,"props":445,"children":446},{"style":371},[447],{"type":28,"value":448}," \"my-unique-bucket-name\"\n",{"type":23,"tag":321,"props":450,"children":452},{"class":323,"line":451},9,[453,458,463,468],{"type":23,"tag":321,"props":454,"children":455},{"style":350},[456],{"type":28,"value":457},"  acl",{"type":23,"tag":321,"props":459,"children":460},{"style":365},[461],{"type":28,"value":462},"    =",{"type":23,"tag":321,"props":464,"children":465},{"style":371},[466],{"type":28,"value":467}," \"private\"",{"type":23,"tag":321,"props":469,"children":470},{"style":328},[471],{"type":28,"value":472},"  # You can adjust access control here\n",{"type":23,"tag":321,"props":474,"children":476},{"class":323,"line":475},10,[477],{"type":23,"tag":321,"props":478,"children":479},{"style":350},[480],{"type":28,"value":388},{"type":23,"tag":24,"props":482,"children":483},{},[484],{"type":28,"value":485},"This Terraform configuration specifies an AWS provider and creates an S3 bucket resource with a unique name. Replace \"my-unique-bucket-name\" with your preferred bucket name.",{"type":23,"tag":24,"props":487,"children":488},{},[489],{"type":28,"value":490},"To apply this configuration, navigate to the directory containing main.tf and run the following commands:",{"type":23,"tag":311,"props":492,"children":496},{"className":493,"code":494,"language":495,"meta":7,"style":7},"language-bash shiki shiki-themes github-dark github-light","terraform init  # Initialize the Terraform working directory\nterraform apply # Create the S3 bucket\n","bash",[497],{"type":23,"tag":14,"props":498,"children":499},{"__ignoreMap":7},[500,518],{"type":23,"tag":321,"props":501,"children":502},{"class":323,"line":324},[503,508,513],{"type":23,"tag":321,"props":504,"children":505},{"style":338},[506],{"type":28,"value":507},"terraform",{"type":23,"tag":321,"props":509,"children":510},{"style":371},[511],{"type":28,"value":512}," init",{"type":23,"tag":321,"props":514,"children":515},{"style":328},[516],{"type":28,"value":517},"  # Initialize the Terraform working directory\n",{"type":23,"tag":321,"props":519,"children":520},{"class":323,"line":334},[521,525,530],{"type":23,"tag":321,"props":522,"children":523},{"style":338},[524],{"type":28,"value":507},{"type":23,"tag":321,"props":526,"children":527},{"style":371},[528],{"type":28,"value":529}," apply",{"type":23,"tag":321,"props":531,"children":532},{"style":328},[533],{"type":28,"value":534}," # Create the S3 bucket\n",{"type":23,"tag":24,"props":536,"children":537},{},[538],{"type":28,"value":539},"Terraform will prompt you to confirm the resource creation. Type \"yes\" and press Enter. Terraform will provision the S3 bucket according to your configuration.",{"type":23,"tag":24,"props":541,"children":542},{},[543],{"type":28,"value":544},"Congratulations! You've just provisioned an S3 bucket using Terraform. You can now manage your infrastructure as code, track changes, and apply updates with ease.",{"type":23,"tag":24,"props":546,"children":547},{},[548],{"type":28,"value":549},"In this post, we've only scratched the surface of Terraform's capabilities. Explore its extensive documentation and dive deeper into its features to harness the full potential of Infrastructure as Code with Terraform.",{"type":23,"tag":31,"props":551,"children":553},{"id":552},"further-reading",[554],{"type":28,"value":555},"Further Reading",{"type":23,"tag":24,"props":557,"children":558},{},[559],{"type":28,"value":560},"To deepen your understanding of Terraform and explore its capabilities in more detail, here are some valuable resources from official documentation and provider-specific documentation:",{"type":23,"tag":54,"props":562,"children":563},{},[564,578,590,602],{"type":23,"tag":58,"props":565,"children":566},{},[567,576],{"type":23,"tag":568,"props":569,"children":573},"a",{"href":570,"rel":571},"https://www.terraform.io/docs/index.html",[572],"nofollow",[574],{"type":28,"value":575},"Terraform Official Documentation (HashiCorp)",{"type":28,"value":577}," The official Terraform documentation is an excellent starting point for learning the tool, understanding its features, and accessing in-depth guides and reference materials.",{"type":23,"tag":58,"props":579,"children":580},{},[581,588],{"type":23,"tag":568,"props":582,"children":585},{"href":583,"rel":584},"https://registry.terraform.io/providers/hashicorp/aws/latest/docs",[572],[586],{"type":28,"value":587},"AWS Provider Documentation",{"type":28,"value":589},": If you plan to use Terraform with AWS, the official AWS Provider documentation provides comprehensive information on configuring and managing AWS resources using Terraform.",{"type":23,"tag":58,"props":591,"children":592},{},[593,600],{"type":23,"tag":568,"props":594,"children":597},{"href":595,"rel":596},"https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs",[572],[598],{"type":28,"value":599},"Azure Provider Documentation",{"type":28,"value":601},": For Azure users, the official Azure Provider documentation offers detailed guidance on working with Azure resources through Terraform.",{"type":23,"tag":58,"props":603,"children":604},{},[605,612],{"type":23,"tag":568,"props":606,"children":609},{"href":607,"rel":608},"https://registry.terraform.io/providers/hashicorp/google/latest/docs",[572],[610],{"type":28,"value":611},"Google Cloud Provider Documentation",{"type":28,"value":613},": If Google Cloud is your chosen platform, the official Google Cloud Provider documentation provides valuable insights into Terraform's integration with Google Cloud resources.",{"type":23,"tag":24,"props":615,"children":616},{},[617],{"type":28,"value":618},"These resources serve as essential references as you explore Terraform and its integration with various cloud providers. Whether you're just getting started or looking to dive deeper into specific topics, these official documents will be invaluable in your Terraform journey.",{"type":23,"tag":620,"props":621,"children":622},"style",{},[623],{"type":28,"value":624},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}",{"title":7,"searchDepth":334,"depth":334,"links":626},[627,628,629,630],{"id":33,"depth":356,"text":36},{"id":44,"depth":356,"text":47},{"id":288,"depth":356,"text":291},{"id":552,"depth":356,"text":555},"markdown","content:posts:terraform.md","content","posts/terraform.md","posts/terraform","md",[638,2052,2958],{"_path":639,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":640,"description":641,"date":642,"layout":11,"subtitle":643,"image":644,"optimized_image":644,"category":14,"tags":645,"author":18,"paginate":6,"body":651,"_type":631,"_id":2049,"_source":633,"_file":2050,"_stem":2051,"_extension":636},"/posts/gpt-sql-integration","Implementa un analizador de consultas en lenguaje natural para bases de datos SQL con GPT","Aprende a implementar un sistema que convierte consultas en lenguaje natural en sentencias SQL usando OpenAI GPT, con un tutorial paso a paso y ejemplos prácticos.","2025-01-15T11:00:00.000Z","Transforma preguntas naturales en consultas SQL automatizadas","/assets/img/uploads/gpt-sql-integration.png",[14,646,647,648,649,650],"gpt","openai","sql","ai","nlp",{"type":20,"children":652,"toc":2038},[653,662,669,687,693,698,738,750,766,772,777,988,994,999,1335,1341,1346,1697,1703,1708,1767,1773,1778,1959,1965,1983,1989,1994,2001,2034],{"type":23,"tag":654,"props":655,"children":656},"blockquote",{},[657],{"type":23,"tag":24,"props":658,"children":659},{},[660],{"type":28,"value":661},"Convertir preguntas naturales en consultas SQL de forma automática simplifica la interacción con bases de datos, permitiendo que usuarios sin conocimientos técnicos extraigan datos relevantes. En este tutorial, aprenderás a implementar esta solución utilizando la API de OpenAI GPT.",{"type":23,"tag":663,"props":664,"children":666},"h2",{"id":665},"requisitos-previos",[667],{"type":28,"value":668},"Requisitos Previos",{"type":23,"tag":54,"props":670,"children":671},{},[672,677,682],{"type":23,"tag":58,"props":673,"children":674},{},[675],{"type":28,"value":676},"Cuenta y clave API de OpenAI",{"type":23,"tag":58,"props":678,"children":679},{},[680],{"type":28,"value":681},"Python instalado en tu entorno",{"type":23,"tag":58,"props":683,"children":684},{},[685],{"type":28,"value":686},"Base de datos SQL (ej.: PostgreSQL, MySQL)",{"type":23,"tag":663,"props":688,"children":690},{"id":689},"paso-1-configuración-del-entorno",[691],{"type":28,"value":692},"Paso 1: Configuración del entorno",{"type":23,"tag":24,"props":694,"children":695},{},[696],{"type":28,"value":697},"Primero, instala las dependencias necesarias:",{"type":23,"tag":311,"props":699,"children":701},{"className":493,"code":700,"language":495,"meta":7,"style":7},"pip install openai python-dotenv sqlalchemy psycopg2-binary\n",[702],{"type":23,"tag":14,"props":703,"children":704},{"__ignoreMap":7},[705],{"type":23,"tag":321,"props":706,"children":707},{"class":323,"line":324},[708,713,718,723,728,733],{"type":23,"tag":321,"props":709,"children":710},{"style":338},[711],{"type":28,"value":712},"pip",{"type":23,"tag":321,"props":714,"children":715},{"style":371},[716],{"type":28,"value":717}," install",{"type":23,"tag":321,"props":719,"children":720},{"style":371},[721],{"type":28,"value":722}," openai",{"type":23,"tag":321,"props":724,"children":725},{"style":371},[726],{"type":28,"value":727}," python-dotenv",{"type":23,"tag":321,"props":729,"children":730},{"style":371},[731],{"type":28,"value":732}," sqlalchemy",{"type":23,"tag":321,"props":734,"children":735},{"style":371},[736],{"type":28,"value":737}," psycopg2-binary\n",{"type":23,"tag":24,"props":739,"children":740},{},[741,743,749],{"type":28,"value":742},"Guarda tu clave API en un archivo ",{"type":23,"tag":14,"props":744,"children":746},{"className":745},[],[747],{"type":28,"value":748},".env",{"type":28,"value":68},{"type":23,"tag":311,"props":751,"children":755},{"className":752,"code":753,"language":754,"meta":7,"style":7},"language-env shiki shiki-themes github-dark github-light","OPENAI_API_KEY='tu-api-key'\n","env",[756],{"type":23,"tag":14,"props":757,"children":758},{"__ignoreMap":7},[759],{"type":23,"tag":321,"props":760,"children":761},{"class":323,"line":324},[762],{"type":23,"tag":321,"props":763,"children":764},{},[765],{"type":28,"value":753},{"type":23,"tag":663,"props":767,"children":769},{"id":768},"paso-2-conexión-a-la-base-de-datos",[770],{"type":28,"value":771},"Paso 2: Conexión a la base de datos",{"type":23,"tag":24,"props":773,"children":774},{},[775],{"type":28,"value":776},"Utiliza SQLAlchemy para conectarte a tu base de datos:",{"type":23,"tag":311,"props":778,"children":782},{"className":779,"code":780,"language":781,"meta":7,"style":7},"language-python shiki shiki-themes github-dark github-light","from sqlalchemy import create_engine\nfrom sqlalchemy.orm import sessionmaker\nimport os\nfrom dotenv import load_dotenv\n\nload_dotenv()\n\nDATABASE_URL = os.getenv(\"DATABASE_URL\")\nengine = create_engine(DATABASE_URL)\nSession = sessionmaker(bind=engine)\nsession = Session()\n","python",[783],{"type":23,"tag":14,"props":784,"children":785},{"__ignoreMap":7},[786,809,830,842,863,870,878,885,912,938,970],{"type":23,"tag":321,"props":787,"children":788},{"class":323,"line":324},[789,794,799,804],{"type":23,"tag":321,"props":790,"children":791},{"style":365},[792],{"type":28,"value":793},"from",{"type":23,"tag":321,"props":795,"children":796},{"style":350},[797],{"type":28,"value":798}," sqlalchemy ",{"type":23,"tag":321,"props":800,"children":801},{"style":365},[802],{"type":28,"value":803},"import",{"type":23,"tag":321,"props":805,"children":806},{"style":350},[807],{"type":28,"value":808}," create_engine\n",{"type":23,"tag":321,"props":810,"children":811},{"class":323,"line":334},[812,816,821,825],{"type":23,"tag":321,"props":813,"children":814},{"style":365},[815],{"type":28,"value":793},{"type":23,"tag":321,"props":817,"children":818},{"style":350},[819],{"type":28,"value":820}," sqlalchemy.orm ",{"type":23,"tag":321,"props":822,"children":823},{"style":365},[824],{"type":28,"value":803},{"type":23,"tag":321,"props":826,"children":827},{"style":350},[828],{"type":28,"value":829}," sessionmaker\n",{"type":23,"tag":321,"props":831,"children":832},{"class":323,"line":356},[833,837],{"type":23,"tag":321,"props":834,"children":835},{"style":365},[836],{"type":28,"value":803},{"type":23,"tag":321,"props":838,"children":839},{"style":350},[840],{"type":28,"value":841}," os\n",{"type":23,"tag":321,"props":843,"children":844},{"class":323,"line":382},[845,849,854,858],{"type":23,"tag":321,"props":846,"children":847},{"style":365},[848],{"type":28,"value":793},{"type":23,"tag":321,"props":850,"children":851},{"style":350},[852],{"type":28,"value":853}," dotenv ",{"type":23,"tag":321,"props":855,"children":856},{"style":365},[857],{"type":28,"value":803},{"type":23,"tag":321,"props":859,"children":860},{"style":350},[861],{"type":28,"value":862}," load_dotenv\n",{"type":23,"tag":321,"props":864,"children":865},{"class":323,"line":391},[866],{"type":23,"tag":321,"props":867,"children":868},{"emptyLinePlaceholder":395},[869],{"type":28,"value":398},{"type":23,"tag":321,"props":871,"children":872},{"class":323,"line":401},[873],{"type":23,"tag":321,"props":874,"children":875},{"style":350},[876],{"type":28,"value":877},"load_dotenv()\n",{"type":23,"tag":321,"props":879,"children":880},{"class":323,"line":410},[881],{"type":23,"tag":321,"props":882,"children":883},{"emptyLinePlaceholder":395},[884],{"type":28,"value":398},{"type":23,"tag":321,"props":886,"children":887},{"class":323,"line":433},[888,893,897,902,907],{"type":23,"tag":321,"props":889,"children":890},{"style":344},[891],{"type":28,"value":892},"DATABASE_URL",{"type":23,"tag":321,"props":894,"children":895},{"style":365},[896],{"type":28,"value":368},{"type":23,"tag":321,"props":898,"children":899},{"style":350},[900],{"type":28,"value":901}," os.getenv(",{"type":23,"tag":321,"props":903,"children":904},{"style":371},[905],{"type":28,"value":906},"\"DATABASE_URL\"",{"type":23,"tag":321,"props":908,"children":909},{"style":350},[910],{"type":28,"value":911},")\n",{"type":23,"tag":321,"props":913,"children":914},{"class":323,"line":451},[915,920,925,930,934],{"type":23,"tag":321,"props":916,"children":917},{"style":350},[918],{"type":28,"value":919},"engine ",{"type":23,"tag":321,"props":921,"children":922},{"style":365},[923],{"type":28,"value":924},"=",{"type":23,"tag":321,"props":926,"children":927},{"style":350},[928],{"type":28,"value":929}," create_engine(",{"type":23,"tag":321,"props":931,"children":932},{"style":344},[933],{"type":28,"value":892},{"type":23,"tag":321,"props":935,"children":936},{"style":350},[937],{"type":28,"value":911},{"type":23,"tag":321,"props":939,"children":940},{"class":323,"line":475},[941,946,950,955,961,965],{"type":23,"tag":321,"props":942,"children":943},{"style":350},[944],{"type":28,"value":945},"Session ",{"type":23,"tag":321,"props":947,"children":948},{"style":365},[949],{"type":28,"value":924},{"type":23,"tag":321,"props":951,"children":952},{"style":350},[953],{"type":28,"value":954}," sessionmaker(",{"type":23,"tag":321,"props":956,"children":958},{"style":957},"--shiki-default:#FFAB70;--shiki-light:#E36209",[959],{"type":28,"value":960},"bind",{"type":23,"tag":321,"props":962,"children":963},{"style":365},[964],{"type":28,"value":924},{"type":23,"tag":321,"props":966,"children":967},{"style":350},[968],{"type":28,"value":969},"engine)\n",{"type":23,"tag":321,"props":971,"children":973},{"class":323,"line":972},11,[974,979,983],{"type":23,"tag":321,"props":975,"children":976},{"style":350},[977],{"type":28,"value":978},"session ",{"type":23,"tag":321,"props":980,"children":981},{"style":365},[982],{"type":28,"value":924},{"type":23,"tag":321,"props":984,"children":985},{"style":350},[986],{"type":28,"value":987}," Session()\n",{"type":23,"tag":663,"props":989,"children":991},{"id":990},"paso-3-obtener-esquema-de-la-base-de-datos",[992],{"type":28,"value":993},"Paso 3: Obtener esquema de la base de datos",{"type":23,"tag":24,"props":995,"children":996},{},[997],{"type":28,"value":998},"Genera una descripción del esquema que será utilizada por GPT:",{"type":23,"tag":311,"props":1000,"children":1002},{"className":779,"code":1001,"language":781,"meta":7,"style":7},"from sqlalchemy import inspect\n\ndef get_database_schema(engine):\n    inspector = inspect(engine)\n    schema_description = \"\"\n    for table_name in inspector.get_table_names():\n        schema_description += f\"Table: {table_name}\\n\"\n        for column in inspector.get_columns(table_name):\n            schema_description += f\"- {column['name']} ({column['type']})\\n\"\n        schema_description += \"\\n\"\n    return schema_description\n\nschema_description = get_database_schema(engine)\nprint(schema_description)\n",[1003],{"type":23,"tag":14,"props":1004,"children":1005},{"__ignoreMap":7},[1006,1026,1033,1051,1068,1085,1108,1151,1173,1258,1282,1295,1303,1321],{"type":23,"tag":321,"props":1007,"children":1008},{"class":323,"line":324},[1009,1013,1017,1021],{"type":23,"tag":321,"props":1010,"children":1011},{"style":365},[1012],{"type":28,"value":793},{"type":23,"tag":321,"props":1014,"children":1015},{"style":350},[1016],{"type":28,"value":798},{"type":23,"tag":321,"props":1018,"children":1019},{"style":365},[1020],{"type":28,"value":803},{"type":23,"tag":321,"props":1022,"children":1023},{"style":350},[1024],{"type":28,"value":1025}," inspect\n",{"type":23,"tag":321,"props":1027,"children":1028},{"class":323,"line":334},[1029],{"type":23,"tag":321,"props":1030,"children":1031},{"emptyLinePlaceholder":395},[1032],{"type":28,"value":398},{"type":23,"tag":321,"props":1034,"children":1035},{"class":323,"line":356},[1036,1041,1046],{"type":23,"tag":321,"props":1037,"children":1038},{"style":365},[1039],{"type":28,"value":1040},"def",{"type":23,"tag":321,"props":1042,"children":1043},{"style":338},[1044],{"type":28,"value":1045}," get_database_schema",{"type":23,"tag":321,"props":1047,"children":1048},{"style":350},[1049],{"type":28,"value":1050},"(engine):\n",{"type":23,"tag":321,"props":1052,"children":1053},{"class":323,"line":382},[1054,1059,1063],{"type":23,"tag":321,"props":1055,"children":1056},{"style":350},[1057],{"type":28,"value":1058},"    inspector ",{"type":23,"tag":321,"props":1060,"children":1061},{"style":365},[1062],{"type":28,"value":924},{"type":23,"tag":321,"props":1064,"children":1065},{"style":350},[1066],{"type":28,"value":1067}," inspect(engine)\n",{"type":23,"tag":321,"props":1069,"children":1070},{"class":323,"line":391},[1071,1076,1080],{"type":23,"tag":321,"props":1072,"children":1073},{"style":350},[1074],{"type":28,"value":1075},"    schema_description ",{"type":23,"tag":321,"props":1077,"children":1078},{"style":365},[1079],{"type":28,"value":924},{"type":23,"tag":321,"props":1081,"children":1082},{"style":371},[1083],{"type":28,"value":1084}," \"\"\n",{"type":23,"tag":321,"props":1086,"children":1087},{"class":323,"line":401},[1088,1093,1098,1103],{"type":23,"tag":321,"props":1089,"children":1090},{"style":365},[1091],{"type":28,"value":1092},"    for",{"type":23,"tag":321,"props":1094,"children":1095},{"style":350},[1096],{"type":28,"value":1097}," table_name ",{"type":23,"tag":321,"props":1099,"children":1100},{"style":365},[1101],{"type":28,"value":1102},"in",{"type":23,"tag":321,"props":1104,"children":1105},{"style":350},[1106],{"type":28,"value":1107}," inspector.get_table_names():\n",{"type":23,"tag":321,"props":1109,"children":1110},{"class":323,"line":410},[1111,1116,1121,1126,1131,1136,1141,1146],{"type":23,"tag":321,"props":1112,"children":1113},{"style":350},[1114],{"type":28,"value":1115},"        schema_description ",{"type":23,"tag":321,"props":1117,"children":1118},{"style":365},[1119],{"type":28,"value":1120},"+=",{"type":23,"tag":321,"props":1122,"children":1123},{"style":365},[1124],{"type":28,"value":1125}," f",{"type":23,"tag":321,"props":1127,"children":1128},{"style":371},[1129],{"type":28,"value":1130},"\"Table: ",{"type":23,"tag":321,"props":1132,"children":1133},{"style":344},[1134],{"type":28,"value":1135},"{",{"type":23,"tag":321,"props":1137,"children":1138},{"style":350},[1139],{"type":28,"value":1140},"table_name",{"type":23,"tag":321,"props":1142,"children":1143},{"style":344},[1144],{"type":28,"value":1145},"}\\n",{"type":23,"tag":321,"props":1147,"children":1148},{"style":371},[1149],{"type":28,"value":1150},"\"\n",{"type":23,"tag":321,"props":1152,"children":1153},{"class":323,"line":433},[1154,1159,1164,1168],{"type":23,"tag":321,"props":1155,"children":1156},{"style":365},[1157],{"type":28,"value":1158},"        for",{"type":23,"tag":321,"props":1160,"children":1161},{"style":350},[1162],{"type":28,"value":1163}," column ",{"type":23,"tag":321,"props":1165,"children":1166},{"style":365},[1167],{"type":28,"value":1102},{"type":23,"tag":321,"props":1169,"children":1170},{"style":350},[1171],{"type":28,"value":1172}," inspector.get_columns(table_name):\n",{"type":23,"tag":321,"props":1174,"children":1175},{"class":323,"line":451},[1176,1181,1185,1189,1194,1198,1203,1208,1213,1218,1223,1227,1231,1236,1240,1244,1249,1254],{"type":23,"tag":321,"props":1177,"children":1178},{"style":350},[1179],{"type":28,"value":1180},"            schema_description ",{"type":23,"tag":321,"props":1182,"children":1183},{"style":365},[1184],{"type":28,"value":1120},{"type":23,"tag":321,"props":1186,"children":1187},{"style":365},[1188],{"type":28,"value":1125},{"type":23,"tag":321,"props":1190,"children":1191},{"style":371},[1192],{"type":28,"value":1193},"\"- ",{"type":23,"tag":321,"props":1195,"children":1196},{"style":344},[1197],{"type":28,"value":1135},{"type":23,"tag":321,"props":1199,"children":1200},{"style":350},[1201],{"type":28,"value":1202},"column[",{"type":23,"tag":321,"props":1204,"children":1205},{"style":371},[1206],{"type":28,"value":1207},"'name'",{"type":23,"tag":321,"props":1209,"children":1210},{"style":350},[1211],{"type":28,"value":1212},"]",{"type":23,"tag":321,"props":1214,"children":1215},{"style":344},[1216],{"type":28,"value":1217},"}",{"type":23,"tag":321,"props":1219,"children":1220},{"style":371},[1221],{"type":28,"value":1222}," (",{"type":23,"tag":321,"props":1224,"children":1225},{"style":344},[1226],{"type":28,"value":1135},{"type":23,"tag":321,"props":1228,"children":1229},{"style":350},[1230],{"type":28,"value":1202},{"type":23,"tag":321,"props":1232,"children":1233},{"style":371},[1234],{"type":28,"value":1235},"'type'",{"type":23,"tag":321,"props":1237,"children":1238},{"style":350},[1239],{"type":28,"value":1212},{"type":23,"tag":321,"props":1241,"children":1242},{"style":344},[1243],{"type":28,"value":1217},{"type":23,"tag":321,"props":1245,"children":1246},{"style":371},[1247],{"type":28,"value":1248},")",{"type":23,"tag":321,"props":1250,"children":1251},{"style":344},[1252],{"type":28,"value":1253},"\\n",{"type":23,"tag":321,"props":1255,"children":1256},{"style":371},[1257],{"type":28,"value":1150},{"type":23,"tag":321,"props":1259,"children":1260},{"class":323,"line":475},[1261,1265,1269,1274,1278],{"type":23,"tag":321,"props":1262,"children":1263},{"style":350},[1264],{"type":28,"value":1115},{"type":23,"tag":321,"props":1266,"children":1267},{"style":365},[1268],{"type":28,"value":1120},{"type":23,"tag":321,"props":1270,"children":1271},{"style":371},[1272],{"type":28,"value":1273}," \"",{"type":23,"tag":321,"props":1275,"children":1276},{"style":344},[1277],{"type":28,"value":1253},{"type":23,"tag":321,"props":1279,"children":1280},{"style":371},[1281],{"type":28,"value":1150},{"type":23,"tag":321,"props":1283,"children":1284},{"class":323,"line":972},[1285,1290],{"type":23,"tag":321,"props":1286,"children":1287},{"style":365},[1288],{"type":28,"value":1289},"    return",{"type":23,"tag":321,"props":1291,"children":1292},{"style":350},[1293],{"type":28,"value":1294}," schema_description\n",{"type":23,"tag":321,"props":1296,"children":1298},{"class":323,"line":1297},12,[1299],{"type":23,"tag":321,"props":1300,"children":1301},{"emptyLinePlaceholder":395},[1302],{"type":28,"value":398},{"type":23,"tag":321,"props":1304,"children":1306},{"class":323,"line":1305},13,[1307,1312,1316],{"type":23,"tag":321,"props":1308,"children":1309},{"style":350},[1310],{"type":28,"value":1311},"schema_description ",{"type":23,"tag":321,"props":1313,"children":1314},{"style":365},[1315],{"type":28,"value":924},{"type":23,"tag":321,"props":1317,"children":1318},{"style":350},[1319],{"type":28,"value":1320}," get_database_schema(engine)\n",{"type":23,"tag":321,"props":1322,"children":1324},{"class":323,"line":1323},14,[1325,1330],{"type":23,"tag":321,"props":1326,"children":1327},{"style":344},[1328],{"type":28,"value":1329},"print",{"type":23,"tag":321,"props":1331,"children":1332},{"style":350},[1333],{"type":28,"value":1334},"(schema_description)\n",{"type":23,"tag":663,"props":1336,"children":1338},{"id":1337},"paso-4-preparar-la-consulta-con-gpt",[1339],{"type":28,"value":1340},"Paso 4: Preparar la consulta con GPT",{"type":23,"tag":24,"props":1342,"children":1343},{},[1344],{"type":28,"value":1345},"Utiliza la API de OpenAI para transformar preguntas en consultas SQL, incluyendo el esquema de la base de datos:",{"type":23,"tag":311,"props":1347,"children":1349},{"className":779,"code":1348,"language":781,"meta":7,"style":7},"import openai\nimport os\n\nopenai.api_key = os.getenv(\"OPENAI_API_KEY\")\n\ndef generate_sql(question, schema):\n    response = openai.ChatCompletion.create(\n        model=\"gpt-4\",\n        messages=[\n            {\"role\": \"system\", \"content\": f\"Convierte preguntas en lenguaje natural a consultas SQL. Esquema de la base de datos:\\n{schema}\"},\n            {\"role\": \"user\", \"content\": question}\n        ]\n    )\n    sql_query = response.choices[0].message.content.strip()\n    return sql_query\n\nquery = generate_sql(\"¿Cuántos usuarios se registraron el último mes?\", schema_description)\nprint(query)\n",[1350],{"type":23,"tag":14,"props":1351,"children":1352},{"__ignoreMap":7},[1353,1365,1376,1383,1408,1415,1432,1449,1471,1488,1559,1592,1600,1608,1635,1648,1656,1684],{"type":23,"tag":321,"props":1354,"children":1355},{"class":323,"line":324},[1356,1360],{"type":23,"tag":321,"props":1357,"children":1358},{"style":365},[1359],{"type":28,"value":803},{"type":23,"tag":321,"props":1361,"children":1362},{"style":350},[1363],{"type":28,"value":1364}," openai\n",{"type":23,"tag":321,"props":1366,"children":1367},{"class":323,"line":334},[1368,1372],{"type":23,"tag":321,"props":1369,"children":1370},{"style":365},[1371],{"type":28,"value":803},{"type":23,"tag":321,"props":1373,"children":1374},{"style":350},[1375],{"type":28,"value":841},{"type":23,"tag":321,"props":1377,"children":1378},{"class":323,"line":356},[1379],{"type":23,"tag":321,"props":1380,"children":1381},{"emptyLinePlaceholder":395},[1382],{"type":28,"value":398},{"type":23,"tag":321,"props":1384,"children":1385},{"class":323,"line":382},[1386,1391,1395,1399,1404],{"type":23,"tag":321,"props":1387,"children":1388},{"style":350},[1389],{"type":28,"value":1390},"openai.api_key ",{"type":23,"tag":321,"props":1392,"children":1393},{"style":365},[1394],{"type":28,"value":924},{"type":23,"tag":321,"props":1396,"children":1397},{"style":350},[1398],{"type":28,"value":901},{"type":23,"tag":321,"props":1400,"children":1401},{"style":371},[1402],{"type":28,"value":1403},"\"OPENAI_API_KEY\"",{"type":23,"tag":321,"props":1405,"children":1406},{"style":350},[1407],{"type":28,"value":911},{"type":23,"tag":321,"props":1409,"children":1410},{"class":323,"line":391},[1411],{"type":23,"tag":321,"props":1412,"children":1413},{"emptyLinePlaceholder":395},[1414],{"type":28,"value":398},{"type":23,"tag":321,"props":1416,"children":1417},{"class":323,"line":401},[1418,1422,1427],{"type":23,"tag":321,"props":1419,"children":1420},{"style":365},[1421],{"type":28,"value":1040},{"type":23,"tag":321,"props":1423,"children":1424},{"style":338},[1425],{"type":28,"value":1426}," generate_sql",{"type":23,"tag":321,"props":1428,"children":1429},{"style":350},[1430],{"type":28,"value":1431},"(question, schema):\n",{"type":23,"tag":321,"props":1433,"children":1434},{"class":323,"line":410},[1435,1440,1444],{"type":23,"tag":321,"props":1436,"children":1437},{"style":350},[1438],{"type":28,"value":1439},"    response ",{"type":23,"tag":321,"props":1441,"children":1442},{"style":365},[1443],{"type":28,"value":924},{"type":23,"tag":321,"props":1445,"children":1446},{"style":350},[1447],{"type":28,"value":1448}," openai.ChatCompletion.create(\n",{"type":23,"tag":321,"props":1450,"children":1451},{"class":323,"line":433},[1452,1457,1461,1466],{"type":23,"tag":321,"props":1453,"children":1454},{"style":957},[1455],{"type":28,"value":1456},"        model",{"type":23,"tag":321,"props":1458,"children":1459},{"style":365},[1460],{"type":28,"value":924},{"type":23,"tag":321,"props":1462,"children":1463},{"style":371},[1464],{"type":28,"value":1465},"\"gpt-4\"",{"type":23,"tag":321,"props":1467,"children":1468},{"style":350},[1469],{"type":28,"value":1470},",\n",{"type":23,"tag":321,"props":1472,"children":1473},{"class":323,"line":451},[1474,1479,1483],{"type":23,"tag":321,"props":1475,"children":1476},{"style":957},[1477],{"type":28,"value":1478},"        messages",{"type":23,"tag":321,"props":1480,"children":1481},{"style":365},[1482],{"type":28,"value":924},{"type":23,"tag":321,"props":1484,"children":1485},{"style":350},[1486],{"type":28,"value":1487},"[\n",{"type":23,"tag":321,"props":1489,"children":1490},{"class":323,"line":475},[1491,1496,1501,1506,1511,1516,1521,1525,1530,1535,1540,1545,1549,1554],{"type":23,"tag":321,"props":1492,"children":1493},{"style":350},[1494],{"type":28,"value":1495},"            {",{"type":23,"tag":321,"props":1497,"children":1498},{"style":371},[1499],{"type":28,"value":1500},"\"role\"",{"type":23,"tag":321,"props":1502,"children":1503},{"style":350},[1504],{"type":28,"value":1505},": ",{"type":23,"tag":321,"props":1507,"children":1508},{"style":371},[1509],{"type":28,"value":1510},"\"system\"",{"type":23,"tag":321,"props":1512,"children":1513},{"style":350},[1514],{"type":28,"value":1515},", ",{"type":23,"tag":321,"props":1517,"children":1518},{"style":371},[1519],{"type":28,"value":1520},"\"content\"",{"type":23,"tag":321,"props":1522,"children":1523},{"style":350},[1524],{"type":28,"value":1505},{"type":23,"tag":321,"props":1526,"children":1527},{"style":365},[1528],{"type":28,"value":1529},"f",{"type":23,"tag":321,"props":1531,"children":1532},{"style":371},[1533],{"type":28,"value":1534},"\"Convierte preguntas en lenguaje natural a consultas SQL. Esquema de la base de datos:",{"type":23,"tag":321,"props":1536,"children":1537},{"style":344},[1538],{"type":28,"value":1539},"\\n{",{"type":23,"tag":321,"props":1541,"children":1542},{"style":350},[1543],{"type":28,"value":1544},"schema",{"type":23,"tag":321,"props":1546,"children":1547},{"style":344},[1548],{"type":28,"value":1217},{"type":23,"tag":321,"props":1550,"children":1551},{"style":371},[1552],{"type":28,"value":1553},"\"",{"type":23,"tag":321,"props":1555,"children":1556},{"style":350},[1557],{"type":28,"value":1558},"},\n",{"type":23,"tag":321,"props":1560,"children":1561},{"class":323,"line":972},[1562,1566,1570,1574,1579,1583,1587],{"type":23,"tag":321,"props":1563,"children":1564},{"style":350},[1565],{"type":28,"value":1495},{"type":23,"tag":321,"props":1567,"children":1568},{"style":371},[1569],{"type":28,"value":1500},{"type":23,"tag":321,"props":1571,"children":1572},{"style":350},[1573],{"type":28,"value":1505},{"type":23,"tag":321,"props":1575,"children":1576},{"style":371},[1577],{"type":28,"value":1578},"\"user\"",{"type":23,"tag":321,"props":1580,"children":1581},{"style":350},[1582],{"type":28,"value":1515},{"type":23,"tag":321,"props":1584,"children":1585},{"style":371},[1586],{"type":28,"value":1520},{"type":23,"tag":321,"props":1588,"children":1589},{"style":350},[1590],{"type":28,"value":1591},": question}\n",{"type":23,"tag":321,"props":1593,"children":1594},{"class":323,"line":1297},[1595],{"type":23,"tag":321,"props":1596,"children":1597},{"style":350},[1598],{"type":28,"value":1599},"        ]\n",{"type":23,"tag":321,"props":1601,"children":1602},{"class":323,"line":1305},[1603],{"type":23,"tag":321,"props":1604,"children":1605},{"style":350},[1606],{"type":28,"value":1607},"    )\n",{"type":23,"tag":321,"props":1609,"children":1610},{"class":323,"line":1323},[1611,1616,1620,1625,1630],{"type":23,"tag":321,"props":1612,"children":1613},{"style":350},[1614],{"type":28,"value":1615},"    sql_query ",{"type":23,"tag":321,"props":1617,"children":1618},{"style":365},[1619],{"type":28,"value":924},{"type":23,"tag":321,"props":1621,"children":1622},{"style":350},[1623],{"type":28,"value":1624}," response.choices[",{"type":23,"tag":321,"props":1626,"children":1627},{"style":344},[1628],{"type":28,"value":1629},"0",{"type":23,"tag":321,"props":1631,"children":1632},{"style":350},[1633],{"type":28,"value":1634},"].message.content.strip()\n",{"type":23,"tag":321,"props":1636,"children":1638},{"class":323,"line":1637},15,[1639,1643],{"type":23,"tag":321,"props":1640,"children":1641},{"style":365},[1642],{"type":28,"value":1289},{"type":23,"tag":321,"props":1644,"children":1645},{"style":350},[1646],{"type":28,"value":1647}," sql_query\n",{"type":23,"tag":321,"props":1649,"children":1651},{"class":323,"line":1650},16,[1652],{"type":23,"tag":321,"props":1653,"children":1654},{"emptyLinePlaceholder":395},[1655],{"type":28,"value":398},{"type":23,"tag":321,"props":1657,"children":1659},{"class":323,"line":1658},17,[1660,1665,1669,1674,1679],{"type":23,"tag":321,"props":1661,"children":1662},{"style":350},[1663],{"type":28,"value":1664},"query ",{"type":23,"tag":321,"props":1666,"children":1667},{"style":365},[1668],{"type":28,"value":924},{"type":23,"tag":321,"props":1670,"children":1671},{"style":350},[1672],{"type":28,"value":1673}," generate_sql(",{"type":23,"tag":321,"props":1675,"children":1676},{"style":371},[1677],{"type":28,"value":1678},"\"¿Cuántos usuarios se registraron el último mes?\"",{"type":23,"tag":321,"props":1680,"children":1681},{"style":350},[1682],{"type":28,"value":1683},", schema_description)\n",{"type":23,"tag":321,"props":1685,"children":1687},{"class":323,"line":1686},18,[1688,1692],{"type":23,"tag":321,"props":1689,"children":1690},{"style":344},[1691],{"type":28,"value":1329},{"type":23,"tag":321,"props":1693,"children":1694},{"style":350},[1695],{"type":28,"value":1696},"(query)\n",{"type":23,"tag":663,"props":1698,"children":1700},{"id":1699},"paso-5-ejecutar-consultas-generadas",[1701],{"type":28,"value":1702},"Paso 5: Ejecutar consultas generadas",{"type":23,"tag":24,"props":1704,"children":1705},{},[1706],{"type":28,"value":1707},"Ejecuta la consulta generada y obtiene resultados:",{"type":23,"tag":311,"props":1709,"children":1711},{"className":779,"code":1710,"language":781,"meta":7,"style":7},"result = session.execute(query)\nfor row in result:\n    print(row)\n",[1712],{"type":23,"tag":14,"props":1713,"children":1714},{"__ignoreMap":7},[1715,1732,1754],{"type":23,"tag":321,"props":1716,"children":1717},{"class":323,"line":324},[1718,1723,1727],{"type":23,"tag":321,"props":1719,"children":1720},{"style":350},[1721],{"type":28,"value":1722},"result ",{"type":23,"tag":321,"props":1724,"children":1725},{"style":365},[1726],{"type":28,"value":924},{"type":23,"tag":321,"props":1728,"children":1729},{"style":350},[1730],{"type":28,"value":1731}," session.execute(query)\n",{"type":23,"tag":321,"props":1733,"children":1734},{"class":323,"line":334},[1735,1740,1745,1749],{"type":23,"tag":321,"props":1736,"children":1737},{"style":365},[1738],{"type":28,"value":1739},"for",{"type":23,"tag":321,"props":1741,"children":1742},{"style":350},[1743],{"type":28,"value":1744}," row ",{"type":23,"tag":321,"props":1746,"children":1747},{"style":365},[1748],{"type":28,"value":1102},{"type":23,"tag":321,"props":1750,"children":1751},{"style":350},[1752],{"type":28,"value":1753}," result:\n",{"type":23,"tag":321,"props":1755,"children":1756},{"class":323,"line":356},[1757,1762],{"type":23,"tag":321,"props":1758,"children":1759},{"style":344},[1760],{"type":28,"value":1761},"    print",{"type":23,"tag":321,"props":1763,"children":1764},{"style":350},[1765],{"type":28,"value":1766},"(row)\n",{"type":23,"tag":663,"props":1768,"children":1770},{"id":1769},"paso-6-manejo-de-errores-y-seguridad",[1771],{"type":28,"value":1772},"Paso 6: Manejo de errores y seguridad",{"type":23,"tag":24,"props":1774,"children":1775},{},[1776],{"type":28,"value":1777},"Para evitar problemas con consultas inseguras o errores, siempre valida las consultas generadas por GPT antes de ejecutarlas directamente:",{"type":23,"tag":311,"props":1779,"children":1781},{"className":779,"code":1780,"language":781,"meta":7,"style":7},"def execute_safe_query(sql_query):\n    try:\n        result = session.execute(sql_query)\n        return result.fetchall()\n    except Exception as e:\n        print(f\"Error al ejecutar consulta: {e}\")\n        return None\n\nresults = execute_safe_query(query)\nprint(results)\n",[1782],{"type":23,"tag":14,"props":1783,"children":1784},{"__ignoreMap":7},[1785,1802,1815,1832,1845,1868,1911,1923,1930,1947],{"type":23,"tag":321,"props":1786,"children":1787},{"class":323,"line":324},[1788,1792,1797],{"type":23,"tag":321,"props":1789,"children":1790},{"style":365},[1791],{"type":28,"value":1040},{"type":23,"tag":321,"props":1793,"children":1794},{"style":338},[1795],{"type":28,"value":1796}," execute_safe_query",{"type":23,"tag":321,"props":1798,"children":1799},{"style":350},[1800],{"type":28,"value":1801},"(sql_query):\n",{"type":23,"tag":321,"props":1803,"children":1804},{"class":323,"line":334},[1805,1810],{"type":23,"tag":321,"props":1806,"children":1807},{"style":365},[1808],{"type":28,"value":1809},"    try",{"type":23,"tag":321,"props":1811,"children":1812},{"style":350},[1813],{"type":28,"value":1814},":\n",{"type":23,"tag":321,"props":1816,"children":1817},{"class":323,"line":356},[1818,1823,1827],{"type":23,"tag":321,"props":1819,"children":1820},{"style":350},[1821],{"type":28,"value":1822},"        result ",{"type":23,"tag":321,"props":1824,"children":1825},{"style":365},[1826],{"type":28,"value":924},{"type":23,"tag":321,"props":1828,"children":1829},{"style":350},[1830],{"type":28,"value":1831}," session.execute(sql_query)\n",{"type":23,"tag":321,"props":1833,"children":1834},{"class":323,"line":382},[1835,1840],{"type":23,"tag":321,"props":1836,"children":1837},{"style":365},[1838],{"type":28,"value":1839},"        return",{"type":23,"tag":321,"props":1841,"children":1842},{"style":350},[1843],{"type":28,"value":1844}," result.fetchall()\n",{"type":23,"tag":321,"props":1846,"children":1847},{"class":323,"line":391},[1848,1853,1858,1863],{"type":23,"tag":321,"props":1849,"children":1850},{"style":365},[1851],{"type":28,"value":1852},"    except",{"type":23,"tag":321,"props":1854,"children":1855},{"style":344},[1856],{"type":28,"value":1857}," Exception",{"type":23,"tag":321,"props":1859,"children":1860},{"style":365},[1861],{"type":28,"value":1862}," as",{"type":23,"tag":321,"props":1864,"children":1865},{"style":350},[1866],{"type":28,"value":1867}," e:\n",{"type":23,"tag":321,"props":1869,"children":1870},{"class":323,"line":401},[1871,1876,1881,1885,1890,1894,1899,1903,1907],{"type":23,"tag":321,"props":1872,"children":1873},{"style":344},[1874],{"type":28,"value":1875},"        print",{"type":23,"tag":321,"props":1877,"children":1878},{"style":350},[1879],{"type":28,"value":1880},"(",{"type":23,"tag":321,"props":1882,"children":1883},{"style":365},[1884],{"type":28,"value":1529},{"type":23,"tag":321,"props":1886,"children":1887},{"style":371},[1888],{"type":28,"value":1889},"\"Error al ejecutar consulta: ",{"type":23,"tag":321,"props":1891,"children":1892},{"style":344},[1893],{"type":28,"value":1135},{"type":23,"tag":321,"props":1895,"children":1896},{"style":350},[1897],{"type":28,"value":1898},"e",{"type":23,"tag":321,"props":1900,"children":1901},{"style":344},[1902],{"type":28,"value":1217},{"type":23,"tag":321,"props":1904,"children":1905},{"style":371},[1906],{"type":28,"value":1553},{"type":23,"tag":321,"props":1908,"children":1909},{"style":350},[1910],{"type":28,"value":911},{"type":23,"tag":321,"props":1912,"children":1913},{"class":323,"line":410},[1914,1918],{"type":23,"tag":321,"props":1915,"children":1916},{"style":365},[1917],{"type":28,"value":1839},{"type":23,"tag":321,"props":1919,"children":1920},{"style":344},[1921],{"type":28,"value":1922}," None\n",{"type":23,"tag":321,"props":1924,"children":1925},{"class":323,"line":433},[1926],{"type":23,"tag":321,"props":1927,"children":1928},{"emptyLinePlaceholder":395},[1929],{"type":28,"value":398},{"type":23,"tag":321,"props":1931,"children":1932},{"class":323,"line":451},[1933,1938,1942],{"type":23,"tag":321,"props":1934,"children":1935},{"style":350},[1936],{"type":28,"value":1937},"results ",{"type":23,"tag":321,"props":1939,"children":1940},{"style":365},[1941],{"type":28,"value":924},{"type":23,"tag":321,"props":1943,"children":1944},{"style":350},[1945],{"type":28,"value":1946}," execute_safe_query(query)\n",{"type":23,"tag":321,"props":1948,"children":1949},{"class":323,"line":475},[1950,1954],{"type":23,"tag":321,"props":1951,"children":1952},{"style":344},[1953],{"type":28,"value":1329},{"type":23,"tag":321,"props":1955,"children":1956},{"style":350},[1957],{"type":28,"value":1958},"(results)\n",{"type":23,"tag":663,"props":1960,"children":1962},{"id":1961},"buenas-prácticas",[1963],{"type":28,"value":1964},"Buenas prácticas",{"type":23,"tag":54,"props":1966,"children":1967},{},[1968,1973,1978],{"type":23,"tag":58,"props":1969,"children":1970},{},[1971],{"type":28,"value":1972},"Siempre revisa o limita el acceso de los usuarios a consultas críticas o sensibles.",{"type":23,"tag":58,"props":1974,"children":1975},{},[1976],{"type":28,"value":1977},"Implementa validaciones adicionales para asegurar la integridad y seguridad de tu base de datos.",{"type":23,"tag":58,"props":1979,"children":1980},{},[1981],{"type":28,"value":1982},"Utiliza tokens y modelos específicos de OpenAI optimizados para tareas SQL.",{"type":23,"tag":663,"props":1984,"children":1986},{"id":1985},"conclusión",[1987],{"type":28,"value":1988},"Conclusión",{"type":23,"tag":24,"props":1990,"children":1991},{},[1992],{"type":28,"value":1993},"Utilizar GPT para transformar consultas en lenguaje natural a SQL facilita enormemente la accesibilidad a los datos. Implementando este sistema, podrás ofrecer una experiencia de usuario más amigable y eficiente.",{"type":23,"tag":1995,"props":1996,"children":1998},"h1",{"id":1997},"recursos-adicionales",[1999],{"type":28,"value":2000},"Recursos adicionales",{"type":23,"tag":54,"props":2002,"children":2003},{},[2004,2014,2024],{"type":23,"tag":58,"props":2005,"children":2006},{},[2007],{"type":23,"tag":568,"props":2008,"children":2011},{"href":2009,"rel":2010},"https://platform.openai.com/docs/api-reference",[572],[2012],{"type":28,"value":2013},"Documentación API OpenAI",{"type":23,"tag":58,"props":2015,"children":2016},{},[2017],{"type":23,"tag":568,"props":2018,"children":2021},{"href":2019,"rel":2020},"https://docs.sqlalchemy.org/en/20/",[572],[2022],{"type":28,"value":2023},"SQLAlchemy ORM Documentation",{"type":23,"tag":58,"props":2025,"children":2026},{},[2027],{"type":23,"tag":568,"props":2028,"children":2031},{"href":2029,"rel":2030},"https://pypi.org/project/python-dotenv/",[572],[2032],{"type":28,"value":2033},"Python Dotenv",{"type":23,"tag":620,"props":2035,"children":2036},{},[2037],{"type":28,"value":624},{"title":7,"searchDepth":334,"depth":334,"links":2039},[2040,2041,2042,2043,2044,2045,2046,2047,2048],{"id":665,"depth":334,"text":668},{"id":689,"depth":334,"text":692},{"id":768,"depth":334,"text":771},{"id":990,"depth":334,"text":993},{"id":1337,"depth":334,"text":1340},{"id":1699,"depth":334,"text":1702},{"id":1769,"depth":334,"text":1772},{"id":1961,"depth":334,"text":1964},{"id":1985,"depth":334,"text":1988},"content:posts:gpt-sql-integration.md","posts/gpt-sql-integration.md","posts/gpt-sql-integration",{"_path":2053,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":2054,"description":2055,"date":2056,"layout":11,"subtitle":2057,"image":2058,"optimized_image":2058,"category":14,"tags":2059,"author":18,"paginate":6,"body":2064,"_type":631,"_id":2955,"_source":633,"_file":2956,"_stem":2957,"_extension":636},"/posts/java-security-best-practices","Java Security Best Practices: Preventing Vulnerabilities and Threats","Explore essential security strategies for Java applications, addressing common vulnerabilities identified by OWASP Top 10 with practical examples.","2024-08-15T11:00:00.000Z","Practical Strategies to Safeguard Your Java Applications","/assets/img/uploads/java-security-best-practices.png",[14,2060,2061,2062,2063],"java","security","owasp","cybersecurity",{"type":20,"children":2065,"toc":2943},[2066,2074,2080,2085,2139,2144,2150,2155,2278,2283,2289,2294,2395,2401,2406,2529,2534,2540,2545,2570,2575,2581,2586,2602,2607,2613,2618,2701,2706,2712,2717,2837,2842,2848,2853,2886,2891,2897,2902,2906,2939],{"type":23,"tag":654,"props":2067,"children":2068},{},[2069],{"type":23,"tag":24,"props":2070,"children":2071},{},[2072],{"type":28,"value":2073},"Security is critical in software development. Java applications, like all software, face numerous potential vulnerabilities. In this article, we will explore essential security best practices, referencing the OWASP Top 10, and providing practical Java examples to help you protect your applications effectively.",{"type":23,"tag":663,"props":2075,"children":2077},{"id":2076},"understanding-owasp-top-10",[2078],{"type":28,"value":2079},"Understanding OWASP Top 10",{"type":23,"tag":24,"props":2081,"children":2082},{},[2083],{"type":28,"value":2084},"The OWASP Top 10 outlines the most critical web application security risks:",{"type":23,"tag":2086,"props":2087,"children":2088},"ol",{},[2089,2094,2099,2104,2109,2114,2119,2124,2129,2134],{"type":23,"tag":58,"props":2090,"children":2091},{},[2092],{"type":28,"value":2093},"Injection",{"type":23,"tag":58,"props":2095,"children":2096},{},[2097],{"type":28,"value":2098},"Broken Authentication",{"type":23,"tag":58,"props":2100,"children":2101},{},[2102],{"type":28,"value":2103},"Sensitive Data Exposure",{"type":23,"tag":58,"props":2105,"children":2106},{},[2107],{"type":28,"value":2108},"XML External Entities (XXE)",{"type":23,"tag":58,"props":2110,"children":2111},{},[2112],{"type":28,"value":2113},"Broken Access Control",{"type":23,"tag":58,"props":2115,"children":2116},{},[2117],{"type":28,"value":2118},"Security Misconfiguration",{"type":23,"tag":58,"props":2120,"children":2121},{},[2122],{"type":28,"value":2123},"Cross-Site Scripting (XSS)",{"type":23,"tag":58,"props":2125,"children":2126},{},[2127],{"type":28,"value":2128},"Insecure Deserialization",{"type":23,"tag":58,"props":2130,"children":2131},{},[2132],{"type":28,"value":2133},"Using Components with Known Vulnerabilities",{"type":23,"tag":58,"props":2135,"children":2136},{},[2137],{"type":28,"value":2138},"Insufficient Logging and Monitoring",{"type":23,"tag":24,"props":2140,"children":2141},{},[2142],{"type":28,"value":2143},"Let's delve into practical strategies and Java implementations for some of these threats.",{"type":23,"tag":663,"props":2145,"children":2147},{"id":2146},"_1-injection-prevention",[2148],{"type":28,"value":2149},"1. Injection Prevention",{"type":23,"tag":24,"props":2151,"children":2152},{},[2153],{"type":28,"value":2154},"Use Prepared Statements and parameterized queries:",{"type":23,"tag":311,"props":2156,"children":2159},{"className":2157,"code":2158,"language":2060,"meta":7,"style":7},"language-java shiki shiki-themes github-dark github-light","PreparedStatement stmt = connection.prepareStatement(\"SELECT * FROM users WHERE username=? AND password=?\");\nstmt.setString(1, username);\nstmt.setString(2, password);\nResultSet rs = stmt.executeQuery();\n",[2160],{"type":23,"tag":14,"props":2161,"children":2162},{"__ignoreMap":7},[2163,2199,2226,2251],{"type":23,"tag":321,"props":2164,"children":2165},{"class":323,"line":324},[2166,2171,2175,2180,2185,2189,2194],{"type":23,"tag":321,"props":2167,"children":2168},{"style":350},[2169],{"type":28,"value":2170},"PreparedStatement stmt ",{"type":23,"tag":321,"props":2172,"children":2173},{"style":365},[2174],{"type":28,"value":924},{"type":23,"tag":321,"props":2176,"children":2177},{"style":350},[2178],{"type":28,"value":2179}," connection.",{"type":23,"tag":321,"props":2181,"children":2182},{"style":338},[2183],{"type":28,"value":2184},"prepareStatement",{"type":23,"tag":321,"props":2186,"children":2187},{"style":350},[2188],{"type":28,"value":1880},{"type":23,"tag":321,"props":2190,"children":2191},{"style":371},[2192],{"type":28,"value":2193},"\"SELECT * FROM users WHERE username=? AND password=?\"",{"type":23,"tag":321,"props":2195,"children":2196},{"style":350},[2197],{"type":28,"value":2198},");\n",{"type":23,"tag":321,"props":2200,"children":2201},{"class":323,"line":334},[2202,2207,2212,2216,2221],{"type":23,"tag":321,"props":2203,"children":2204},{"style":350},[2205],{"type":28,"value":2206},"stmt.",{"type":23,"tag":321,"props":2208,"children":2209},{"style":338},[2210],{"type":28,"value":2211},"setString",{"type":23,"tag":321,"props":2213,"children":2214},{"style":350},[2215],{"type":28,"value":1880},{"type":23,"tag":321,"props":2217,"children":2218},{"style":344},[2219],{"type":28,"value":2220},"1",{"type":23,"tag":321,"props":2222,"children":2223},{"style":350},[2224],{"type":28,"value":2225},", username);\n",{"type":23,"tag":321,"props":2227,"children":2228},{"class":323,"line":356},[2229,2233,2237,2241,2246],{"type":23,"tag":321,"props":2230,"children":2231},{"style":350},[2232],{"type":28,"value":2206},{"type":23,"tag":321,"props":2234,"children":2235},{"style":338},[2236],{"type":28,"value":2211},{"type":23,"tag":321,"props":2238,"children":2239},{"style":350},[2240],{"type":28,"value":1880},{"type":23,"tag":321,"props":2242,"children":2243},{"style":344},[2244],{"type":28,"value":2245},"2",{"type":23,"tag":321,"props":2247,"children":2248},{"style":350},[2249],{"type":28,"value":2250},", password);\n",{"type":23,"tag":321,"props":2252,"children":2253},{"class":323,"line":382},[2254,2259,2263,2268,2273],{"type":23,"tag":321,"props":2255,"children":2256},{"style":350},[2257],{"type":28,"value":2258},"ResultSet rs ",{"type":23,"tag":321,"props":2260,"children":2261},{"style":365},[2262],{"type":28,"value":924},{"type":23,"tag":321,"props":2264,"children":2265},{"style":350},[2266],{"type":28,"value":2267}," stmt.",{"type":23,"tag":321,"props":2269,"children":2270},{"style":338},[2271],{"type":28,"value":2272},"executeQuery",{"type":23,"tag":321,"props":2274,"children":2275},{"style":350},[2276],{"type":28,"value":2277},"();\n",{"type":23,"tag":24,"props":2279,"children":2280},{},[2281],{"type":28,"value":2282},"This approach prevents SQL injection by ensuring that input data is treated as data, not executable code.",{"type":23,"tag":663,"props":2284,"children":2286},{"id":2285},"_2-secure-authentication",[2287],{"type":28,"value":2288},"2. Secure Authentication",{"type":23,"tag":24,"props":2290,"children":2291},{},[2292],{"type":28,"value":2293},"Implement robust authentication using secure password storage (bcrypt or Argon2):",{"type":23,"tag":311,"props":2295,"children":2297},{"className":2157,"code":2296,"language":2060,"meta":7,"style":7},"import org.springframework.security.crypto.bcrypt.BCrypt;\n\nString hashedPassword = BCrypt.hashpw(password, BCrypt.gensalt());\nif (BCrypt.checkpw(password, hashedPassword)) {\n    // authentication successful\n}\n",[2298],{"type":23,"tag":14,"props":2299,"children":2300},{"__ignoreMap":7},[2301,2313,2320,2357,2380,2388],{"type":23,"tag":321,"props":2302,"children":2303},{"class":323,"line":324},[2304,2308],{"type":23,"tag":321,"props":2305,"children":2306},{"style":365},[2307],{"type":28,"value":803},{"type":23,"tag":321,"props":2309,"children":2310},{"style":350},[2311],{"type":28,"value":2312}," org.springframework.security.crypto.bcrypt.BCrypt;\n",{"type":23,"tag":321,"props":2314,"children":2315},{"class":323,"line":334},[2316],{"type":23,"tag":321,"props":2317,"children":2318},{"emptyLinePlaceholder":395},[2319],{"type":28,"value":398},{"type":23,"tag":321,"props":2321,"children":2322},{"class":323,"line":356},[2323,2328,2332,2337,2342,2347,2352],{"type":23,"tag":321,"props":2324,"children":2325},{"style":350},[2326],{"type":28,"value":2327},"String hashedPassword ",{"type":23,"tag":321,"props":2329,"children":2330},{"style":365},[2331],{"type":28,"value":924},{"type":23,"tag":321,"props":2333,"children":2334},{"style":350},[2335],{"type":28,"value":2336}," BCrypt.",{"type":23,"tag":321,"props":2338,"children":2339},{"style":338},[2340],{"type":28,"value":2341},"hashpw",{"type":23,"tag":321,"props":2343,"children":2344},{"style":350},[2345],{"type":28,"value":2346},"(password, BCrypt.",{"type":23,"tag":321,"props":2348,"children":2349},{"style":338},[2350],{"type":28,"value":2351},"gensalt",{"type":23,"tag":321,"props":2353,"children":2354},{"style":350},[2355],{"type":28,"value":2356},"());\n",{"type":23,"tag":321,"props":2358,"children":2359},{"class":323,"line":382},[2360,2365,2370,2375],{"type":23,"tag":321,"props":2361,"children":2362},{"style":365},[2363],{"type":28,"value":2364},"if",{"type":23,"tag":321,"props":2366,"children":2367},{"style":350},[2368],{"type":28,"value":2369}," (BCrypt.",{"type":23,"tag":321,"props":2371,"children":2372},{"style":338},[2373],{"type":28,"value":2374},"checkpw",{"type":23,"tag":321,"props":2376,"children":2377},{"style":350},[2378],{"type":28,"value":2379},"(password, hashedPassword)) {\n",{"type":23,"tag":321,"props":2381,"children":2382},{"class":323,"line":391},[2383],{"type":23,"tag":321,"props":2384,"children":2385},{"style":328},[2386],{"type":28,"value":2387},"    // authentication successful\n",{"type":23,"tag":321,"props":2389,"children":2390},{"class":323,"line":401},[2391],{"type":23,"tag":321,"props":2392,"children":2393},{"style":350},[2394],{"type":28,"value":388},{"type":23,"tag":663,"props":2396,"children":2398},{"id":2397},"_3-sensitive-data-exposure",[2399],{"type":28,"value":2400},"3. Sensitive Data Exposure",{"type":23,"tag":24,"props":2402,"children":2403},{},[2404],{"type":28,"value":2405},"Use encryption for sensitive data storage:",{"type":23,"tag":311,"props":2407,"children":2409},{"className":2157,"code":2408,"language":2060,"meta":7,"style":7},"Cipher cipher = Cipher.getInstance(\"AES/GCM/NoPadding\");\nSecretKey key = generateSecretKey();\ncipher.init(Cipher.ENCRYPT_MODE, key);\nbyte[] encryptedData = cipher.doFinal(plainData.getBytes(StandardCharsets.UTF_8));\n",[2410],{"type":23,"tag":14,"props":2411,"children":2412},{"__ignoreMap":7},[2413,2448,2469,2487],{"type":23,"tag":321,"props":2414,"children":2415},{"class":323,"line":324},[2416,2421,2425,2430,2435,2439,2444],{"type":23,"tag":321,"props":2417,"children":2418},{"style":350},[2419],{"type":28,"value":2420},"Cipher cipher ",{"type":23,"tag":321,"props":2422,"children":2423},{"style":365},[2424],{"type":28,"value":924},{"type":23,"tag":321,"props":2426,"children":2427},{"style":350},[2428],{"type":28,"value":2429}," Cipher.",{"type":23,"tag":321,"props":2431,"children":2432},{"style":338},[2433],{"type":28,"value":2434},"getInstance",{"type":23,"tag":321,"props":2436,"children":2437},{"style":350},[2438],{"type":28,"value":1880},{"type":23,"tag":321,"props":2440,"children":2441},{"style":371},[2442],{"type":28,"value":2443},"\"AES/GCM/NoPadding\"",{"type":23,"tag":321,"props":2445,"children":2446},{"style":350},[2447],{"type":28,"value":2198},{"type":23,"tag":321,"props":2449,"children":2450},{"class":323,"line":334},[2451,2456,2460,2465],{"type":23,"tag":321,"props":2452,"children":2453},{"style":350},[2454],{"type":28,"value":2455},"SecretKey key ",{"type":23,"tag":321,"props":2457,"children":2458},{"style":365},[2459],{"type":28,"value":924},{"type":23,"tag":321,"props":2461,"children":2462},{"style":338},[2463],{"type":28,"value":2464}," generateSecretKey",{"type":23,"tag":321,"props":2466,"children":2467},{"style":350},[2468],{"type":28,"value":2277},{"type":23,"tag":321,"props":2470,"children":2471},{"class":323,"line":356},[2472,2477,2482],{"type":23,"tag":321,"props":2473,"children":2474},{"style":350},[2475],{"type":28,"value":2476},"cipher.",{"type":23,"tag":321,"props":2478,"children":2479},{"style":338},[2480],{"type":28,"value":2481},"init",{"type":23,"tag":321,"props":2483,"children":2484},{"style":350},[2485],{"type":28,"value":2486},"(Cipher.ENCRYPT_MODE, key);\n",{"type":23,"tag":321,"props":2488,"children":2489},{"class":323,"line":382},[2490,2495,2500,2504,2509,2514,2519,2524],{"type":23,"tag":321,"props":2491,"children":2492},{"style":365},[2493],{"type":28,"value":2494},"byte",{"type":23,"tag":321,"props":2496,"children":2497},{"style":350},[2498],{"type":28,"value":2499},"[] encryptedData ",{"type":23,"tag":321,"props":2501,"children":2502},{"style":365},[2503],{"type":28,"value":924},{"type":23,"tag":321,"props":2505,"children":2506},{"style":350},[2507],{"type":28,"value":2508}," cipher.",{"type":23,"tag":321,"props":2510,"children":2511},{"style":338},[2512],{"type":28,"value":2513},"doFinal",{"type":23,"tag":321,"props":2515,"children":2516},{"style":350},[2517],{"type":28,"value":2518},"(plainData.",{"type":23,"tag":321,"props":2520,"children":2521},{"style":338},[2522],{"type":28,"value":2523},"getBytes",{"type":23,"tag":321,"props":2525,"children":2526},{"style":350},[2527],{"type":28,"value":2528},"(StandardCharsets.UTF_8));\n",{"type":23,"tag":24,"props":2530,"children":2531},{},[2532],{"type":28,"value":2533},"Always encrypt data at rest and in transit (use HTTPS).",{"type":23,"tag":663,"props":2535,"children":2537},{"id":2536},"_4-security-misconfiguration",[2538],{"type":28,"value":2539},"4. Security Misconfiguration",{"type":23,"tag":24,"props":2541,"children":2542},{},[2543],{"type":28,"value":2544},"Adopt secure defaults, disable debugging, and avoid detailed error messages:",{"type":23,"tag":311,"props":2546,"children":2550},{"className":2547,"code":2548,"language":2549,"meta":7,"style":7},"language-properties shiki shiki-themes github-dark github-light","server.error.include-stacktrace=never\nserver.error.include-message=never\n","properties",[2551],{"type":23,"tag":14,"props":2552,"children":2553},{"__ignoreMap":7},[2554,2562],{"type":23,"tag":321,"props":2555,"children":2556},{"class":323,"line":324},[2557],{"type":23,"tag":321,"props":2558,"children":2559},{},[2560],{"type":28,"value":2561},"server.error.include-stacktrace=never\n",{"type":23,"tag":321,"props":2563,"children":2564},{"class":323,"line":334},[2565],{"type":23,"tag":321,"props":2566,"children":2567},{},[2568],{"type":28,"value":2569},"server.error.include-message=never\n",{"type":23,"tag":24,"props":2571,"children":2572},{},[2573],{"type":28,"value":2574},"Review and secure your Java application configuration regularly.",{"type":23,"tag":663,"props":2576,"children":2578},{"id":2577},"_5-cross-site-scripting-xss",[2579],{"type":28,"value":2580},"5. Cross-Site Scripting (XSS)",{"type":23,"tag":24,"props":2582,"children":2583},{},[2584],{"type":28,"value":2585},"Utilize proper encoding or frameworks that prevent XSS by default, such as Thymeleaf:",{"type":23,"tag":311,"props":2587,"children":2591},{"className":2588,"code":2589,"language":2590,"meta":7,"style":7},"language-html shiki shiki-themes github-dark github-light","\u003Cp th:text=\"${userInput}\">\u003C/p>\n","html",[2592],{"type":23,"tag":14,"props":2593,"children":2594},{"__ignoreMap":7},[2595],{"type":23,"tag":321,"props":2596,"children":2597},{"class":323,"line":324},[2598],{"type":23,"tag":321,"props":2599,"children":2600},{},[2601],{"type":28,"value":2589},{"type":23,"tag":24,"props":2603,"children":2604},{},[2605],{"type":28,"value":2606},"Avoid directly inserting user inputs into HTML without proper sanitization or encoding.",{"type":23,"tag":663,"props":2608,"children":2610},{"id":2609},"_6-insecure-deserialization",[2611],{"type":28,"value":2612},"6. Insecure Deserialization",{"type":23,"tag":24,"props":2614,"children":2615},{},[2616],{"type":28,"value":2617},"Limit deserialization to trusted sources only:",{"type":23,"tag":311,"props":2619,"children":2621},{"className":2157,"code":2620,"language":2060,"meta":7,"style":7},"ObjectInputStream ois = new ObjectInputStream(new FileInputStream(\"trusted_data.ser\"));\nMyObject obj = (MyObject) ois.readObject();\n",[2622],{"type":23,"tag":14,"props":2623,"children":2624},{"__ignoreMap":7},[2625,2675],{"type":23,"tag":321,"props":2626,"children":2627},{"class":323,"line":324},[2628,2633,2637,2642,2647,2651,2656,2661,2665,2670],{"type":23,"tag":321,"props":2629,"children":2630},{"style":350},[2631],{"type":28,"value":2632},"ObjectInputStream ois ",{"type":23,"tag":321,"props":2634,"children":2635},{"style":365},[2636],{"type":28,"value":924},{"type":23,"tag":321,"props":2638,"children":2639},{"style":365},[2640],{"type":28,"value":2641}," new",{"type":23,"tag":321,"props":2643,"children":2644},{"style":338},[2645],{"type":28,"value":2646}," ObjectInputStream",{"type":23,"tag":321,"props":2648,"children":2649},{"style":350},[2650],{"type":28,"value":1880},{"type":23,"tag":321,"props":2652,"children":2653},{"style":365},[2654],{"type":28,"value":2655},"new",{"type":23,"tag":321,"props":2657,"children":2658},{"style":338},[2659],{"type":28,"value":2660}," FileInputStream",{"type":23,"tag":321,"props":2662,"children":2663},{"style":350},[2664],{"type":28,"value":1880},{"type":23,"tag":321,"props":2666,"children":2667},{"style":371},[2668],{"type":28,"value":2669},"\"trusted_data.ser\"",{"type":23,"tag":321,"props":2671,"children":2672},{"style":350},[2673],{"type":28,"value":2674},"));\n",{"type":23,"tag":321,"props":2676,"children":2677},{"class":323,"line":334},[2678,2683,2687,2692,2697],{"type":23,"tag":321,"props":2679,"children":2680},{"style":350},[2681],{"type":28,"value":2682},"MyObject obj ",{"type":23,"tag":321,"props":2684,"children":2685},{"style":365},[2686],{"type":28,"value":924},{"type":23,"tag":321,"props":2688,"children":2689},{"style":350},[2690],{"type":28,"value":2691}," (MyObject) ois.",{"type":23,"tag":321,"props":2693,"children":2694},{"style":338},[2695],{"type":28,"value":2696},"readObject",{"type":23,"tag":321,"props":2698,"children":2699},{"style":350},[2700],{"type":28,"value":2277},{"type":23,"tag":24,"props":2702,"children":2703},{},[2704],{"type":28,"value":2705},"Always validate deserialized data.",{"type":23,"tag":663,"props":2707,"children":2709},{"id":2708},"_7-component-vulnerabilities",[2710],{"type":28,"value":2711},"7. Component Vulnerabilities",{"type":23,"tag":24,"props":2713,"children":2714},{},[2715],{"type":28,"value":2716},"Regularly update libraries and dependencies, and use tools like OWASP Dependency-Check to identify vulnerabilities:",{"type":23,"tag":311,"props":2718,"children":2722},{"className":2719,"code":2720,"language":2721,"meta":7,"style":7},"language-xml shiki shiki-themes github-dark github-light","\u003Cplugin>\n    \u003CgroupId>org.owasp\u003C/groupId>\n    \u003CartifactId>dependency-check-maven\u003C/artifactId>\n    \u003Cversion>9.0.9\u003C/version>\n\u003C/plugin>\n","xml",[2723],{"type":23,"tag":14,"props":2724,"children":2725},{"__ignoreMap":7},[2726,2745,2771,2796,2821],{"type":23,"tag":321,"props":2727,"children":2728},{"class":323,"line":324},[2729,2734,2740],{"type":23,"tag":321,"props":2730,"children":2731},{"style":350},[2732],{"type":28,"value":2733},"\u003C",{"type":23,"tag":321,"props":2735,"children":2737},{"style":2736},"--shiki-default:#85E89D;--shiki-light:#22863A",[2738],{"type":28,"value":2739},"plugin",{"type":23,"tag":321,"props":2741,"children":2742},{"style":350},[2743],{"type":28,"value":2744},">\n",{"type":23,"tag":321,"props":2746,"children":2747},{"class":323,"line":334},[2748,2753,2758,2763,2767],{"type":23,"tag":321,"props":2749,"children":2750},{"style":350},[2751],{"type":28,"value":2752},"    \u003C",{"type":23,"tag":321,"props":2754,"children":2755},{"style":2736},[2756],{"type":28,"value":2757},"groupId",{"type":23,"tag":321,"props":2759,"children":2760},{"style":350},[2761],{"type":28,"value":2762},">org.owasp\u003C/",{"type":23,"tag":321,"props":2764,"children":2765},{"style":2736},[2766],{"type":28,"value":2757},{"type":23,"tag":321,"props":2768,"children":2769},{"style":350},[2770],{"type":28,"value":2744},{"type":23,"tag":321,"props":2772,"children":2773},{"class":323,"line":356},[2774,2778,2783,2788,2792],{"type":23,"tag":321,"props":2775,"children":2776},{"style":350},[2777],{"type":28,"value":2752},{"type":23,"tag":321,"props":2779,"children":2780},{"style":2736},[2781],{"type":28,"value":2782},"artifactId",{"type":23,"tag":321,"props":2784,"children":2785},{"style":350},[2786],{"type":28,"value":2787},">dependency-check-maven\u003C/",{"type":23,"tag":321,"props":2789,"children":2790},{"style":2736},[2791],{"type":28,"value":2782},{"type":23,"tag":321,"props":2793,"children":2794},{"style":350},[2795],{"type":28,"value":2744},{"type":23,"tag":321,"props":2797,"children":2798},{"class":323,"line":382},[2799,2803,2808,2813,2817],{"type":23,"tag":321,"props":2800,"children":2801},{"style":350},[2802],{"type":28,"value":2752},{"type":23,"tag":321,"props":2804,"children":2805},{"style":2736},[2806],{"type":28,"value":2807},"version",{"type":23,"tag":321,"props":2809,"children":2810},{"style":350},[2811],{"type":28,"value":2812},">9.0.9\u003C/",{"type":23,"tag":321,"props":2814,"children":2815},{"style":2736},[2816],{"type":28,"value":2807},{"type":23,"tag":321,"props":2818,"children":2819},{"style":350},[2820],{"type":28,"value":2744},{"type":23,"tag":321,"props":2822,"children":2823},{"class":323,"line":391},[2824,2829,2833],{"type":23,"tag":321,"props":2825,"children":2826},{"style":350},[2827],{"type":28,"value":2828},"\u003C/",{"type":23,"tag":321,"props":2830,"children":2831},{"style":2736},[2832],{"type":28,"value":2739},{"type":23,"tag":321,"props":2834,"children":2835},{"style":350},[2836],{"type":28,"value":2744},{"type":23,"tag":24,"props":2838,"children":2839},{},[2840],{"type":28,"value":2841},"Execute dependency checks regularly in your CI/CD pipeline.",{"type":23,"tag":663,"props":2843,"children":2845},{"id":2844},"_8-logging-and-monitoring",[2846],{"type":28,"value":2847},"8. Logging and Monitoring",{"type":23,"tag":24,"props":2849,"children":2850},{},[2851],{"type":28,"value":2852},"Implement comprehensive logging and monitoring to detect and respond to security incidents:",{"type":23,"tag":311,"props":2854,"children":2856},{"className":2157,"code":2855,"language":2060,"meta":7,"style":7},"logger.warn(\"Failed login attempt for user: {}\", username);\n",[2857],{"type":23,"tag":14,"props":2858,"children":2859},{"__ignoreMap":7},[2860],{"type":23,"tag":321,"props":2861,"children":2862},{"class":323,"line":324},[2863,2868,2873,2877,2882],{"type":23,"tag":321,"props":2864,"children":2865},{"style":350},[2866],{"type":28,"value":2867},"logger.",{"type":23,"tag":321,"props":2869,"children":2870},{"style":338},[2871],{"type":28,"value":2872},"warn",{"type":23,"tag":321,"props":2874,"children":2875},{"style":350},[2876],{"type":28,"value":1880},{"type":23,"tag":321,"props":2878,"children":2879},{"style":371},[2880],{"type":28,"value":2881},"\"Failed login attempt for user: {}\"",{"type":23,"tag":321,"props":2883,"children":2884},{"style":350},[2885],{"type":28,"value":2225},{"type":23,"tag":24,"props":2887,"children":2888},{},[2889],{"type":28,"value":2890},"Aggregate logs centrally, and set up alerts for suspicious activities.",{"type":23,"tag":663,"props":2892,"children":2894},{"id":2893},"conclusion",[2895],{"type":28,"value":2896},"Conclusion",{"type":23,"tag":24,"props":2898,"children":2899},{},[2900],{"type":28,"value":2901},"Adopting these best practices can greatly enhance the security posture of your Java applications. Stay proactive by regularly reviewing security measures, updating dependencies, and monitoring your systems. Security is a continuous process, not a one-time setup.",{"type":23,"tag":1995,"props":2903,"children":2904},{"id":552},[2905],{"type":28,"value":555},{"type":23,"tag":54,"props":2907,"children":2908},{},[2909,2919,2929],{"type":23,"tag":58,"props":2910,"children":2911},{},[2912],{"type":23,"tag":568,"props":2913,"children":2916},{"href":2914,"rel":2915},"https://owasp.org/www-project-top-ten/",[572],[2917],{"type":28,"value":2918},"OWASP Top 10",{"type":23,"tag":58,"props":2920,"children":2921},{},[2922],{"type":23,"tag":568,"props":2923,"children":2926},{"href":2924,"rel":2925},"https://spring.io/projects/spring-security",[572],[2927],{"type":28,"value":2928},"Spring Security",{"type":23,"tag":58,"props":2930,"children":2931},{},[2932],{"type":23,"tag":568,"props":2933,"children":2936},{"href":2934,"rel":2935},"https://owasp.org/www-project-dependency-check/",[572],[2937],{"type":28,"value":2938},"OWASP Dependency Check",{"type":23,"tag":620,"props":2940,"children":2941},{},[2942],{"type":28,"value":624},{"title":7,"searchDepth":334,"depth":334,"links":2944},[2945,2946,2947,2948,2949,2950,2951,2952,2953,2954],{"id":2076,"depth":334,"text":2079},{"id":2146,"depth":334,"text":2149},{"id":2285,"depth":334,"text":2288},{"id":2397,"depth":334,"text":2400},{"id":2536,"depth":334,"text":2539},{"id":2577,"depth":334,"text":2580},{"id":2609,"depth":334,"text":2612},{"id":2708,"depth":334,"text":2711},{"id":2844,"depth":334,"text":2847},{"id":2893,"depth":334,"text":2896},"content:posts:java-security-best-practices.md","posts/java-security-best-practices.md","posts/java-security-best-practices",{"_path":2959,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":2960,"description":2961,"date":2962,"layout":11,"subtitle":2963,"image":2964,"optimized_image":2964,"category":14,"tags":2965,"author":18,"paginate":6,"body":2969,"_type":631,"_id":3773,"_source":633,"_file":3774,"_stem":3775,"_extension":636},"/posts/circuit-breaking-resilience","Circuit Breaking in Distributed Systems","An expert guide to understanding and implementing circuit breakers in distributed systems, with practical Java examples using Resilience4j and best practices.","2024-07-15T11:00:00.000Z","Enhancing Resilience with Circuit Breaker Patterns","/assets/img/uploads/circuit-breaking-resilience.png",[14,2060,2966,2967,2968],"resilience","circuit-breaker","distributed-systems",{"type":20,"children":2970,"toc":3761},[2971,2979,2985,2990,3023,3028,3034,3039,3057,3063,3069,3074,3184,3190,3394,3400,3405,3572,3578,3583,3677,3682,3688,3711,3715,3720,3724,3757],{"type":23,"tag":654,"props":2972,"children":2973},{},[2974],{"type":23,"tag":24,"props":2975,"children":2976},{},[2977],{"type":28,"value":2978},"In modern distributed systems, failures are inevitable. The circuit breaker pattern helps maintain system stability by preventing failures from cascading across service boundaries. In this post, we'll dive deep into circuit breakers, explore their importance, and demonstrate practical implementation using Resilience4j in Java.",{"type":23,"tag":663,"props":2980,"children":2982},{"id":2981},"understanding-the-circuit-breaker-pattern",[2983],{"type":28,"value":2984},"Understanding the Circuit Breaker Pattern",{"type":23,"tag":24,"props":2986,"children":2987},{},[2988],{"type":28,"value":2989},"The circuit breaker pattern prevents a service from making repeated calls to an external service that is experiencing issues. It has three main states:",{"type":23,"tag":54,"props":2991,"children":2992},{},[2993,3003,3013],{"type":23,"tag":58,"props":2994,"children":2995},{},[2996,3001],{"type":23,"tag":76,"props":2997,"children":2998},{},[2999],{"type":28,"value":3000},"Closed:",{"type":28,"value":3002}," All requests pass through normally.",{"type":23,"tag":58,"props":3004,"children":3005},{},[3006,3011],{"type":23,"tag":76,"props":3007,"children":3008},{},[3009],{"type":28,"value":3010},"Open:",{"type":28,"value":3012}," Requests fail fast, bypassing the problematic service.",{"type":23,"tag":58,"props":3014,"children":3015},{},[3016,3021],{"type":23,"tag":76,"props":3017,"children":3018},{},[3019],{"type":28,"value":3020},"Half-Open:",{"type":28,"value":3022}," A limited number of requests test if the external service has recovered.",{"type":23,"tag":24,"props":3024,"children":3025},{},[3026],{"type":28,"value":3027},"This mechanism helps improve the resilience and responsiveness of your systems.",{"type":23,"tag":663,"props":3029,"children":3031},{"id":3030},"when-to-use-circuit-breakers",[3032],{"type":28,"value":3033},"When to Use Circuit Breakers",{"type":23,"tag":24,"props":3035,"children":3036},{},[3037],{"type":28,"value":3038},"Circuit breakers are essential when:",{"type":23,"tag":54,"props":3040,"children":3041},{},[3042,3047,3052],{"type":23,"tag":58,"props":3043,"children":3044},{},[3045],{"type":28,"value":3046},"Your system relies on remote calls (microservices architecture, external APIs).",{"type":23,"tag":58,"props":3048,"children":3049},{},[3050],{"type":28,"value":3051},"You need to prevent failure propagation.",{"type":23,"tag":58,"props":3053,"children":3054},{},[3055],{"type":28,"value":3056},"You aim to improve user experience by quickly responding to failures.",{"type":23,"tag":663,"props":3058,"children":3060},{"id":3059},"implementing-circuit-breakers-with-resilience4j",[3061],{"type":28,"value":3062},"Implementing Circuit Breakers with Resilience4j",{"type":23,"tag":31,"props":3064,"children":3066},{"id":3065},"step-1-adding-dependencies",[3067],{"type":28,"value":3068},"Step 1: Adding Dependencies",{"type":23,"tag":24,"props":3070,"children":3071},{},[3072],{"type":28,"value":3073},"Add Resilience4j dependencies to your project (Maven example):",{"type":23,"tag":311,"props":3075,"children":3077},{"className":2719,"code":3076,"language":2721,"meta":7,"style":7},"\u003Cdependency>\n    \u003CgroupId>io.github.resilience4j\u003C/groupId>\n    \u003CartifactId>resilience4j-circuitbreaker\u003C/artifactId>\n    \u003Cversion>2.0.2\u003C/version>\n\u003C/dependency>\n",[3078],{"type":23,"tag":14,"props":3079,"children":3080},{"__ignoreMap":7},[3081,3097,3121,3145,3169],{"type":23,"tag":321,"props":3082,"children":3083},{"class":323,"line":324},[3084,3088,3093],{"type":23,"tag":321,"props":3085,"children":3086},{"style":350},[3087],{"type":28,"value":2733},{"type":23,"tag":321,"props":3089,"children":3090},{"style":2736},[3091],{"type":28,"value":3092},"dependency",{"type":23,"tag":321,"props":3094,"children":3095},{"style":350},[3096],{"type":28,"value":2744},{"type":23,"tag":321,"props":3098,"children":3099},{"class":323,"line":334},[3100,3104,3108,3113,3117],{"type":23,"tag":321,"props":3101,"children":3102},{"style":350},[3103],{"type":28,"value":2752},{"type":23,"tag":321,"props":3105,"children":3106},{"style":2736},[3107],{"type":28,"value":2757},{"type":23,"tag":321,"props":3109,"children":3110},{"style":350},[3111],{"type":28,"value":3112},">io.github.resilience4j\u003C/",{"type":23,"tag":321,"props":3114,"children":3115},{"style":2736},[3116],{"type":28,"value":2757},{"type":23,"tag":321,"props":3118,"children":3119},{"style":350},[3120],{"type":28,"value":2744},{"type":23,"tag":321,"props":3122,"children":3123},{"class":323,"line":356},[3124,3128,3132,3137,3141],{"type":23,"tag":321,"props":3125,"children":3126},{"style":350},[3127],{"type":28,"value":2752},{"type":23,"tag":321,"props":3129,"children":3130},{"style":2736},[3131],{"type":28,"value":2782},{"type":23,"tag":321,"props":3133,"children":3134},{"style":350},[3135],{"type":28,"value":3136},">resilience4j-circuitbreaker\u003C/",{"type":23,"tag":321,"props":3138,"children":3139},{"style":2736},[3140],{"type":28,"value":2782},{"type":23,"tag":321,"props":3142,"children":3143},{"style":350},[3144],{"type":28,"value":2744},{"type":23,"tag":321,"props":3146,"children":3147},{"class":323,"line":382},[3148,3152,3156,3161,3165],{"type":23,"tag":321,"props":3149,"children":3150},{"style":350},[3151],{"type":28,"value":2752},{"type":23,"tag":321,"props":3153,"children":3154},{"style":2736},[3155],{"type":28,"value":2807},{"type":23,"tag":321,"props":3157,"children":3158},{"style":350},[3159],{"type":28,"value":3160},">2.0.2\u003C/",{"type":23,"tag":321,"props":3162,"children":3163},{"style":2736},[3164],{"type":28,"value":2807},{"type":23,"tag":321,"props":3166,"children":3167},{"style":350},[3168],{"type":28,"value":2744},{"type":23,"tag":321,"props":3170,"children":3171},{"class":323,"line":391},[3172,3176,3180],{"type":23,"tag":321,"props":3173,"children":3174},{"style":350},[3175],{"type":28,"value":2828},{"type":23,"tag":321,"props":3177,"children":3178},{"style":2736},[3179],{"type":28,"value":3092},{"type":23,"tag":321,"props":3181,"children":3182},{"style":350},[3183],{"type":28,"value":2744},{"type":23,"tag":31,"props":3185,"children":3187},{"id":3186},"step-2-configuring-circuit-breaker",[3188],{"type":28,"value":3189},"Step 2: Configuring Circuit Breaker",{"type":23,"tag":311,"props":3191,"children":3193},{"className":2157,"code":3192,"language":2060,"meta":7,"style":7},"CircuitBreakerConfig config = CircuitBreakerConfig.custom()\n    .failureRateThreshold(50)\n    .waitDurationInOpenState(Duration.ofMillis(1000))\n    .permittedNumberOfCallsInHalfOpenState(2)\n    .minimumNumberOfCalls(5)\n    .build();\n\nCircuitBreaker circuitBreaker = CircuitBreaker.of(\"myService\", config);\n",[3194],{"type":23,"tag":14,"props":3195,"children":3196},{"__ignoreMap":7},[3197,3224,3250,3286,3310,3335,3351,3358],{"type":23,"tag":321,"props":3198,"children":3199},{"class":323,"line":324},[3200,3205,3209,3214,3219],{"type":23,"tag":321,"props":3201,"children":3202},{"style":350},[3203],{"type":28,"value":3204},"CircuitBreakerConfig config ",{"type":23,"tag":321,"props":3206,"children":3207},{"style":365},[3208],{"type":28,"value":924},{"type":23,"tag":321,"props":3210,"children":3211},{"style":350},[3212],{"type":28,"value":3213}," CircuitBreakerConfig.",{"type":23,"tag":321,"props":3215,"children":3216},{"style":338},[3217],{"type":28,"value":3218},"custom",{"type":23,"tag":321,"props":3220,"children":3221},{"style":350},[3222],{"type":28,"value":3223},"()\n",{"type":23,"tag":321,"props":3225,"children":3226},{"class":323,"line":334},[3227,3232,3237,3241,3246],{"type":23,"tag":321,"props":3228,"children":3229},{"style":350},[3230],{"type":28,"value":3231},"    .",{"type":23,"tag":321,"props":3233,"children":3234},{"style":338},[3235],{"type":28,"value":3236},"failureRateThreshold",{"type":23,"tag":321,"props":3238,"children":3239},{"style":350},[3240],{"type":28,"value":1880},{"type":23,"tag":321,"props":3242,"children":3243},{"style":344},[3244],{"type":28,"value":3245},"50",{"type":23,"tag":321,"props":3247,"children":3248},{"style":350},[3249],{"type":28,"value":911},{"type":23,"tag":321,"props":3251,"children":3252},{"class":323,"line":356},[3253,3257,3262,3267,3272,3276,3281],{"type":23,"tag":321,"props":3254,"children":3255},{"style":350},[3256],{"type":28,"value":3231},{"type":23,"tag":321,"props":3258,"children":3259},{"style":338},[3260],{"type":28,"value":3261},"waitDurationInOpenState",{"type":23,"tag":321,"props":3263,"children":3264},{"style":350},[3265],{"type":28,"value":3266},"(Duration.",{"type":23,"tag":321,"props":3268,"children":3269},{"style":338},[3270],{"type":28,"value":3271},"ofMillis",{"type":23,"tag":321,"props":3273,"children":3274},{"style":350},[3275],{"type":28,"value":1880},{"type":23,"tag":321,"props":3277,"children":3278},{"style":344},[3279],{"type":28,"value":3280},"1000",{"type":23,"tag":321,"props":3282,"children":3283},{"style":350},[3284],{"type":28,"value":3285},"))\n",{"type":23,"tag":321,"props":3287,"children":3288},{"class":323,"line":382},[3289,3293,3298,3302,3306],{"type":23,"tag":321,"props":3290,"children":3291},{"style":350},[3292],{"type":28,"value":3231},{"type":23,"tag":321,"props":3294,"children":3295},{"style":338},[3296],{"type":28,"value":3297},"permittedNumberOfCallsInHalfOpenState",{"type":23,"tag":321,"props":3299,"children":3300},{"style":350},[3301],{"type":28,"value":1880},{"type":23,"tag":321,"props":3303,"children":3304},{"style":344},[3305],{"type":28,"value":2245},{"type":23,"tag":321,"props":3307,"children":3308},{"style":350},[3309],{"type":28,"value":911},{"type":23,"tag":321,"props":3311,"children":3312},{"class":323,"line":391},[3313,3317,3322,3326,3331],{"type":23,"tag":321,"props":3314,"children":3315},{"style":350},[3316],{"type":28,"value":3231},{"type":23,"tag":321,"props":3318,"children":3319},{"style":338},[3320],{"type":28,"value":3321},"minimumNumberOfCalls",{"type":23,"tag":321,"props":3323,"children":3324},{"style":350},[3325],{"type":28,"value":1880},{"type":23,"tag":321,"props":3327,"children":3328},{"style":344},[3329],{"type":28,"value":3330},"5",{"type":23,"tag":321,"props":3332,"children":3333},{"style":350},[3334],{"type":28,"value":911},{"type":23,"tag":321,"props":3336,"children":3337},{"class":323,"line":401},[3338,3342,3347],{"type":23,"tag":321,"props":3339,"children":3340},{"style":350},[3341],{"type":28,"value":3231},{"type":23,"tag":321,"props":3343,"children":3344},{"style":338},[3345],{"type":28,"value":3346},"build",{"type":23,"tag":321,"props":3348,"children":3349},{"style":350},[3350],{"type":28,"value":2277},{"type":23,"tag":321,"props":3352,"children":3353},{"class":323,"line":410},[3354],{"type":23,"tag":321,"props":3355,"children":3356},{"emptyLinePlaceholder":395},[3357],{"type":28,"value":398},{"type":23,"tag":321,"props":3359,"children":3360},{"class":323,"line":433},[3361,3366,3370,3375,3380,3384,3389],{"type":23,"tag":321,"props":3362,"children":3363},{"style":350},[3364],{"type":28,"value":3365},"CircuitBreaker circuitBreaker ",{"type":23,"tag":321,"props":3367,"children":3368},{"style":365},[3369],{"type":28,"value":924},{"type":23,"tag":321,"props":3371,"children":3372},{"style":350},[3373],{"type":28,"value":3374}," CircuitBreaker.",{"type":23,"tag":321,"props":3376,"children":3377},{"style":338},[3378],{"type":28,"value":3379},"of",{"type":23,"tag":321,"props":3381,"children":3382},{"style":350},[3383],{"type":28,"value":1880},{"type":23,"tag":321,"props":3385,"children":3386},{"style":371},[3387],{"type":28,"value":3388},"\"myService\"",{"type":23,"tag":321,"props":3390,"children":3391},{"style":350},[3392],{"type":28,"value":3393},", config);\n",{"type":23,"tag":31,"props":3395,"children":3397},{"id":3396},"step-3-using-circuit-breaker",[3398],{"type":28,"value":3399},"Step 3: Using Circuit Breaker",{"type":23,"tag":24,"props":3401,"children":3402},{},[3403],{"type":28,"value":3404},"Wrap service calls using the circuit breaker:",{"type":23,"tag":311,"props":3406,"children":3408},{"className":2157,"code":3407,"language":2060,"meta":7,"style":7},"Supplier\u003CString> decoratedSupplier = CircuitBreaker.decorateSupplier(circuitBreaker, () -> myService.remoteCall());\n\nTry.ofSupplier(decoratedSupplier)\n    .recover(throwable -> \"Fallback response\")\n    .onSuccess(result -> System.out.println(\"Response: \" + result));\n",[3409],{"type":23,"tag":14,"props":3410,"children":3411},{"__ignoreMap":7},[3412,3467,3474,3492,3522],{"type":23,"tag":321,"props":3413,"children":3414},{"class":323,"line":324},[3415,3420,3425,3430,3434,3438,3443,3448,3453,3458,3463],{"type":23,"tag":321,"props":3416,"children":3417},{"style":350},[3418],{"type":28,"value":3419},"Supplier\u003C",{"type":23,"tag":321,"props":3421,"children":3422},{"style":365},[3423],{"type":28,"value":3424},"String",{"type":23,"tag":321,"props":3426,"children":3427},{"style":350},[3428],{"type":28,"value":3429},"> decoratedSupplier ",{"type":23,"tag":321,"props":3431,"children":3432},{"style":365},[3433],{"type":28,"value":924},{"type":23,"tag":321,"props":3435,"children":3436},{"style":350},[3437],{"type":28,"value":3374},{"type":23,"tag":321,"props":3439,"children":3440},{"style":338},[3441],{"type":28,"value":3442},"decorateSupplier",{"type":23,"tag":321,"props":3444,"children":3445},{"style":350},[3446],{"type":28,"value":3447},"(circuitBreaker, () ",{"type":23,"tag":321,"props":3449,"children":3450},{"style":365},[3451],{"type":28,"value":3452},"->",{"type":23,"tag":321,"props":3454,"children":3455},{"style":350},[3456],{"type":28,"value":3457}," myService.",{"type":23,"tag":321,"props":3459,"children":3460},{"style":338},[3461],{"type":28,"value":3462},"remoteCall",{"type":23,"tag":321,"props":3464,"children":3465},{"style":350},[3466],{"type":28,"value":2356},{"type":23,"tag":321,"props":3468,"children":3469},{"class":323,"line":334},[3470],{"type":23,"tag":321,"props":3471,"children":3472},{"emptyLinePlaceholder":395},[3473],{"type":28,"value":398},{"type":23,"tag":321,"props":3475,"children":3476},{"class":323,"line":356},[3477,3482,3487],{"type":23,"tag":321,"props":3478,"children":3479},{"style":350},[3480],{"type":28,"value":3481},"Try.",{"type":23,"tag":321,"props":3483,"children":3484},{"style":338},[3485],{"type":28,"value":3486},"ofSupplier",{"type":23,"tag":321,"props":3488,"children":3489},{"style":350},[3490],{"type":28,"value":3491},"(decoratedSupplier)\n",{"type":23,"tag":321,"props":3493,"children":3494},{"class":323,"line":382},[3495,3499,3504,3509,3513,3518],{"type":23,"tag":321,"props":3496,"children":3497},{"style":350},[3498],{"type":28,"value":3231},{"type":23,"tag":321,"props":3500,"children":3501},{"style":338},[3502],{"type":28,"value":3503},"recover",{"type":23,"tag":321,"props":3505,"children":3506},{"style":350},[3507],{"type":28,"value":3508},"(throwable ",{"type":23,"tag":321,"props":3510,"children":3511},{"style":365},[3512],{"type":28,"value":3452},{"type":23,"tag":321,"props":3514,"children":3515},{"style":371},[3516],{"type":28,"value":3517}," \"Fallback response\"",{"type":23,"tag":321,"props":3519,"children":3520},{"style":350},[3521],{"type":28,"value":911},{"type":23,"tag":321,"props":3523,"children":3524},{"class":323,"line":391},[3525,3529,3534,3539,3543,3548,3553,3557,3562,3567],{"type":23,"tag":321,"props":3526,"children":3527},{"style":350},[3528],{"type":28,"value":3231},{"type":23,"tag":321,"props":3530,"children":3531},{"style":338},[3532],{"type":28,"value":3533},"onSuccess",{"type":23,"tag":321,"props":3535,"children":3536},{"style":350},[3537],{"type":28,"value":3538},"(result ",{"type":23,"tag":321,"props":3540,"children":3541},{"style":365},[3542],{"type":28,"value":3452},{"type":23,"tag":321,"props":3544,"children":3545},{"style":350},[3546],{"type":28,"value":3547}," System.out.",{"type":23,"tag":321,"props":3549,"children":3550},{"style":338},[3551],{"type":28,"value":3552},"println",{"type":23,"tag":321,"props":3554,"children":3555},{"style":350},[3556],{"type":28,"value":1880},{"type":23,"tag":321,"props":3558,"children":3559},{"style":371},[3560],{"type":28,"value":3561},"\"Response: \"",{"type":23,"tag":321,"props":3563,"children":3564},{"style":365},[3565],{"type":28,"value":3566}," +",{"type":23,"tag":321,"props":3568,"children":3569},{"style":350},[3570],{"type":28,"value":3571}," result));\n",{"type":23,"tag":663,"props":3573,"children":3575},{"id":3574},"monitoring-and-metrics",[3576],{"type":28,"value":3577},"Monitoring and Metrics",{"type":23,"tag":24,"props":3579,"children":3580},{},[3581],{"type":28,"value":3582},"Resilience4j provides built-in support for metrics and monitoring:",{"type":23,"tag":311,"props":3584,"children":3586},{"className":2157,"code":3585,"language":2060,"meta":7,"style":7},"CircuitBreakerRegistry registry = CircuitBreakerRegistry.ofDefaults();\nregistry.getEventPublisher()\n    .onStateTransition(event -> System.out.println(event.getStateTransition()));\n",[3587],{"type":23,"tag":14,"props":3588,"children":3589},{"__ignoreMap":7},[3590,3616,3633],{"type":23,"tag":321,"props":3591,"children":3592},{"class":323,"line":324},[3593,3598,3602,3607,3612],{"type":23,"tag":321,"props":3594,"children":3595},{"style":350},[3596],{"type":28,"value":3597},"CircuitBreakerRegistry registry ",{"type":23,"tag":321,"props":3599,"children":3600},{"style":365},[3601],{"type":28,"value":924},{"type":23,"tag":321,"props":3603,"children":3604},{"style":350},[3605],{"type":28,"value":3606}," CircuitBreakerRegistry.",{"type":23,"tag":321,"props":3608,"children":3609},{"style":338},[3610],{"type":28,"value":3611},"ofDefaults",{"type":23,"tag":321,"props":3613,"children":3614},{"style":350},[3615],{"type":28,"value":2277},{"type":23,"tag":321,"props":3617,"children":3618},{"class":323,"line":334},[3619,3624,3629],{"type":23,"tag":321,"props":3620,"children":3621},{"style":350},[3622],{"type":28,"value":3623},"registry.",{"type":23,"tag":321,"props":3625,"children":3626},{"style":338},[3627],{"type":28,"value":3628},"getEventPublisher",{"type":23,"tag":321,"props":3630,"children":3631},{"style":350},[3632],{"type":28,"value":3223},{"type":23,"tag":321,"props":3634,"children":3635},{"class":323,"line":356},[3636,3640,3645,3650,3654,3658,3662,3667,3672],{"type":23,"tag":321,"props":3637,"children":3638},{"style":350},[3639],{"type":28,"value":3231},{"type":23,"tag":321,"props":3641,"children":3642},{"style":338},[3643],{"type":28,"value":3644},"onStateTransition",{"type":23,"tag":321,"props":3646,"children":3647},{"style":350},[3648],{"type":28,"value":3649},"(event ",{"type":23,"tag":321,"props":3651,"children":3652},{"style":365},[3653],{"type":28,"value":3452},{"type":23,"tag":321,"props":3655,"children":3656},{"style":350},[3657],{"type":28,"value":3547},{"type":23,"tag":321,"props":3659,"children":3660},{"style":338},[3661],{"type":28,"value":3552},{"type":23,"tag":321,"props":3663,"children":3664},{"style":350},[3665],{"type":28,"value":3666},"(event.",{"type":23,"tag":321,"props":3668,"children":3669},{"style":338},[3670],{"type":28,"value":3671},"getStateTransition",{"type":23,"tag":321,"props":3673,"children":3674},{"style":350},[3675],{"type":28,"value":3676},"()));\n",{"type":23,"tag":24,"props":3678,"children":3679},{},[3680],{"type":28,"value":3681},"Integrate with Prometheus, Grafana, or other observability tools for comprehensive monitoring.",{"type":23,"tag":663,"props":3683,"children":3685},{"id":3684},"best-practices-for-circuit-breaking",[3686],{"type":28,"value":3687},"Best Practices for Circuit Breaking",{"type":23,"tag":54,"props":3689,"children":3690},{},[3691,3696,3701,3706],{"type":23,"tag":58,"props":3692,"children":3693},{},[3694],{"type":28,"value":3695},"Configure sensible thresholds to avoid premature circuit opening.",{"type":23,"tag":58,"props":3697,"children":3698},{},[3699],{"type":28,"value":3700},"Always define fallback mechanisms.",{"type":23,"tag":58,"props":3702,"children":3703},{},[3704],{"type":28,"value":3705},"Regularly monitor circuit breaker states and metrics.",{"type":23,"tag":58,"props":3707,"children":3708},{},[3709],{"type":28,"value":3710},"Test thoroughly to ensure reliability under failure conditions.",{"type":23,"tag":663,"props":3712,"children":3713},{"id":2893},[3714],{"type":28,"value":2896},{"type":23,"tag":24,"props":3716,"children":3717},{},[3718],{"type":28,"value":3719},"Implementing circuit breakers using Resilience4j significantly enhances the resilience of your Java-based distributed systems. This proactive approach ensures your systems gracefully handle failures, maintaining service availability and user satisfaction.",{"type":23,"tag":1995,"props":3721,"children":3722},{"id":552},[3723],{"type":28,"value":555},{"type":23,"tag":54,"props":3725,"children":3726},{},[3727,3737,3747],{"type":23,"tag":58,"props":3728,"children":3729},{},[3730],{"type":23,"tag":568,"props":3731,"children":3734},{"href":3732,"rel":3733},"https://resilience4j.readme.io/docs",[572],[3735],{"type":28,"value":3736},"Resilience4j Official Documentation",{"type":23,"tag":58,"props":3738,"children":3739},{},[3740],{"type":23,"tag":568,"props":3741,"children":3744},{"href":3742,"rel":3743},"https://martinfowler.com/bliki/CircuitBreaker.html",[572],[3745],{"type":28,"value":3746},"Circuit Breaker Pattern by Martin Fowler",{"type":23,"tag":58,"props":3748,"children":3749},{},[3750],{"type":23,"tag":568,"props":3751,"children":3754},{"href":3752,"rel":3753},"https://microservices.io/patterns/reliability/circuit-breaker.html",[572],[3755],{"type":28,"value":3756},"Microservices Patterns by Chris Richardson",{"type":23,"tag":620,"props":3758,"children":3759},{},[3760],{"type":28,"value":624},{"title":7,"searchDepth":334,"depth":334,"links":3762},[3763,3764,3765,3770,3771,3772],{"id":2981,"depth":334,"text":2984},{"id":3030,"depth":334,"text":3033},{"id":3059,"depth":334,"text":3062,"children":3766},[3767,3768,3769],{"id":3065,"depth":356,"text":3068},{"id":3186,"depth":356,"text":3189},{"id":3396,"depth":356,"text":3399},{"id":3574,"depth":334,"text":3577},{"id":3684,"depth":334,"text":3687},{"id":2893,"depth":334,"text":2896},"content:posts:circuit-breaking-resilience.md","posts/circuit-breaking-resilience.md","posts/circuit-breaking-resilience",[3777,3778,3779,3780,3784,3788,3792,3796,3800,3804,3808,3812,3816,3817,3821,3825,3829,3833,3836,3840,3844],{"_path":639,"title":640,"date":642},{"_path":2053,"title":2054,"date":2056},{"_path":2959,"title":2960,"date":2962},{"_path":3781,"title":3782,"date":3783},"/posts/maven-and-github-actions","Automating Java Builds with Maven and GitHub Actions CI/CD","2024-06-15T11:00:00.000Z",{"_path":3785,"title":3786,"date":3787},"/posts/pattern-matching-sealed-classes-java21","A Guide to Pattern Matching and Sealed Classes in Java 21","2024-05-15T11:00:00.000Z",{"_path":3789,"title":3790,"date":3791},"/posts/async-java-completable-vs-reactive","Asynchronous Programming in Java: CompletableFuture vs Reactive Streams","2024-04-15T11:00:00.000Z",{"_path":3793,"title":3794,"date":3795},"/posts/mastering-concurrency","Mastering Concurrency in Java: Threads, Executors, and Virtual Threads","2024-03-15T11:00:00.000Z",{"_path":3797,"title":3798,"date":3799},"/posts/microservices-mistakes","Common Mistakes When Developing Microservices","2024-02-15T11:00:00.000Z",{"_path":3801,"title":3802,"date":3803},"/posts/tdd-testing","Test-Driven Development (TDD) in Java with JUnit and Mockito","2024-01-15T11:00:00.000Z",{"_path":3805,"title":3806,"date":3807},"/posts/single-table-design","Single Table Design","2023-12-27T11:00:00.000Z",{"_path":3809,"title":3810,"date":3811},"/posts/java-17","Exploring Java 17's New Features","2023-10-08T11:00:00.000Z",{"_path":3813,"title":3814,"date":3815},"/posts/hexagonal-architecture","Introduction to Hexagonal Architecture","2023-10-02 18:00:00",{"_path":4,"title":8,"date":10},{"_path":3818,"title":3819,"date":3820},"/posts/python-virtual-environments","Python Virtual Environments (venv)","2023-09-17 22:00:00",{"_path":3822,"title":3823,"date":3824},"/posts/api-first-principles","API First principles","2023-09-01 22:15:18",{"_path":3826,"title":3827,"date":3828},"/posts/how-to-configure-ssh-key-based-authentication","How To Configure SSH Key-Based Authentication","2021-02-21 03:46:12",{"_path":3830,"title":3831,"date":3832},"/posts/algorithms-binary-search-tree","Algorithms - Binary Search Tree in kotlin","2020-12-06T11:00:00.000Z",{"_path":3834,"title":3835,"date":3832},"/posts/how-to-create-a-twitter-bot","How to create a Twitter bot",{"_path":3837,"title":3838,"date":3839},"/posts/manage-aws-infrastructure-with-terraform","Bootstrap complete Java application infrastructure in AWS with Terraform","2020-12-02T11:00:00.000Z",{"_path":3841,"title":3842,"date":3843},"/posts/algorithms-working-with-trees","Algorithms - Binary tree traversals in kotlin","2020-11-24T11:00:00.000Z",{"_path":3845,"title":3846,"date":3847},"/posts/playing-with-ocr-libraries","Playing with OCR libraries","2020-11-22T11:00:00.000Z",1790510065879]