JBoss Tools Aggregated FeedJBoss Tools Aggregated FeedJBoss ToolsDebugging RestAssured TestsF.Marchionihttp://www.mastertheboss.com/various-stuff/testing-java/debugging-restassured-tests/2023-03-24T16:45:58ZWhen you run REST Assured tests, you may encounter errors such as failing assertions, incorrect responses, or unexpected behaviors. This article explains some techniques that can help you identify the root cause of these errors and fix them quickly. By debugging your tests, you can see what’s happening under the hood and find the issues ... The post appeared first on .F.MarchioniSimplify Kubernetes debugging with declarative logicMatteo Mortarihttps://blog.kie.org/2023/03/simplify-kubernetes-debugging-with-declarative-logic.html2023-03-23T10:34:41ZWe put Drools inside Kubernetes’ control plane …you wouldn’t believe what happened next! 😉 This is a longer post on the current status of explorations with RuleOps; you may want to skim or skip to different sections, depending on your interests. RuleOps in a nutshellRead time: ~ 1 minute Kubernetes is an orchestration platform, very powerful but also complex with multiple layers of abstraction, interdependent components, relying on automation and orchestration to manage deployments; this can make it difficult at times to pinpoint the actual root cause of an issue when troubleshooting. We have coined the terms RuleOps to identify both the abstract concept and the actual solution which can pragmatically be of support in many of those scenarios: 1. In the context of RuleOps, we believe that a declarative approach helps a lot while defining the root cause analysis, troubleshooting concepts, standard operating procedures (SOP), and is an effective instrument to help in debugging and troubleshooting Kubernetes operations. 2. We have developed a real application (based on Drools and Quarkus), which can be used from the command line as well as a continuously running application on a control plane, which demonstrates in practice the RuleOps concepts and techniques. We have implemented some best-practice troubleshooting guides available on the public domain as well as built PoC on some real SOP used by teams that we know. We believe RuleOps is valuable research exploration and a tangible, pragmatic, helpful instrument you can start to use in your day-to-day when managing a Kubernetes cluster. INTRODUCTION TO RULEOPS DevOps practitioners who interact daily with Kubernetes throughout its control plane know the problem of having to apply different resources, through different interactions. Every DevOps engineer has experienced the feeling of having forgotten to create a specific resource, having the cluster in an unknown state or not being sure about what is the best action to do next to continue troubleshooting. For example: if a Pod fails to start, it may be due to a misconfiguration in the Deployment, a problem with the container image, or an issue with the required resources on the cluster itself. For another example: a DevOps team has several configurations in place to ensure two namespaces are properly isolated and related policies to segment the network in the cluster; this requires performing checks and maintenance to mitigate the risk of configuration drift, across the lifecycles of application deployments and other general operations on the cluster. Troubleshooting may require digging through a variety of logs, configurations and exercising other debugging techniques. RuleOps solves this problem by providing a toolchain to help users writing custom rules that will check the consistency of the cluster and more generally speaking, the health of the system.  In the following we’ll see some theory behind RuleOps and how it can detect problems in your cluster Control Plane, with a real demo showing the actual rules the users can model and define. Here are some of the topic we’ll cover: * The team managing the cluster can use RuleOps as a foundation to align on the definition of a healthy system (for example, define what is the expected relationship between resources being developed, define what are the requirements of a strict cluster security configuration), by providing specific checks beyond what Kubernetes can perform out-of-the-box, also correlating internal and custom resources with a high-level declarative language especially optimized for executing a large number of checks. * RuleOps provides useful information about the issues so that DevOps and SRE can easily understand and resolve the issue. * The checks and the rules provided can be packaged in a series of reusable components that can be shared throughout the different DevOps. * In addition to that, RuleOps provides general rules that apply to most common error-cases that improves the debug experience of a vanilla cluster. After understanding RuleOps, users can start defining their own rules to fix the most common Kubernetes problems. BENEFITS TO THE KUBERNETES ECOSYSTEM We strongly believe that RuleOps with its powerful declarative language based on symbolic AI reasoning can help the Kubernetes ecosystem in building more healthy cloud based application, by detecting anomalies in the control plane configuration and improving on the amount of time DevOps and SREs will take to find and resolve problem in a Kubernetes cluster.  In addition to that, we’d like to provide some contributions to the conversation on how to improve the robustness of Kubernetes with external tools.  Various tools such as monitoring are already available; our focus is to offer the full power of a symbolic AI rule engine in this space. More specifically, even though Kubernetes by itself is a mature project and it’s meant to be reliable and consistent, once App Developers start building applications using the Kubernetes API a whole new set of problems emerge, i.e. how to handle the lifecycle of the custom resources, or how to make sure that error messages from the cluster are useful to the developers that need to detect inconsistent scenarios. Day-2 operations are especially affected, as these broken scenarios will need clear and solvable error messages even after the application has been deployed and it’s currently running. WHY RULEOPS We believe it’s important to highlight that in Kubernetes the etcd key-value store is used as the Source of Truth but, on the other hand, typically operations on the cluster (e.g.: through kubectl apply ) are performed on  several resources at different times, while the global configuration of the cluster is inherently eventually-consistent in nature. This could lead to a global or local configuration drift for cluster resources, and in some way a semantically inconsistent state of the cluster; the probability of reaching such an inconsistent state also correlates with the number of operations performed on the cluster. What we strive to do with RuleOps, in this whitepaper and demo, is to put more Dev skills inside of DevOps: from the software development principles we have a lot of debugging instruments which are at the core of our discipline and at the same time debugging can also be further complemented with a lot of automation using AI (Artificial Intelligence) as we will see in this content. We don’t want to overlook a potential opportunity for process improvement benefitting operations on the kubernetes cluster. We are also aware that AI these days is quite a buzzword, but what we mean for AI in this context is a very pragmatic AI approach, specifically focusing on Rule Engine (previously related to expert systems) and a symbolic AI, used for Knowledge Representation and Reasoning (KRR). Throughout the rest of this document, when we refer to AI, kindly keep this smaller disclaimer in mind. STATE OF THE ART IN DEBUGGING KUBERNETES A quick can sometimes be used as a litmus test for the actual day to day reality, especially when facing the needs of “Debugging Kubernetes” operations. The fact that such query returns millions of results and plenty of courses,  videos, and other training material is a clear indication that is a hot topic and likely a problem without a trivial solution, but at the same time an opportunity for people to acquire new knowledge, undergo training, and improve their skills. Another interesting consideration is that many of these “debugging kubernetes” resources are in the form of flowchart, decision tree, or more specifically if-this-do-that, when-this-do-that guides. This is interesting because it expresses a semantic reasoning, which can find a natural translation and equivalent in a semantic rule, such as DRL for Drools (but not limiting to DRL). For example: many times the knowledge in these types of resources resembles “please check these things first, if those fail, then check these other things …” in order to provide a framework to identify the root-cause of the problem; once the root-cause has been identified, corrective actions can be effectively performed. This is the perfect opportunity to automate all of this with KRR and a rule engine, such as Drools!  WHAT RULEOPS MEANS We coined the term RuleOps as an evolution of the term DevOps name. DevOps is a compound name that brings together Development and Operations; we want to play on the term itself and add to the mix also the Rules as coming from rule engine: we believe that the declarative power that can be expressed with the rule definition, together with a lot of the features that are typical of rule engine (such as Drools) really make it a perfect fit for debugging, inspecting and automating a lot of the semantic reasoning on the cluster resources and on the cluster status. DEMOS In this section, we present with pragmatic examples and real demo and working prototypes, some application of the RuleOps concepts. DEMO: “RELAX THE RESOURCEQUOTA LIMITS FOR DEPLOYMENT” For the first example we would like to make reference to a tutorial in the kubernetes documentation titled “”. Drawing inspiration from that tutorial, we simulate instead the case where a Deployment no longer fit the configured ResourceQuota on the cluster with: apiVersion: v1 kind: ResourceQuota metadata: name: pod-demo spec: hard: pods: "2" and: apiVersion: apps/v1 kind: Deployment metadata: name: pod-quota-demo spec: selector: matchLabels: purpose: quota-demo replicas: 3 template: metadata: labels: purpose: quota-demo spec: containers: - name: pod-quota-demo image: nginx Preparing this experiment on a Minikube-based lab environment, accessing the dashboard we can see the deployment is grayed out:  This scenario can easily be governed by defining a semantic rule using the domain model of kubernetes and in the rule example below we are correlating some of deployment conditions on the actual deployment: - name: Relax the ResourceQuota limits Deployment PENDING when: - given: Deployment as: $d - given: DeploymentCondition having: - type == "Available" - status == "False" from: $d.status.conditions - given: DeploymentCondition having: - message contains "exceeded quota" from: $d.status.conditions then: | insert(new Advice("Relax the ResourceQuota limits", ... And the RuleOps interface provide the defined advisory: This is a very first example on how to implement a declarative rule on a concept which was expressed by the troubleshooting debugging flowchart section, and instead of manually performing some checks, we automated the same checks in a declarative way. DEMO: “RELAX THE RESOURCEQUOTA LIMITS FOR STATEFULSET” In this example we would like to make reference to another tutorial in the kubernetes documentation titled “”. Drawing inspiration from that tutorial, we simulate instead the case where a StatefulSet no longer fit the configured ResourceQuota on the cluster with: apiVersion: v1 kind: ResourceQuota metadata: name: mem-cpu-demo spec: hard: requests.cpu: "1" requests.memory: 1Gi limits.cpu: "2" limits.memory: 2Gi and apiVersion: v1 kind: Pod metadata: name: quota-mem-cpu-demo spec: containers: - name: quota-mem-cpu-demo-ctr image: nginx resources: limits: memory: "1Gi" cpu: "1" requests: memory: "600Mi" cpu: "500m" and finally apiVersion: apps/v1 kind: StatefulSet metadata: labels: app.kubernetes.io/version: 1.0.0-SNAPSHOT app.kubernetes.io/name: hello-pvdf name: hello-pvdf namespace: default spec: replicas: 1 selector: matchLabels: app.kubernetes.io/name: hello-pvdf app.kubernetes.io/version: 1.0.0-SNAPSHOT serviceName: hello-pvdf template: metadata: labels: app.kubernetes.io/version: 1.0.0-SNAPSHOT app.kubernetes.io/name: hello-pvdf spec: containers: - env: - name: KUBERNETES_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace - name: PVDF_DIRECTORY value: /mnt/data image: quay.io/mmortari/hello-pvdf:1.0.0-SNAPSHOT imagePullPolicy: Always livenessProbe: failureThreshold: 3 httpGet: path: /q/health/live port: 8080 scheme: HTTP initialDelaySeconds: 0 periodSeconds: 30 successThreshold: 1 timeoutSeconds: 10 name: hello-pvdf ports: - containerPort: 8080 name: http protocol: TCP readinessProbe: failureThreshold: 3 httpGet: path: /q/health/ready port: 8080 scheme: HTTP initialDelaySeconds: 0 periodSeconds: 30 successThreshold: 1 timeoutSeconds: 10 resources: limits: cpu: 2000m memory: 2Gi requests: cpu: 500m memory: 500Mi volumeMounts: - mountPath: /mnt/data name: my-pvc-claim readOnly: false terminationGracePeriodSeconds: 10 volumeClaimTemplates: - apiVersion: v1 kind: PersistentVolumeClaim metadata: labels: app.kubernetes.io/version: 1.0.0-SNAPSHOT app.kubernetes.io/name: hello-pvdf name: my-pvc-claim namespace: default spec: accessModes: - ReadWriteOnce resources: requests: storage: 10Mi storageClassName: standard Preparing this experiment on a Minikube-based lab environment, accessing the dashboard we can see the stateful set is grayed out: This scenario can also be governed very easily by defining a declarative rule, again using the domain model of kubernetes correlating event from the StatefulSet: - name: Relax the ResourceQuota limits StatefulSet PENDING when: - given: StatefulSet as: $s having: - spec.replicas != status.replicas - given: Event having: - message contains "exceeded quota" from: DroolsK8sClient.eventsFor($s) then: | insert(new Advice("Relax the ResourceQuota limits", ... Again the RuleOps interface automatically generate the advisory: Please notice the name referenced in the advisory “hello-pvdf” is exactly the kubernetes resources we wanted to make reference to! DEMO: “FIX THE PERSISTENTVOLUMECLAIM FOR POD” In this example we would like to make reference to another tutorial in the kubernetes documentation titled “”. Drawing inspiration from that tutorial, we simulate instead the case where a Deployment is not healthy as a PersistentVolumeClaim is still pending because failing to bind on a matching persistent volume on the cluster with: apiVersion: v1 kind: PersistentVolumeClaim metadata: name: task-pv-claim spec: storageClassName: manual accessModes: - ReadWriteOnce resources: requests: storage: 3Gi and apiVersion: apps/v1 kind: Deployment metadata: name: pod-quota-demo spec: selector: matchLabels: purpose: quota-demo replicas: 1 template: metadata: labels: purpose: quota-demo spec: volumes: - name: task-pv-storage persistentVolumeClaim: claimName: task-pv-claim containers: - name: pod-quota-demo image: nginx ports: - containerPort: 80 name: "http-server" volumeMounts: - mountPath: "/usr/share/nginx/html" name: task-pv-storage Preparing this experiment on a Minikube-based lab environment, accessing the dashboard we can see the deployment is red: We can define a semantic rule to cover this scenario with ease: - name: Fix the PersistentVolumeClaim Pod PENDING when: - given: PersistentVolumeClaim as: $pvc having: - status.phase == "Pending" - given: Pod as: $pod having: - status.phase == "Pending" - given: Volume having: - persistentVolumeClaim!.claimName == $pvc.metadata.name from: $pod.spec.volumes then: | insert(new Advice("Fix the PersistentVolume", ... The RuleOps interface automatically generate the relevant advisory: Where we are clearly instructed about the need to fix the requirement of PersistentVolume so that the indicated pvc of the indicated pod can fully deploy. EXTRA: AUTOMATE IT WITH EVENT DRIVEN ANSIBLE! The same demo discussed in the previous chapter, can be further automated integrating it with . In this case, we extended the semantic rule to send a relevant event to an Ansible rulebook, which will be in charge of defining the appropriate remediating response depending on the type of events, and in the specific case of a missing PersistentVolume, we could invoke a playbook creating a new volume from a NAS and make that available to the Kubernetes cluster. In other scenarios, this integration could identify the requirements of more compute nodes, which could also be provided to the cluster with similar automation. We have demonstrated this integration with some sample rulebook and playbook: You can refer to this video for more details: DEMO: “FIX THE SERVICE SELECTOR: NO POD FOUND FOR SELECTOR” In this example, we’ll start from the perspective of overlooking the cluster with the dashboard: Everything seems to be working fine –all is green. But actually from an operational perspective we would not be satisfied with the current health of the system, as we will reveal by the end of this demo. We can showcase the command-line version of using RuleOps: In this scenario, we are advised that the Service selector is faulty. We believe this is of great help, because despite all dashboards looking green, the expressivity of the declarative rules allow us to capture the semantics of a healthy cluster –or a degraded cluster, as this demonstration highlighted. In summary: DEMO: “FIX THE SERVICE SELECTOR BECAUSE IT SOUNDS LIKE ANOTHER POD NAME BUT NOT AN EXACT MATCH” This demo is a variation of the previous one, where we would like to highlight other characteristics of the expressive power of the semantic rules, in order to catch name similarities which may produce inconsistent or degraded state of the cluster. Such rules could easily be expressed as, for example: - name: Fix the Service selector sounds like Pod name but not an exact match when: - given: Service as: $svc having: - metadata.name != "kubernetes" - '$selectorName: spec!.selector["app.kubernetes.io/name"]' - given: Pod as: $pod having: - 'metadata.labels["app.kubernetes.io/name"] != $selectorName' - 'metadata.labels["app.kubernetes.io/name"] soundslike $selectorName' then: | insert(new Advice("Service selector hint", ... In order to detect those anomalies with an increased level of nuances: DEMO: “FIX THE SERVICE TARGETPORT AND THE CONTAINERPORT” In this example we want to highlight the expressive power of the semantic rule making use of existential operators: - name: Fix the Service targetPort and the containerPort when: - given: Service as: $svc having: - metadata.name != "kubernetes" - given: ServicePort as: $sPort from: $svc.spec.ports - given: Pod as: $pod having: - 'mapContains(metadata.labels, $svc.spec.selector)' - not: - all: - given: Container as: $c from: $pod.spec.containers - given: ContainerPort having: - containerPort == $sPort.targetPort.intVal from: $c.ports then: 'insert(new Advice("Fix the Service targetPort and the containerPort", ... In order to detect mismatch between the definition in a service and its related pod: It is to be noted how making use of existential operators in semantic rules make it very easy to express declaratively these types of checks, with a relatively lower effort if compared to coding the same manually by hand using an imperative-style programming language. CONCLUSIONS (FOR TODAY!) We have introduced RuleOps, a concept and a very powerful instrument based on symbol AI, to help with debugging Kubernetes operations.  We have demonstrated with some entry-level but also pragmatic use-cases how RuleOps supports the DevOps practitioners while developing and deploying their application on Kubernetes. We believe RuleOps is valuable research exploration and a very helpful instrument you can start to use today, in your day-to-day management of Kubernetes cluster and cloud-native applications! The post appeared first on .Matteo Mortari10 tips for writing secure, maintainable DockerfilesAnthony Gimeiec08223e-ee14-433c-85e8-8e042404e8cb2023-03-23T07:00:00Z2023-03-23T07:00:00Z<p>This article provides tips and best practices for creating secure Dockerfiles that are highly maintainable. Like code, Dockerfiles change over time and, therefore, should be written in such a way that makes them easy to update in the future. It is also important that the images that they create are secure and do not contain unnecessary vulnerabilities that increase the attack surface for your application. The image produced should be as small as possible because the image(s) must be stored remotely and transported in the network. Also, they must not be blotted. Finally, the Dockerfile, like any well-written code, should be easy to understand and use.</p> <h2>10 Tips and best practices for Dockerfiles</h2> <p>The following list describes tips and best practices for creating secure Dockerfiles that are highly maintainable.</p> <h3>1. Use the current release base upstream image</h3> <p>Always use the most current release base upstream image to provide security. <a href="https://developers.redhat.com/articles/2021/11/11/best-practices-building-images-pass-red-hat-container-certification">Red Hat recommends</a>:</p> <ul><li class="Indent1">Use the latest release of a base image. This release should contain the latest security patches available when the base image is built. When a new release of the base image is available, rebuild the application image to incorporate the base image's latest release because that release contains the latest fixes.</li> <li class="Indent1">Conduct vulnerability scanning. Scan a base or application image to confirm that it doesn't contain any known security vulnerabilities.</li> </ul><h3>2. Use a specific image tag or version</h3> <p>Use a specific tag or version for your image, not "latest". This gives your image traceability. When troubleshooting the running container, the exact image will be obvious.</p> <p>Examples:</p> <ul><li>Do this:  <strong><code>nginx:1.23.1</code></strong></li> <li>Don't do this:  <strong><code>nginx:latest</code></strong></li> </ul><h3>3. Run images as USER</h3> <p>For security purposes, always ensure that your images run as non-root by defining <strong><code>USER</code></strong> in your Dockerfile. Additionally, set the permissions for the files and directories to the user. Because the Docker daemon runs as root, the Docker images run as root by default. This means if a process in the container goes rogue or gets hijacked and accesses the host, it will run with root access. This is certainly not secure.</p> <p>However, <a href="https://podman.io/">Podman</a> is daemonless and rootless by design and, therefore, more secure.</p> <p>The following is an example.</p> <ul><li>Add <code>USER</code> to your Dockerfile.</li> <li>Skipped configurations are indicated by:  ...</li> </ul><pre> <code class="language-bash">... USER 1001 RUN chown -R 1001:0 /some/directory chmod -R g=u /some/directory ... </code></pre> <h3>4. Choose base images without the full OS</h3> <p>Always choose the smallest base images that do not contain the complete or full-blown OS with system utilities installed. You can install the specific tools and utilities needed for your application in the Dockerfile build. This will reduce possible vulnerabilities and the attack surface of your image.</p> <h3>5. Use multi-stage Dockerfiles</h3> <p>Build images using <a href="https://docs.docker.com/develop/develop-images/multistage-build/">multi-stage</a> Dockerfiles to keep the image small. For example, for a Java application running in Open Liberty, use one stage to do the compile and build, and another stage to copy the binary artifact(s) and dependencies into the image, discarding all nonessential artifacts. Another example is, for an Angular application, run the npm install and build in one stage and copy the built artifacts in the next stage.</p> <ul><li>Example: Open Liberty Java application</li> </ul><pre> <code>FROM registry.access.redhat.com/ubi8/openjdk-8:latest as builder USER 0 WORKDIR /tmp/app COPY src/ src/ COPY pom.xml pom.xml RUN mvn clean package ... FROM quay.io/ohthree/open-liberty:22.0.0.4 ... COPY --from=builder /tmp/app/src/main/liberty/config/server.xml /config/ COPY --from=builder /tmp/app/target/*.war /config/apps/ RUN \ chown -R 1001:0 /config && \ chmod -R g=u /config # Run as non-root user USER 1001 EXPOSE 9081 </code></pre> <h3>6. Use Docker ignore file</h3> <p>Use a <code>.dockerignore</code> file to ignore files that do not need to be added to the image.</p> <h3>7. Scan for vulnerabilities</h3> <p>Scan your images for known vulnerabilities.</p> <ul><li>Podman integrates with multiple open-source scanning tools. For example, you can use <a href="https://www.redhat.com/en/blog/using-snyk-and-podman-scan-container-images-development-deployment">Synk</a> or <a href="https://aquasecurity.github.io/trivy/v0.37/docs/target/container_image/#podman">Trivy</a>.</li> <li>Docker integrates with its own plugin local machine. Install the <a href="https://docs.docker.com/engine/scan/">plugin</a>, then run the following command: </li> </ul><p class="Indent2"><code>$ docker scan myappimage:1.0</code></p> <h3>8. Automate scans</h3> <p>Automated scanning tools should also be implemented in the CI pipeline and on the enterprise registry. We also recommend deploying runtime scanning on applications in case a vulnerability is uncovered in the future.</p> <h3>9. Organize your Docker commands</h3> <p>Organize your Docker commands, especially the <code>COPY</code> command, in such a way that the files that change most frequently are at the bottom. This will speed up the build process. The reason for this is to take advantage of the Docker build process and speed up future builds.</p> <p>Each Docker build command creates a layer that is cached to be reused in the next build, designed to speed up subsequent builds. The caveat is that, in the subsequent build, if a command encounters a change, all commands after that will run and recreate new layers and cached, replacing the old ones even if they did not contain any changes. Having the most volatile <code>COPY</code> statements later in the Dockerfile maximize build caching.</p> <h3>10. Concatenate RUN commands</h3> <p>Concatenate <code>RUN</code> commands to make your Dockerfile more readable and create fewer layers. Fewer layers mean a smaller container image. As mentioned previously, each <code>RUN</code> statement in the Dockerfile creates a layer that gets cached. Concatenating reduces the number of layers.</p> <p>The following are examples of what to do and not to do.</p> <ul><li>Don't do this:</li> </ul><pre> <code class="language-bash">... RUN yum --disablerepo=* --enablerepo=”rhel-7-server-rpms” RUN yum update RUN yum install -yl httpd ...</code></pre> <ul><li>Do this instead:</li> </ul><pre> <code class="language-bash">... RUN yum --disablerepo=* --enablerepo=”rhel-7-server-rpms” && yum update && yum install -yl httpd ...</code></pre> <ul><li>Even better, do this for readability:</li> </ul><pre> <code class="language-bash">... RUN yum --disablerepo=* --enablerepo=”rhel-7-server-rpms” && \ yum update && \ yum install -yl httpd ...</code></pre> <h2>Find more resources</h2> <p>We hope that these tips will help you build more secure Dockerfiles. Visit the <a href="https://docs.docker.com/develop/develop-images/dockerfile_best-practices/">Docker website</a> for more information. See what we are doing on the <a href="https://developers.redhat.com/articles/2021/11/11/best-practices-building-images-pass-red-hat-container-certification#)">Red Hat Developers Site</a>. You can learn more about containerizing applications at <a href="https://www.redhat.com/en/services/training/do080-deploying-containerized-applications-technical-overview">Red Hat DO 180 training</a>. If you have a question, feel free to comment below. We welcome your feedback.</p> The post <a href="https://developers.redhat.com/articles/2023/03/23/10-tips-writing-secure-maintainable-dockerfiles" title="10 tips for writing secure, maintainable Dockerfiles">10 tips for writing secure, maintainable Dockerfiles</a> appeared first on <a href="https://developers.redhat.com/blog" title="Red Hat Developer">Red Hat Developer</a>. <br /><br />Anthony Gimei2023-03-23T07:00:00ZThis Week in JBoss - March, 23 2023Francesco Marchionihttps://www.jboss.org/people/francesco-marchionido-not-reply@jboss.comhttps://www.jboss.org/posts/weekly-2023-03-23.html2023-03-23T00:00:00Z<article class="" data-tags="quarkus, java, wildfly, camel, ansible, infinispan, strimzi"> <h1>This Week in JBoss - March, 23 2023</h1> <p class="preamble"></p><p>Happy Friday, everyone!</p> <p>Here is another edition of the JBoss Editorial with exciting news and updates from your JBoss communities.</p><p></p> <div class="sect1"> <h2 id="_release_roundup">Release roundup</h2> <div class="sectionbody"> <p>Here are the most recent releases for this edition:</p> <div class="ulist square"> <ul class="square"> <li> <p><a href="https://infinispan.org/blog/2023/03/13/infinispan-14/">Infinispan 14.0.7</a> - Although it’s just a minor release update, there is an important update in it: the support for Spring 6 and Spring Boot 3 is finally available! Check the blog post for more news about this release.</p> </li> <li> <p><a href="https://quarkus.io/blog/quarkus-3-0-0-alpha6-released/">Quarkus 3.0.0.Alpha6 released</a> - This new minor release continues the path to the upcoming Quarkus version. Besides, it contains an enhancements to export OpenTelemetry data via JDBC.</p> </li> <li> <p><a href="https://camel.apache.org/blog/2023/03/RELEASE-4.0.0-M2/">Camel RELEASE 4.0.0-M2 available</a> - The Camel community announces the availability of Camel 4.0.0-M2, the second milestone towards a new 4.0.0 major release which comes with 75 new features and improvements.</p> </li> </ul> </div> </div> </div> <div class="sect1"> <h2 id="_a_tutorial_on_middleware_automation_collections">A tutorial on Middleware Automation Collections</h2> <div class="sectionbody"> <p><a href="https://www.wildfly.org/news/2022/11/10/wildfly-docker-temurin/">A tutorial on Middleware Automation Collections</a>, by Harsha Cherukuri.</p> <p>This article discusses the ease of getting started with Ansible Middleware Collections and installing the Red Hat Ansible Automation Platform. It describes a tutorial that demonstrates how to configure a WildFly instance using Ansible in six steps, starting with preparing a local machine with the necessary tooling and deploying an instance of WildFly using the WildFly collection provided by the Ansible Middleware.</p> </div> </div> <div class="sect1"> <h2 id="_updates_on_wildfly_maven_plugin">Updates on WildFly Maven Plugin</h2> <div class="sectionbody"> <p><a href="https://www.wildfly.org/news/2023/03/09/WildFly-Maven-Plugin/">WildFly Maven Plugin</a>, by James R. Perkins</p> <p>The wildfly-maven-plugin now includes a dev goal that functions similarly to the run goal, but with the added feature of monitoring source files for changes. In the event of any changes, the plugin automatically rebuilds and redeploys the WAR. This page documents the latest addition which is available in the version 4.1.0.Beta3 of the wildfly-maven-plugin.</p> <p>Besides, you can check this step-by-step guide on <a href="http://www.mastertheboss.com/jbossas/jboss-deploy/how-to-live-reload-applications-on-wildfly/">how to enable live reload</a> of WildFly applications using the dev goal.</p> </div> </div> <div class="sect1"> <h2 id="_getting_started_with_camel_k">Getting started with Camel K</h2> <div class="sectionbody"> <p><a href="http://www.masterspringboot.com/camel/getting-started-with-camel-k-tutorial/">Getting started with Camel-k</a>, by Francesco Marchioni</p> <p>Camel K is a lightweight integration framework built from Apache Camel K that runs natively in the cloud on OpenShift. If you want to get started with it in less than 5 minutes, than this is the article for you!</p> </div> </div> <div class="sect1"> <h2 id="_video_whats_new_in_strimzi_0_34_0">Video: What’s new in Strimzi 0.34.0</h2> <div class="sectionbody"> <p><a href="https://strimzi.io/blog/2023/03/20/what-is-new-in-strimzi-0.34.0/">What’s new in Strimzi 0.34.0</a>, by Jakub Scholz</p> <p>Strimzi 0.34.0 has been released with multiple new features and improvements such as Stable Pod names in Connect. This video will give you an heads up about the new release in just 3 minutes!</p> <p><em>That’s all folks! Please join us again in two weeks for another round of our JBoss editorial!</em></p> </div> </div> <div class="author"> <pfe-avatar pfe-shape="circle" pfe-pattern="squares" pfe-src="/img/people/francesco-marchioni.png"></pfe-avatar> <span>Francesco Marchioni</span> </div></article>Francesco MarchioniHow to enable OpenTelemetry traces in React applicationsPurva Naikc6739437-ace4-4f9f-af8c-3ae22cbf76842023-03-22T07:00:00Z2023-03-22T07:00:00Z<p>The main focus of this article is to demonstrate how to instrument React applications to make them observable. For a good overview of observability and OpenTelemetry, please take a look at the article, <a href="https://developers.redhat.com/articles/2022/04/12/observability-2022-why-it-matters-and-how-opentelemetry-can-help#why_is_observability_important_">Observability in 2022: Why it matters and how OpenTelemetry can help</a>.</p> <ul></ul><h2>10-step OpenTelemetry demonstration</h2> <p>Related to the OpenTelemetry, we are using the following:</p> <ul><li>Auto instrumentation via <a href="https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-sdk-trace-web">sdk-trace-web</a> and a plugin to provide auto instrumentation for <a href="https://github.com/open-telemetry/opentelemetry-js/tree/main/experimental/packages/opentelemetry-instrumentation-fetch#opentelemetry-fetch-instrumentation-for-web">fetch</a>.</li> <li>OpenTelemetry Collector (also known as <code>OTELCOL</code>).</li> <li>Jaeger</li> <li>Basic collector deployment pattern. For more information about <code>OTELCOL</code> deployment patterns, please take a look at <a href="https://github.com/jpkrohling/opentelemetry-collector-deployment-patterns">OpenTelemetry Collector Deployment Patterns</a>.</li> </ul><h3>Step 1. Set up prerequisites</h3> <p>In this demo, we are going to use Docker and docker-compose. You can refer to <a href="https://docs.docker.com/get-started/">Docker</a> and <a href="https://docs.docker.com/compose/">docker-compose</a> to learn more.</p> <h3>Step 2. Run the React application example</h3> <p>You will be using a <a href="https://github.com/obs-nebula/frontend-react">front-end react application</a> that contains the sample React application code that we will instrument. Please note that the repository also contains an Express application as a back end, but the focus of this tutorial is to instrument the front end only.</p> <p>The front-end application contains a button that calls the back end using Express and a scroll component that calls the <a href="https://randomuser.me/">https://randomuser.me/</a> free public API. We are going to delegate to OpenTelemetry libraries the job of capturing traces for the button and the scroll component. So every time the user clicks on the button or scrolls the page, the auto-instrumentation plugin will generate traces for this.</p> <p>Clone the following GitHub repository from the command line:</p> <pre> <code class="language-bash">git clone https://github.com/obs-nebula/frontend-react.git</code></pre> <h3>Step 3. Instrument the React application</h3> <p>The following list shows the dependencies we added. You may want to use newer versions, depending on when you are reading this article:</p> <pre> <code class="language-json">"@opentelemetry/exporter-trace-otlp-http": "^0.35.0", "@opentelemetry/instrumentation": "^0.35.0", "@opentelemetry/instrumentation-fetch": "^0.35.0", "@opentelemetry/resources": "^1.9.1", "@opentelemetry/sdk-trace-web": "^1.8.0", "@opentelemetry/semantic-conventions": "^1.9.1"</code></pre> <p>Create a file named <code>tracing.js</code> that will load OpenTelemetry. We are going to share more details in the following subsections. The content of the <code>front-end/src/tracing.js</code> file is as follows:</p> <pre> <code class="language-javascript">const { Resource } = require('@opentelemetry/resources'); const { SemanticResourceAttributes } = require('@opentelemetry/semantic-conventions'); const { WebTracerProvider, SimpleSpanProcessor, ConsoleSpanExporter } = require('@opentelemetry/sdk-trace-web'); const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-http'); const { registerInstrumentations } = require('@opentelemetry/instrumentation'); const { FetchInstrumentation } = require('@opentelemetry/instrumentation-fetch'); const consoleExporter = new ConsoleSpanExporter(); const collectorExporter = new OTLPTraceExporter({ headers: {} }); const provider = new WebTracerProvider({ resource: new Resource({ [SemanticResourceAttributes.SERVICE_NAME]: process.env.REACT_APP_NAME }) }); const fetchInstrumentation = new FetchInstrumentation({}); fetchInstrumentation.setTracerProvider(provider); provider.addSpanProcessor(new SimpleSpanProcessor(consoleExporter)); provider.addSpanProcessor(new SimpleSpanProcessor(collectorExporter)); provider.register(); registerInstrumentations({ instrumentations: [ fetchInstrumentation ], tracerProvider: provider }); export default function TraceProvider ({ children }) { return ( <> {children} </> ); }</code></pre> <h3>Step 4. Import the required modules</h3> <p>Next, you will need to import the OpenTelemetry modules. As you can see, we can get the <code>ConsoleSpanExporter</code> and <code>SimpleSpanProcessor</code> from the @opentelemetry/sdk-trace-web so we don’t need to add an extra dependency for this.</p> <pre> <code class="language-javascript">const { Resource } = require('@opentelemetry/resources'); const { SemanticResourceAttributes } = require('@opentelemetry/semantic-conventions'); const { WebTracerProvider,SimpleSpanProcessor, ConsoleSpanExporter } = require('@opentelemetry/sdk-trace-web'); const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-http'); const { registerInstrumentations } = require('@opentelemetry/instrumentation'); const { FetchInstrumentation } = require('@opentelemetry/instrumentation-fetch');</code></pre> <h3>Step 5. Initialize the tracer</h3> <p>Since we are using React with JavaScript, to initialize the OpenTelemetry tracer, you will need to create a new instance of the <code>TraceProvider</code> and pass it as a property to your root React component. You can do this by adding the following code to your main application file, in our case, that is in index.js file.</p> <pre> <code class="language-javascript">import TraceProvider from './tracing'; const root = ReactDOM.createRoot(document.getElementById('root')); root.render( <TraceProvider> <App /> </TraceProvider> );</code></pre> <h3>Step 6. Create an OTELCOL exporter instance</h3> <p>To export the traces to <code>OTELCOL</code>, you will need to create an instance of <code>OTLPTraceExporter</code>.</p> <p>Note that we are adding a workaround to use <a href="https://developer.mozilla.org/en-US/docs/Glossary/XMLHttpRequest">XHR</a> instead of <a href="https://developer.mozilla.org/en-US/docs/Web/API/Navigator/sendBeacon">sendBeacon</a>, as described in this OpenTelemetry JS upstream <a href="https://github.com/open-telemetry/opentelemetry-js/issues/3062#issuecomment-1189189494">issue</a>. With that, we can fix the CORS problem when exporting.</p> <pre> <code class="language-javascript">const collectorExporter = new OTLPTraceExporter({ headers: {} });</code></pre> <h3>Step 7. Create the otel-collector-config file</h3> <p>Now let’s take a look at the yaml file content. To configure the <code>OTELCOL</code>, you will need to create a new file called <code>otel-collector-config.yaml</code> in your root directory. In this file, we are going to configure the receiver, processor, and exporters (using Jaeger and logging as exporters).</p> <pre> <code class="language-yaml">receivers: otlp: protocols: http: cors: allowed_origins: ["*"] allowed_headers: ["*"] exporters: logging: verbosity: Detailed jaeger: endpoint: jaeger-all-in-one:14250 tls: insecure: true processors: batch: service: telemetry: logs: level: "debug" pipelines: traces: receivers: [otlp] exporters: [logging, jaeger] processors: [batch]</code></pre> <h3>Step 8. Create a docker compose file</h3> <p>Create a docker-compose file and define the services for <code>OTELCOL</code>, Jaeger, and the application as follows:</p> <pre> <code class="language-yaml">version: "2" services: front-end: build: context:./front-end depends_on: - express-server ports: - "3000:3000" env_file: -./front-end/src/.env express-server: build: context:./express-server ports: - "5000:5000" collector: image: otel/opentelemetry-collector:latest command: ["--config=/otel-collector-config.yaml"] volumes: - './otel-collector-config.yaml:/otel-collector-config.yaml' ports: - "4318:4318" depends_on: - jaeger-all-in-one # Jaeger jaeger-all-in-one: hostname: jaeger-all-in-one image: jaegertracing/all-in-one:latest ports: - "16685" - "16686:16686" - "14268:14268" - "14250:14250"</code></pre> <h3>Step 9. Start the services</h3> <p>Once you have created <code>OTELCOL</code> config and Docker compose files, you can start the services by running the following command in your terminal:</p> <pre> <code>$docker-compose up</code></pre> <p>Once the services are started you can access the react application at <a href="http://localhost:3000">http://localhost:3000</a>.</p> <p>As mentioned previously, every time the users scroll the page, it will generate random data through an API call and the OpenTelemetry will generate traces based on the scrolling activity.</p> <h3>Step 10. View the traces in Jaeger</h3> <p>You can view the traces in the Jaeger UI by navigating to <a href="http://localhost:16686">http://localhost:16686</a>. The horizontal circles in the chart represent button clicks, and the vertical circles represent scrolling activity, as shown in Figure 1.</p> <div class="rhd-c-figure"> <article class="align-center media media--type-image media--view-mode-article-content"><div class="field field--name-image field--type-image field--label-hidden field__items"> <a href="https://developers.redhat.com/sites/default/files/jaeger.png" data-featherlight="image"><img loading="lazy" src="https://developers.redhat.com/sites/default/files/styles/article_floated/public/jaeger.png?itok=a8j9x5tC" width="600" height="290" alt="The jaeger UI showing circles in the chart that represent button clicks and scrolling activity." typeof="Image" /></a> </div><div class="field field--name-field-caption field--type-string field--label-hidden field__items"> <div class="rhd-c-caption field__item">Figure 1: Application tracing in Jaeger.</div> </div> </article></div> <p>Let's click on one of the horizontal items and expand the trace detail as shown in Figure 2:</p> <div class="rhd-c-figure"> <article class="align-center media media--type-image media--view-mode-article-content"><div class="field field--name-image field--type-image field--label-hidden field__items"> <a href="https://developers.redhat.com/sites/default/files/2023-02-24_09-14.png" data-featherlight="image"><img loading="lazy" src="https://developers.redhat.com/sites/default/files/styles/article_floated/public/2023-02-24_09-14.png?itok=XJ69RS8q" width="600" height="304" alt="In the Jaeger UI, expanded trace detail shows the Express back-end was called and the OpenTelemetry library name." typeof="Image" /></a> </div><div class="field field--name-field-caption field--type-string field--label-hidden field__items"> <div class="rhd-c-caption field__item">Figure 2: The expanded trace detail shows the Express back-end was called and the OpenTelemetry library name.</div> </div> </article></div> <p>We can see in Figure 2 that the Express back end was called, and the OpenTelemetry library name that is responsible for this trace generation.</p> <p>Now let’s click in one vertical circle as shown in Figure 3:</p> <div class="rhd-c-figure"> <article class="align-center media media--type-image media--view-mode-article-content"><div class="field field--name-image field--type-image field--label-hidden field__items"> <a href="https://developers.redhat.com/sites/default/files/type.png" data-featherlight="image"><img loading="lazy" src="https://developers.redhat.com/sites/default/files/styles/article_floated/public/type.png?itok=qb9l_okb" width="600" height="345" alt="The trace information showing that the scrolling activity is calling an external API." typeof="Image" /></a> </div><div class="field field--name-field-caption field--type-string field--label-hidden field__items"> <div class="rhd-c-caption field__item">Figure 3: The trace information showing that the scrolling activity is calling an external API.</div> </div> </article></div> <p>We can see in Figure 3 that scrolling activity is calling an external API.</p> <h2>Collecting and analyzing telemetry data</h2> <p>You have successfully enabled OpenTelemetry in your React application using the OpenTelemetry collector and Jaeger. You can now start collecting and analyzing telemetry data. You can use the Jaeger UI to view traces, identify performance bottlenecks, and gain deeper understanding about what the React application is doing when calling external systems.</p> <h2>Further reading</h2> <p>Want to learn more about observability and OpenTelemetry? Check out these articles:</p> <ul><li><a href="https://developers.redhat.com/articles/2022/04/12/observability-2022-why-it-matters-and-how-opentelemetry-can-help">Observability in 2022: Why it matters and how OpenTelemetry can help</a></li> <li><a href="https://developers.redhat.com/articles/2022/06/21/distributed-tracing-opentelemetry-knative-and-quarkus">Distributed tracing with OpenTelemetry, Knative, and Quarkus</a></li> <li><a href="https://developers.redhat.com/blog/2019/05/01/a-guide-to-the-open-source-distributed-tracing-landscape">A guide to the open source distributed tracing landscape</a></li> </ul> The post <a href="https://developers.redhat.com/articles/2023/03/22/how-enable-opentelemetry-traces-react-applications" title="How to enable OpenTelemetry traces in React applications">How to enable OpenTelemetry traces in React applications</a> appeared first on <a href="https://developers.redhat.com/blog" title="Red Hat Developer">Red Hat Developer</a>. <br /><br />Purva Naik2023-03-22T07:00:00ZQuarkus 2.16.5.Final released - Maintenance releaseGuillaume Smethttps://quarkus.io/blog/quarkus-2-16-5-final-released/2023-03-22T00:00:00ZWe released Quarkus 2.16.5.Final, the fifth maintenance release of our 2.16 release train. As usual, it contains bugfixes and documentation improvements. It should be a safe upgrade for anyone already using 2.16. If you are not already using 2.16, please refer to our migration guide. Full changelog You can get...Guillaume SmetHow to investigate 7 common problems in productionMichael Dawson4c05d237-a97b-4969-a2c7-7cc828ba19182023-03-21T07:00:00Z2023-03-21T07:00:00Z<p>Leveraging the experience shared in the <a data-entity-substitution="canonical" data-entity-type="node" data-entity-uuid="43652567-d1ab-4765-a588-4e905032ad7f" href="https://developers.redhat.com/topics/nodejs" title="Node.js: Develop server-side JavaScript applications">Node.js</a> reference architecture can help you minimize problems in production. However, it's a fact of life that problems will still occur and you need to do problem determination. This installment of the ongoing <a href="https://github.com/nodeshift/nodejs-reference-architecture">Node.js Reference Architecture</a> series covers the Node.js reference architecture team’s experience with respect to how you can investigate common problems when they do occur.</p> <p>7 common problems include:</p> <ul><li>Memory leaks</li> <li>Hangs or slow performance</li> <li>Application failures</li> <li>Unhandled promise rejections or exceptions</li> <li>Resource leaks</li> <li>Network issues</li> <li>Natives crashes</li> </ul><p>Read the series so far:</p> <ul><li>Part 1: <a href="https://developers.redhat.com/blog/2021/03/08/introduction-to-the-node-js-reference-architecture-part-1-overview">Overview of the Node.js reference architecture</a></li> <li>Part 2: <a href="https://developer.ibm.com/blogs/nodejs-reference-architectire-pino-for-logging/">Logging in Node.js</a></li> <li>Part 3: <a href="https://developers.redhat.com/articles/2021/05/17/introduction-nodejs-reference-architecture-part-3-code-consistency">Code consistency in Node.js</a></li> <li>Part 4: <a href="https://developers.redhat.com/articles/2021/06/22/introduction-nodejs-reference-architecture-part-4-graphql-nodejs">GraphQL in Node.js</a></li> <li>Part 5: <a href="https://developers.redhat.com/articles/2021/08/26/introduction-nodejs-reference-architecture-part-5-building-good-containers">Building good containers</a></li> <li>Part 6: <a href="https://developers.redhat.com/articles/2021/12/03/introduction-nodejs-reference-architecture-part-6-choosing-web-frameworks">Choosing web frameworks</a></li> <li>Part 7: <a href="https://developers.redhat.com/articles/2022/03/02/introduction-nodejs-reference-architecture-part-7-code-coverage">Code Coverage</a></li> <li>Part 8: <a href="https://developers.redhat.com/articles/2022/04/11/introduction-nodejs-reference-architecture-part-8-typescript">Typescript</a></li> <li>Part 9: <a href="https://developers.redhat.com/articles/2022/08/09/8-elements-securing-nodejs-applications">Securing Node.js applications</a></li> <li>Part 10: <a href="https://developers.redhat.com/articles/2022/11/03/nodejs-reference-architecture-part-10-accessibility">Accessibility</a></li> <li>Part 11: <a href="https://developers.redhat.com/articles/2022/12/21/typical-development-workflows">Typical development workflows</a></li> <li>Part 12: <a href="https://developers.redhat.com/articles/2023/02/22/installing-nodejs-modules-using-npm-registry">Npm development</a></li> <li><strong>Part 13: Problem determination</strong></li> </ul><h2>Preparing for production problems</h2> <p>Investigating problems in production most often requires tools and processes to be in place and approved in advance. It is important to define the tools you’ll rely on and to get approval for those tools to either already be in place or to be installed when needed. Production environments are often tightly controlled, and doing this in advance will speed up your ability to get information when problems do occur.</p> <p>The team typically used one of the following to capture a set of metrics regularly in production:</p> <ul><li>Existing application performance management (APM) offering</li> <li>Custom solution leveraging available platform tools (for example, those provided by a cloud provider or <a href="https://developers.redhat.com/products/openshift/overview">Red Hat OpenShift</a>)</li> </ul><p>You can read more about the suggested approach for capturing metrics in the <a href="https://github.com/nodeshift/nodejs-reference-architecture/blob/main/docs/operations/metrics.md">metrics</a> section. When those metrics have identified there is a problem, it’s time to kick off the problem determination process and try to match the symptoms to one of the common problems. </p> <h2>APM or custom solution</h2> <p>From the discussion we had within the team, one of the key factors of whether you want to use an APM or custom solution is whether you are operating a service or developing an application that will be operated by your customers.</p> <p>If you are operating a service where you own all deployments an existing application performance management (APM) solution can make sense if budget is not an issue. They offer the advantage of requiring less upfront investment and leveraging a solution designed to help investigate problems. The team has had success with using <a href="https://www.dynatrace.com/">Dynatrace</a>, <a href="https://www.ibm.com/cloud/instana">Instana</a>, and <a href="https://newrelic.com/">NewRelic</a>.</p> <p>If you develop applications that will be operated by customers, adding a dependency on a specific APM for problem determination is not recommended. The cost may be an issue for some customers, while others may already have standardized on a specific APM.</p> <p>Whichever you choose, you’ll want to be ready to:</p> <ul><li>Instrument the application in order to capture:  <ul><li><a href="https://github.com/nodeshift/nodejs-reference-architecture/blob/main/docs/operations/logging.md">Logs</a></li> <li><a href="https://github.com/nodeshift/nodejs-reference-architecture/blob/main/docs/operations/metrics.md">Metrics</a></li> <li><a href="https://github.com/nodeshift/nodejs-reference-architecture/blob/main/docs/operations/distributed-tracing.md">Traces</a></li> </ul></li> <li>Generate and extract heap snapshots.</li> <li>Generate and extract core dumps.</li> <li>Dynamically change log levels.</li> </ul><p>The <a href="https://github.com/nodeshift/nodejs-reference-architecture/blob/main/docs/operations/problem-determination.md#implementation">implementation</a> section of the problem-determination section of the Node.js reference architecture has some good suggestions on how to do these based on our experience.</p> <h2>Investigating specific problems</h2> <p>Once you have your chosen approach in place (APM or custom) and your metrics start reporting an issue, the general flow the team discussed and agreed on for problem determination was to:</p> <ol><li>Match the symptoms reported by traces, metrics, logs, and health checks to one of the common problems.</li> <li>Follow a set of steps from easiest to hardest to confirm/refute the suspected problem.</li> <li>When confirmed, capture additional information. </li> <li>Repeat as necessary until you’ve narrowed it down to the right problem.</li> </ol><p>I won’t repeat the content from the <a href="https://github.com/nodeshift/nodejs-reference-architecture/blob/main/docs/operations/problem-determination.md#common-problems">common problems</a> section of the problem determination section in the reference architecture. But each problem includes:</p> <ul><li>Symptoms - how to identify the problem from the traces, metrics, logs, or health checks.</li> <li>Approach - the steps and tools used by the team to investigate and capture more information for that problem.</li> <li>Guidance - guidance and things to look out for when applying the approach suggested.</li> </ul><p>The  <a href="https://github.com/nodeshift/nodejs-reference-architecture/blob/main/docs/operations/problem-determination.md#common-problems">common problems</a> section covers the following problems based on the team's experience:</p> <ul><li>Memory leaks</li> <li>Hangs or slow performance</li> <li>Application failures</li> <li>Unhandled promise rejections or exceptions</li> <li>Resource leaks</li> <li>Network issues</li> <li>Natives crash</li> </ul><p>The information in that section for each of those problems should help you identify what problem your application is encountering based on the symptoms and then investigate to get more information as to what might be causing it to occur.</p> <h2>Coming next</h2> <p>I hope that this quick overview of the problem determination section of the Node.js Reference Architecture, along with the team discussions that led to that content, has been helpful and that the information shared in the architecture helps you in your future problem determination efforts.</p> <p>We plan to cover new topics regularly as part of the <a href="https://developers.redhat.com/blog/2021/03/08/introduction-to-the-node-js-reference-architecture-part-1-overview/">Node.js reference architecture series</a>. Until the next installment, we invite you to visit the <a href="https://github.com/nodeshift/nodejs-reference-architecture">Node.js reference architecture repository</a> on GitHub, where you will see the work we have done and future topics. </p> <p>To learn more about what Red Hat is up to on the Node.js front, check out our <a href="https://developers.redhat.com/topics/nodejs">Node.js page</a>.</p> The post <a href="https://developers.redhat.com/articles/2023/03/21/how-investigate-7-common-problems-production" title="How to investigate 7 common problems in production">How to investigate 7 common problems in production</a> appeared first on <a href="https://developers.redhat.com/blog" title="Red Hat Developer">Red Hat Developer</a>. <br /><br />Michael Dawson2023-03-21T07:00:00ZKogito 1.35.0 released!Cristiano Nicolaihttps://blog.kie.org/2023/03/kogito-1-35-0-released.html2023-03-17T12:58:52ZWe are glad to announce that the Kogito 1.35.0 release is now available! This goes hand in hand with , release. From a feature point of view, we have included a series of new features and bug fixes, including: * Flyway integration for JDBC based persistence * We have removed the use of kogito.persistence.auto.ddl property to initialize tables across persistence in Kogito. When using kogito-addons-quarkus-persistence-jdbc extension, we must set the quarkus.datasource.db-kind property to locate appropriate schema scripts. * GET <processId> API does not return all active process instances any longer, but a subset of them. The number of instances returned is determined by the property kogito.process.instances.limit, whose default value is 1000. If you need finer control of those instances, please check data-index functionality.  * Users that want to reduce memory footprint might replace quarkus postgresql extension  (quakus-jdbc-postgresql) by extension (quarkus-embedded-postgresql) * Data Index allows to be configured to use http-connector to consume Knative eventing. BREAKING CHANGES * Removed kogito.persistence.auto.ddl property for JDBC persistence addons ( kogito-addons-quarkus-persistence-jdbc and kogito-addons-springboot-persistence-jdbc). Please refer to using Flyway integration in order to handle database creation. For more details head to the complete . All artifacts are available now: * Kogito runtime artifacts are available on Maven Central. * Kogito examples can be found . * Kogito images are available on . * Kogito operator is available in the in OpenShift and Kubernetes. * Kogito tooling 0.27.0 artifacts are available at the . A detailed changelog for 1.35.0 can be found in . New to Kogito? Check out our website . Click the "Get Started" button. The post appeared first on .Cristiano NicolaiHow to live reload applications on WildFlyF.Marchionihttp://www.mastertheboss.com/jbossas/jboss-deploy/how-to-live-reload-applications-on-wildfly/2023-03-17T07:38:45ZIn this article we will discuss how to use WildFly Maven plugin to automate the redeployment of applications on WildFly when you apply some changes to the application class files. What is WildFly Maven plugin WildFly Maven Plugin is a plugin for Apache Maven that provides a set of goals to manage and deploy applications ... The post appeared first on .F.MarchioniHow to easily deploy OpenShift on Azure via GitOps, Part 2Ignacio Lago, Pablo Castelob4b5b5b2-d750-44b7-b5d9-6b64a946271b2023-03-17T07:00:00Z2023-03-17T07:00:00Z<p>Deploying OpenShift in Azure utilizing OpenShift GitOps makes it not only easier but enables you to achieve faster time to market, better collaboration, more efficient workflows, and ensures access to the cloud's scalability, flexibility, and reliability.</p> <p>In this article, we are going to follow the same process from our <a href="https://developers.redhat.com/articles/2023/03/16/how-deploy-openshift-azure-gui-part-1">previous article</a> but use a GitOps approach for this.</p> <h2>Step 1: Setting up the credentials for Azure in GitOps</h2> <p>First of all, we have to fork the <a href="https://github.com/ignaciolago/acm-ocp-azure.git">repository</a>, so we can make changes to it since we are going to use the integration from the previous article. In between Red Hat Advanced Cluster Management for Kubernetes and ArgoCD to deploy the changes (ArgoCD reads a Git Repository). Now we can take a look at the repo:</p> <pre> <code class="language-bash">tree -L 2 . ├── README.md ├── bootstrap │ ├── argocd │ └── deploy └── resources ├── 01-acm-operator ├── 02-azure-credentials └── 03-azure-cluster 7 directories, 1 file</code></pre> <p>We need to edit the folders for the <strong>02-azure-credentials</strong> and <strong>03-azure-cluster.</strong></p> <p>Let us take a look at what is inside the folders. The./resources/02-azure-credentials are shown in the following snippet:</p> <pre> <code class="language-bash">tree -L 2./resources/02-azure-credentials ./resources/02-azure-credentials ├── 00-azure-credentials-namespace copy.yaml ├── 01-azure-credentials-secret.yaml └── kustomization.yaml 0 directories, 3 files</code></pre> <p>Here we need to edit the file 01-azure-credentials-secret.yaml. Let us take a look at that file and what we have to replace. In this case, the baseDomainResourceGroupName¹, PullSecret², the baseDomain³, the SSH Private<strong>⁵⁴</strong> and Public<strong>⁵</strong> Keys:</p> <pre> <code class="language-bash">cat resources/02-azure-credentials/01-azure-credentials-secret.yaml --- apiVersion: v1 kind: Secret type: Opaque metadata: annotations: argocd.argoproj.io/sync-wave: "1" name: azure-credentials namespace: azure-credentials labels: cluster.open-cluster-management.io/type: azr cluster.open-cluster-management.io/credentials: "" stringData: # 1 resource group created for the DNS to be used as base in the installation baseDomainResourceGroupName: openenv-jrh4l cloudName: AzurePublicCloud # 2 ClientId + ClientSecret + TenantId + SubscriptionId in json format osServicePrincipal.json: '{"clientId":"client_id_here","clientSecret":"client_secret_here","tenantId":"tenant_id_here","subscriptionId":"subscription_id_here"}' # 3 base DNS to be used as base in the installation baseDomain: jrh4l.azure.something.io # Your pull secret for pulling the images pullSecret: > {pull_secret_here} # Your Private Key for accessing the machines 4 ssh-privatekey: | -----BEGIN OPENSSH PRIVATE KEY----- private_key_here -----END OPENSSH PRIVATE KEY----- # Your Public Key for accessing the machines 5 ssh-publickey: > ssh-rsa public_key_here httpProxy: "" httpsProxy: "" noProxy: "" additionalTrustBundle: ""</code></pre> <h2>Step 2: Install the cluster in Azure via GitOps</h2> <p>Let us take a look at what is inside the folders. The./resources/02-azure-credentials are shown in the following snippet:</p> <pre> <code class="language-bash">tree -L 2./resources/03-azure-cluster ./resources/03-azure-cluster ├── 00-azure-cluster-namespace.yaml ├── 01-azure-managedclusterset copy.yaml ├── 02-azure-cluster.yaml └── kustomization.yaml 0 directories, 4 files</code></pre> <p>Here we need to edit the file 02-azure-cluster.yaml. Let us take a look at that file and what we have to replace. In this case, the Cluster Name, Cluster Namespace, the baseDomain, the baseDomainResourceGroupName, Base64 encoding of the pull secret, install-config.yaml in base64 encoding, ssh-private key, osServicePrincipal.json:</p> <pre> <code class="language-bash">cat resources/03-azure-cluster/02-azure-cluster.yaml --- apiVersion: v1 kind: Namespace metadata: name: cluster01 --- apiVersion: hive.openshift.io/v1 kind: ClusterDeployment metadata: # 1 Cluster name in this case is cluster01 name: 'cluster01' # 2 Cluster namespace in this case is cluster01 namespace: 'cluster01' labels: cloud: 'Azure' region: 'westeurope' vendor: OpenShift cluster.open-cluster-management.io/clusterset: 'azure-clusters' spec: # 3 base DNS to be used as base in the installation baseDomain: jrh4l.azure.something.io clusterName: 'cluster01' controlPlaneConfig: servingCertificates: {} installAttemptsLimit: 1 installed: false platform: azure: # 4 resource group created for the DNS to be used in the installation baseDomainResourceGroupName: openenv-jrh4l credentialsSecretRef: name: cluster01-azure-creds region: westeurope cloudName: AzurePublicCloud provisioning: installConfigSecretRef: name: cluster01-install-config sshPrivateKeySecretRef: name: cluster01-ssh-private-key imageSetRef: #quay.io/openshift-release-dev/ocp-release:4.10.53-x86_64 name: img4.10.53-x86-64-appsub pullSecretRef: name: cluster01-pull-secret --- apiVersion: cluster.open-cluster-management.io/v1 kind: ManagedCluster metadata: labels: cloud: Azure region: westeurope name: 'cluster01' vendor: OpenShift cluster.open-cluster-management.io/clusterset: 'azure-clusters' name: 'cluster01' spec: hubAcceptsClient: true --- apiVersion: hive.openshift.io/v1 kind: MachinePool metadata: name: cluster01-worker namespace: 'cluster01' spec: clusterDeploymentRef: name: 'cluster01' name: worker platform: azure: osDisk: diskSizeGB: 128 type: Standard_D2s_v3 zones: - "1" - "2" - "3" replicas: 3 --- apiVersion: v1 kind: Secret metadata: name: cluster01-pull-secret namespace: 'cluster01' data: # 5 Base64 encoding of the pull secret .dockerconfigjson: >- pull_secret_in_base64 type: kubernetes.io/dockerconfigjson --- apiVersion: v1 kind: Secret metadata: name: cluster01-install-config namespace: 'cluster01' type: Opaque data: # 6 Base64 encoding of install-config yaml install-config.yaml: YXBpVmVyc2lvbjogdjENCm1ldGFkYXRhOg0KICBuYW1lOiAnY2x1c3RlcjAxJw0KIyBiYXNlIEROUyB0byBiZSB1c2VkIGFzIGJhc2UgaW4gdGhlIGluc3RhbGxhdGlvbg0KYmFzZURvbWFpbjoganJoNGwuYXp1cmUuc29tZXRoaW5nLmlvDQpjb250cm9sUGxhbmU6DQogIGFyY2hpdGVjdHVyZTogYW1kNjQNCiAgaHlwZXJ0aHJlYWRpbmc6IEVuYWJsZWQNCiAgbmFtZTogbWFzdGVyDQogIHJlcGxpY2FzOiAzDQogIHBsYXRmb3JtOg0KICAgIGF6dXJlOg0KICAgICAgb3NEaXNrOg0KICAgICAgICBkaXNrU2l6ZUdCOiAxMjgNCiAgICAgIHR5cGU6ICBTdGFuZGFyZF9ENHNfdjMNCmNvbXB1dGU6DQotIGh5cGVydGhyZWFkaW5nOiBFbmFibGVkDQogIGFyY2hpdGVjdHVyZTogYW1kNjQNCiAgbmFtZTogJ3dvcmtlcicNCiAgcmVwbGljYXM6IDMNCiAgcGxhdGZvcm06DQogICAgYXp1cmU6DQogICAgICB0eXBlOiAgU3RhbmRhcmRfRDJzX3YzDQogICAgICBvc0Rpc2s6DQogICAgICAgIGRpc2tTaXplR0I6IDEyOA0KICAgICAgem9uZXM6DQogICAgICAtICIxIg0KICAgICAgLSAiMiINCiAgICAgIC0gIjMiDQpuZXR3b3JraW5nOg0KICBuZXR3b3JrVHlwZTogT1ZOS3ViZXJuZXRlcw0KICBjbHVzdGVyTmV0d29yazoNCiAgLSBjaWRyOiAxMC4xMjguMC4wLzE0DQogICAgaG9zdFByZWZpeDogMjMNCiAgbWFjaGluZU5ldHdvcms6DQogIC0gY2lkcjogMTAuMC4wLjAvMTYNCiAgc2VydmljZU5ldHdvcms6DQogIC0gMTcyLjMwLjAuMC8xNg0KcGxhdGZvcm06DQogIGF6dXJlOg0KICAgICMgcmVzb3VyY2UgZ3JvdXAgY3JlYXRlZCBmb3IgdGhlIEROUyB0byBiZSB1c2VkIGFzIGJhc2UgaW4gdGhlIGluc3RhbGxhdGlvbg0KICAgIGJhc2VEb21haW5SZXNvdXJjZUdyb3VwTmFtZTogb3BlbmVudi1qcmg0bA0KICAgIGNsb3VkTmFtZTogQXp1cmVQdWJsaWNDbG91ZA0KICAgIHJlZ2lvbjogd2VzdGV1cm9wZQ0KcHVsbFNlY3JldDogIiIgIyBza2lwLCBoaXZlIHdpbGwgaW5qZWN0IGJhc2VkIG9uIGl0J3Mgc2VjcmV0cw0Kc3NoS2V5OiB8LQ0KICAgIHNzaC1yc2ENCiAgICBwdWJsaWNfa2V5X2hlcmUNCg== --- apiVersion: v1 kind: Secret metadata: name: cluster01-ssh-private-key namespace: 'cluster01' stringData: # 7 we have to put our private ssh key in base64 here ssh-privatekey: >- private_ssh_key_in_base64 type: Opaque --- apiVersion: v1 kind: Secret type: Opaque metadata: name: cluster01-azure-creds namespace: 'cluster01' stringData: # 8 we have to put the azure credentials in base 64 here osServicePrincipal.json: >- azure_credentials_in_base64 --- apiVersion: agent.open-cluster-management.io/v1 kind: KlusterletAddonConfig metadata: name: 'cluster01' namespace: 'cluster01' spec: clusterName: 'cluster01' clusterNamespace: 'cluster01' clusterLabels: cloud: Azure vendor: OpenShift applicationManager: enabled: true policyController: enabled: true searchCollector: enabled: true certPolicyController: enabled: true iamPolicyController: enabled: true</code></pre> <p>Before deploying it, we need to change the application sets so it points to our newly forked repository. Take a look at the deploy folder in the following snippets:</p> <pre> <code>tree -L 2 bootstrap/deploy bootstrap/deploy ├── 00-applicationset-acm │ ├── 00-acm-appproject.yaml │ ├── 01-acm-appset.yaml │ └── kustomization.yaml ├── 01-applicationset-azure-credentials │ ├── 00-azure-credentials-appproject.yaml │ ├── 01-azure-credentials-appset.yaml │ └── kustomization.yaml └── 02-applicationset-azure-cluster ├── 01-azure-cluster-appset.yaml └── kustomization.yaml 3 directories, 8 files</code></pre> <pre> <code class="language-bash">cat bootstrap/deploy/01-applicationset-azure-credentials/01-azure-credentials-appset.yaml --- apiVersion: argoproj.io/v1alpha1 kind: ApplicationSet metadata: name: azure-credentials namespace: openshift-gitops spec: generators: - clusters: {} template: metadata: name: azure-credentials-{{name}} spec: project: azure syncPolicy: automated: prune: true selfHeal: true source: # we have to replace this with our forked repository repoURL: https://github.com/ignaciolago/acm-ocp-azure.git targetRevision: main path: resources/02-azure-credentials destination: server: https://kubernetes.default.svc </code></pre> <pre> <code class="language-bash">cat bootstrap/deploy/02-applicationset-azure-cluster/01-azure-cluster-appset.yaml --- apiVersion: argoproj.io/v1alpha1 kind: ApplicationSet metadata: name: azure-cluster namespace: openshift-gitops spec: generators: - clusters: {} template: metadata: name: azure-cluster-{{name}} spec: project: azure syncPolicy: automated: prune: true selfHeal: true source: # we have to replace this with our forked repository repoURL: https://github.com/ignaciolago/acm-ocp-azure.git targetRevision: main path: resources/03-azure-cluster destination: server: https://kubernetes.default.svc </code></pre> <p>Now we are ready to deploy. Run the following commands:</p> <pre> <code class="language-bash">oc apply -k bootstrap/deploy/01-applicationset-azure-credentials oc apply -k bootstrap/deploy/02-applicationset-azure-cluster</code></pre> <p>We can track the process in the web GUI or get the logs from the pod in the namespace <strong>cluster01</strong>.</p> <pre> <code class="language-bash">oc get pods -n cluster01 oc get logs pod-name -n cluster01</code></pre> <h2>Quick and easy deployment OpenShift on Azure</h2> <p>Congrats on deploying OpenShift on Azure in only a few steps! In these two articles, we have shown two easy ways to deploy OpenShift on Azure: GUI and GitOps. Comment below if you have questions. As always, we welcome your feedback.</p> The post <a href="https://developers.redhat.com/articles/2023/03/17/deploy-openshift-azure-gitops-part-2" title="How to easily deploy OpenShift on Azure via GitOps, Part 2">How to easily deploy OpenShift on Azure via GitOps, Part 2</a> appeared first on <a href="https://developers.redhat.com/blog" title="Red Hat Developer">Red Hat Developer</a>. <br /><br />Ignacio Lago, Pablo Castelo2023-03-17T07:00:00Z