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