tag:blogger.com,1999:blog-31958851703487297532024-03-18T21:40:18.513+01:00Java mon amourAnything about Java, WebLogic, OSB, Linux etc.... this is my logbook of a navigation in the IT Technology ocean.Unknownnoreply@blogger.comBlogger2689125tag:blogger.com,1999:blog-3195885170348729753.post-38713540690522828662023-07-15T13:24:00.004+02:002023-07-15T13:24:36.136+02:00Coursera and verifying ID with PersonaIt was a total nightmare being able to verify my Id with Coursera. Coursera will not issue a certificate unless you verify your Id.
It turned out that Coursera/Persona doesn't recognize my Italian Paper Id - probably because it's not in Credic Card format.
And It doesn't recognize my Residence Permit in Switzerland.
After a LOT of attempts it accepted my Swiss Driving License.
It's totally disappointing that they don't allow you to tal to a human, all is determined by these automated procedures.
If you think that the AI-dominated world will be a Paradise, think twice, an Algorythm will decide of your life. Worst of the orwellian nightmares.Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-3195885170348729753.post-62649988846701115802023-07-15T12:59:00.001+02:002023-07-15T12:59:06.935+02:00springdoc-openapi-maven-pluginI will guide you to build a simple RESTful web service using Spring Boot, and then we will generate the OpenAPI 3.0 documentation using the springdoc-openapi-maven-plugin.
Step 1: Setup Spring Boot Project
Create a new Spring Boot project. You can use Spring Initializr (https://start.spring.io/) for easy bootstrapping of your project.
For the dependencies, select:
Web
JPA
H2 (for simplicity, we're using an in-memory database)
Springdoc OpenAPI UI
Step 2: Create the application.properties
In src/main/resources/application.properties, add the following configuration:
<pre>
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
</pre>
Step 3: Create a simple Entity
Create a Student class in your project:
<pre>
import javax.persistence.Entity;
import javax.persistence.Id;
@Entity
public class Student {
@Id
private String id;
private String name;
// getters and setters
}
</pre>
Step 4: Create a JPA Repository
Create an interface StudentRepository that extends JpaRepository:
<pre>
import org.springframework.data.jpa.repository.JpaRepository;
public interface StudentRepository extends JpaRepository<Student, String> {}
</pre>
Step 5: Create a REST Controller
Create a StudentController class:
<pre>
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/students")
public class StudentController {
private final StudentRepository repository;
public StudentController(StudentRepository repository) {
this.repository = repository;
}
@GetMapping
public List<Student> getAllStudents() {
return repository.findAll();
}
@PostMapping
public Student newStudent(@RequestBody Student newStudent) {
return repository.save(newStudent);
}
}
</pre>
Step 6: Generating OpenAPI 3.0 docs
Add the springdoc-openapi-maven-plugin to your pom.xml:
<pre>
<plugin>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-maven-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
<phase>compile</phase>
<configuration>
<apiDocsUrl>http://localhost:8080/v3/api-docs</apiDocsUrl>
<outputFileName>openapi.json</outputFileName>
<outputDir>${project.build.directory}</outputDir>
</configuration>
</execution>
</executions>
</plugin>
</pre>
This will generate an openapi.json file in your target directory whenever you compile your project.
Now when you run your application and go to http://localhost:8080/swagger-ui.html, you should see the OpenAPI UI with your API documented. You can use the UI to send requests and see the responses.
Remember to start your application before generating the documentation, because the plugin makes an actual HTTP request to the /v3/api-docs endpoint to generate the OpenAPI specification.
Please be aware that as of my knowledge cut-off in September 2021, the above mentioned plugin and setup were in use. Please ensure that you're using up-to-date versions and configurations by checking the official documentation.
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-3195885170348729753.post-24969700545783986912023-07-15T12:55:00.004+02:002023-07-15T12:55:38.630+02:00openapi-generator-maven-pluginThe openapi-generator-maven-plugin is a plugin for the Apache Maven project management tool, which is used to build and manage projects written in Java and other languages. This plugin specifically aids in the generation of API clients, server stubs, API documentation, and configuration from an OpenAPI Specification (formerly known as the Swagger Specification).
An OpenAPI Specification is a standard, language-agnostic way of describing HTTP-based APIs, allowing both humans and machines to understand the capabilities of a service without having to read the source code or access documentation.
Here is an example of how the openapi-generator-maven-plugin might be configured in your pom.xml:
<pre>
<build>
<plugins>
<plugin>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<version>4.3.1</version> <!-- use the latest version available -->
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<inputSpec>${project.basedir}/src/main/resources/api.yaml</inputSpec>
<generatorName>java</generatorName>
<configOptions>
<sourceFolder>src/gen/java/main</sourceFolder>
</configOptions>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</pre>
In the configuration above, the inputSpec tag is used to specify the location of the API specification file. The generatorName tag is used to specify the language of the generated code, in this case, Java. The configOptions tag is used to specify various options for the generated code, such as its location within the project.
After this plugin is set up and the project is built (for instance, with mvn install), the API clients, server stubs, and other generated code are produced automatically based on the API specification file. This can significantly streamline the development process when working with APIs.
Please note the plugin version in the example is hypothetical and might be outdated at the time of your query. You should always try to use the latest available version.
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-3195885170348729753.post-58385430626201773432023-07-08T17:17:00.007+02:002023-07-08T17:44:07.327+02:00AI and Deep Learning coursesSomeone deeply recommended me this Coursera course <a href="https://www.coursera.org/learn/neural-networks-deep-learning/">https://www.coursera.org/learn/neural-networks-deep-learning/</a> , for me it turned out to be quite disappointing, the lessons show lot of formulas with hardly any example, they don't communicate passion and interest, and they are totally in the wrong order in relation to the practical tests, so you have to take a test before the theory has been explained.
<br/>
The exercises are useful, but you can find them <a href="https://github.com/fanghao6666/neural-networks-and-deep-learning/blob/master/py/Logistic%20Regression%20with%20a%20Neural%20Network%20mindset%20v3.py">here</a> and you can practice in here <a href="https://jupyter.org/try">https://jupyter.org/try</a> .
<br/>
Some exercises are also available here <a href="https://github.com/Kulbear/deep-learning-coursera/blob/master/Neural%20Networks%20and%20Deep%20Learning/Week%203%20Quiz%20-%20Shallow%20Neural%20Networks.md">https://github.com/Kulbear/deep-learning-coursera/blob/master/Neural%20Networks%20and%20Deep%20Learning/Week%203%20Quiz%20-%20Shallow%20Neural%20Networks.md</a>
<br/>
Someone recommended me a textbook Deep Learning by Ian Goodfellow, inventor of generative networks. But it is very theoretical. There's a very nice course on YouTube from NYU and it's by Alfredo Canziani and Yann LeCun who's the guy who invented convolutional networks. There is a channel called Deep Lizard which has a course on PyTorch which is a framework to make neural networks.
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-3195885170348729753.post-32096755333360952232023-06-13T22:23:00.004+02:002023-06-20T17:22:06.861+02:00AI-900 exam<a href="https://youtu.be/edEfRpQSjXs">https://youtu.be/edEfRpQSjXs</a> excellent video with questions and answers (skip first 20 minutes)
<br/><br/>
<a href="https://learn.microsoft.com/en-us/certifications/exams/ai-900/">https://learn.microsoft.com/en-us/certifications/exams/ai-900/</a> official doc
<br/><br/>
<br/><br/>
This also is watchable, although lot of blablabla <a href="https://youtu.be/OwZHNH8EfSU">https://youtu.be/OwZHNH8EfSU</a>
<br/><br/>
Sample questions here <a href="https://www.kasolution.com.br/cp/AI-900-SampleQuestions.pdf">https://www.kasolution.com.br/cp/AI-900-SampleQuestions.pdf</a>
<br/><br/>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-3195885170348729753.post-57644353758191096372023-06-13T01:24:00.002+02:002023-06-13T01:26:15.448+02:00Fun with jhipsterPrecious video to get started:
<br/><br/>
<a href="https://www.youtube.com/watch?v=uQqlO3IGpTU&ab_channel=MattRaible">https://www.youtube.com/watch?v=uQqlO3IGpTU&ab_channel=MattRaible</a>
<br/><br/>
remember to set your postgres password in src/main/resources/config/application-dev.yml
<br/><br/>
Then you can start your @SpringBootApplication application, and "npm start" and http://localhost:9000 and login as admin/admin
<br/><br/>
(when running in DEV locally, it doesn't seem to be able to send emails to authenticate new users)
<br/><br/>
You can now use https://github.com/mraible/jhipster6-demo/blob/master/blog.jdl to populate the DB.
<br/><br/>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-3195885170348729753.post-89143056545552439402023-05-09T15:48:00.009+02:002023-05-09T15:49:42.149+02:00React menusSo far in React tutorials I have seen only tiny applications with a very simple menu system.
<br/>
Menus are simply hardcoded, maybe using React Router to simplify a bit the navigation.
<br/><br/>
A real life enterprise application will be MUCH more complex than that.
<br/><br/>
I have asked ChatGPT:
<br/>
"I need to build a large UI application with a complex menu system. What is the current industry standard to maintain the menu items?"
<br/><br/>
Here is the answer - which is quite decent IMHO:
<br/><br/>
<i>
There are several approaches to maintaining menu items in a large UI application with a complex menu system, and the industry standard can vary depending on the specific requirements and technologies used in the project. However, here are a few common approaches:
<br/><br/>
Data-driven menus: In this approach, the menu items are stored in a database or other data source and retrieved dynamically by the application at runtime. This allows for greater flexibility in managing the menu items, as changes can be made to the data source without having to update the application code.
<br/><br/>
Component-based menus: Another approach is to build the menu system as a set of reusable components that can be composed and reused across different parts of the application. This can make it easier to maintain the menu items, as changes can be made to the components and propagated throughout the application.
<br/><br/>
Configuration-based menus: In this approach, the menu items are defined in configuration files or other external files that can be easily modified without having to modify the application code. This can make it easier to maintain the menu items, as changes can be made without requiring a code release.
<br/><br/>
Code-based menus: Finally, some applications may choose to maintain the menu items directly in code. While this can be more difficult to maintain, it can also provide greater control and customization over the menu system.
<br/><br/>
Ultimately, the best approach will depend on the specific requirements and constraints of the project. It may be helpful to consult with experienced UI developers and architects to determine the most appropriate approach for your particular use case.
<br/>
</i>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-3195885170348729753.post-25511942176114311922023-05-06T10:14:00.003+02:002023-05-06T10:14:23.917+02:00Swagger 2.0 vs OpenAPI 3.0, conversion<a href="https://swagger.io/docs/specification/2-0/basic-structure/">https://swagger.io/docs/specification/2-0/basic-structure/</a> Swagger 2.0 specifications
<br/><br/>
<a href="https://swagger.io/docs/specification/basic-structure/">https://swagger.io/docs/specification/basic-structure/</a> OpenAPI 3.0 specifications
<br/><br/>
<a href="https://editor.swagger.io/">https://editor.swagger.io/</a> Swagger Editor, it contains a menu to translate 2.0 into 3.0, but this works by sending the yaml to a remote conversion service, so it might not work in your premises. You can also install the container with swagger-editor https://hub.docker.com/r/swaggerapi/swagger-editor/ , but make sure that external connectoins are legal in your company.
<br/><br/>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-3195885170348729753.post-77184870916447281742023-04-30T21:57:00.003+02:002023-04-30T21:57:16.396+02:00@react-oauth/google for React authentication in google<a href="https://www.npmjs.com/package/@react-oauth/google">https://www.npmjs.com/package/@react-oauth/google</a>
<br/><br/>
Sample application <a href="https://github.com/MomenSherif/react-oauth">https://github.com/MomenSherif/react-oauth</a>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-3195885170348729753.post-6597806960335012512023-04-07T17:48:00.004+02:002023-04-07T17:48:35.222+02:00Functions vs Components in React, and useStateuseState example:
<br/>
<pre>
import React, {useState} from 'react'
export default function Counter({initialCount}) {
const [count, setCount] = useState(initialCount)
return (
<div>
<button onClick = {() => setCount(prevCount => prevCount - 1)}>-</button>
<span>{count}</span>
<button onClick = {() => setCount(prevCount => prevCount + 1)}>+</button>
</div>
)
}
</pre>
<br/><br/>
same thing using Component
<br/><br/>
<pre>
import React, { Component } from 'react'
export default class Counter extends Component {
constructor(props){
super(props);
this.state = {
count: props.initialCount
}
}
render() {
return (
<div>
<button onClick={() => this.changeCount(-1)}>-</button>
<span>{this.state.count}</span>
<button onClick={() => this.changeCount(1)}>+</button>
</div>
)
}
changeCount(amount) {
this.setState(prevState => {return { count: prevState.count + amount}})
}
}
</pre>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-3195885170348729753.post-39657264011735465262023-04-07T14:39:00.002+02:002023-04-07T14:39:06.142+02:00Popular VSCode Extensions for React<a href="https://www.syncfusion.com/blogs/post/7-vs-code-extensions-for-react-developers.aspx">https://www.syncfusion.com/blogs/post/7-vs-code-extensions-for-react-developers.aspx</a>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-3195885170348729753.post-92174032923942338722023-03-31T22:52:00.005+02:002023-04-01T22:53:38.234+02:00Excellent ESLint tutorial<a href="https://www.youtube.com/watch?v=veDP5ij_i8U&list=PL_euSNU_eLbeVd_eDmWzUpEmXizWQRmEm&index=8&ab_channel=LeelaWebDev">https://www.youtube.com/watch?v=veDP5ij_i8U&list=PL_euSNU_eLbeVd_eDmWzUpEmXizWQRmEm&index=8&ab_channel=LeelaWebDev</a>
<br/>
Sure the indian accept is a bit strong, but also enjoyable to hear.
<br/><br/>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgnJ4n1KxIgPgqsc3An0JHhHbCYuJlvdUOXIEcfqaHCyP2kgcEdqM8N9vaJBUVHmGr_9mxvSIt1B0fmaCtGpLO-_EM-bE38k0Ryyfa9jUT5HcSJLzXCY6AUVcO7VR6datkadpGksW3JobYyJR5xRD_wheDFjaH7Une1ftH-2tvqvlk24td7A1gwMOcXKg/s1224/eslint001Capture.JPG" style="display: block; padding: 1em 0; text-align: center; clear: left; float: left;"><img alt="" border="0" width="400" data-original-height="502" data-original-width="1224" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgnJ4n1KxIgPgqsc3An0JHhHbCYuJlvdUOXIEcfqaHCyP2kgcEdqM8N9vaJBUVHmGr_9mxvSIt1B0fmaCtGpLO-_EM-bE38k0Ryyfa9jUT5HcSJLzXCY6AUVcO7VR6datkadpGksW3JobYyJR5xRD_wheDFjaH7Une1ftH-2tvqvlk24td7A1gwMOcXKg/s400/eslint001Capture.JPG"/></a></div>
<br/><br/>
References:
<br/><br/>
<a href="https://eslint.org/docs/latest/extend/custom-rules">https://eslint.org/docs/latest/extend/custom-rules</a> for some sample custom rules
<br/><br/>
<a href="https://astexplorer.net/">https://astexplorer.net/</a>
<br/><br/>
<br/><br/>
<a href="https://github.com/leelanarasimha/ESLint-Course">https://github.com/leelanarasimha/ESLint-Course</a> the code used in the video course
<br/><br/>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-3195885170348729753.post-5029760875145526432023-03-27T09:22:00.001+02:002023-03-27T09:22:03.105+02:00ChatGPT in ESLint (I will soon lose my job, replaced by this little bastard...)<p>Question: </p><p> </p><p>please write a ESLint rule to flag as deprecated the usage of variable names like Button.size.NORMAL <br /></p><p>
Answer:
</p><p><br />To write an ESLint rule to flag the usage of variable names like Button.size.NORMAL, you can use the following code:<br /><br />vbnet<br /><br />module.exports = {<br /> rules: {<br /> "no-deprecated-variable-name": {<br /> meta: {<br /> deprecated: true,<br /> type: "problem"<br /> },<br /> create: function(context) {<br /> return {<br /> MemberExpression(node) {<br /> const { object, property } = node;<br /> if (object.type === "Identifier" && object.name === "Button" &&<br /> property.type === "MemberExpression" && property.property.name === "NORMAL") {<br /> context.report({<br /> node: property.property,<br /> message: "The use of 'Button.size.NORMAL' is deprecated. Use a different value instead."<br /> });<br /> }<br /> }<br /> };<br /> }<br /> }<br /> }<br />};<br /><br />This rule creates a new ESLint rule called no-deprecated-variable-name, which checks for the usage of Button.size.NORMAL variables. When the rule encounters this variable, it reports a warning message to the user indicating that the usage of this variable is deprecated and suggests using a different value instead.<br /><br />To use this rule, you will need to add it to your .eslintrc configuration file:<br /><br />json<br /><br />{<br /> "rules": {<br /> "no-deprecated-variable-name": "warn"<br /> }<br />}<br /><br />In this configuration, the rule is set to "warn", which means it will produce a warning message but will not fail the build. You can set it to "error" to make it fail the build.<br /><br /><br /></p>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-3195885170348729753.post-26275272837118810512023-03-19T13:24:00.004+01:002023-03-19T13:24:33.967+01:00Reverse Proxy with Docker httpd container on Windows<p><a href="https://www.middlewareinventory.com/blog/docker-reverse-proxy-example/"> https://www.middlewareinventory.com/blog/docker-reverse-proxy-example/</a></p><p> </p><p>I have followed these instructions for Windows and it works, the only change I had to do is to start the container with the "--net=host" options, and from the container I had to configure the ReverseProxyPass to use the IP address of the host (NOT the WSL IP). <br /></p>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-3195885170348729753.post-65913445832472718072023-03-19T13:21:00.001+01:002023-03-19T13:37:58.841+01:00Reverse Proxy with Spring Boot<p><a href="https://github.com/vernetto/myreverseproxy/blob/master/src/main/java/org/pierre/myreverseproxy/CharonConfiguration.java">https://github.com/vernetto/myreverseproxy/blob/master/src/main/java/org/pierre/myreverseproxy/CharonConfiguration.java</a> </p><p> </p><p>I really like the simplicity and power of this CHARON, a Spring Boot- based Swiss knife for load balancing and request forwarding. </p><p> </p><p>Here a lot more examples <a href="https://github.com/mkopylec/charon-spring-boot-starter/blob/master/charon-spring-webmvc/src/test/java/com/github/mkopylec/charon/test/ReverseProxyConfiguration.java">https://github.com/mkopylec/charon-spring-boot-starter/blob/master/charon-spring-webmvc/src/test/java/com/github/mkopylec/charon/test/ReverseProxyConfiguration.java</a> <br /></p>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-3195885170348729753.post-56806342667644198362023-03-18T23:46:00.008+01:002023-03-19T13:21:11.186+01:00Reverse Proxy with nodejshttps://github.com/http-party/node-http-proxy
<br />
npm install http-proxy --save
<br />
node .\server.js
<br />
<br />
<pre>var http = require('http'),
httpProxy = require('http-proxy');
//
// Create your proxy server and set the target in the options.
//
httpProxy.createProxyServer({target:'http://localhost:10090'}).listen(8000);
</pre>
<br />
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-3195885170348729753.post-3442844538337772902023-03-18T16:48:00.004+01:002023-03-18T21:56:21.793+01:00Docker container connecting to host service on Windowsdocker run -d -p 80:80 --name webserver nginx
<br/>
docker ps
<pre>
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2733688156aa nginx "/docker-entrypoint.…" 14 seconds ago Up 13 seconds 0.0.0.0:80->80/tcp webserver
</pre>
<br/>
<br/>
on my windows host I have a Spring Boot application running at port 10090:
<br/>
<pre>
netstat -an | grep 10090
TCP 0.0.0.0:10090 0.0.0.0:0 LISTENING
TCP [::]:10090 [::]:0 LISTENING
TCP [::1]:53110 [::1]:10090 TIME_WAIT
TCP [::1]:53123 [::1]:10090 TIME_WAIT
TCP [::1]:53126 [::1]:10090 TIME_WAIT
</pre>
<br/>
and I can also see the nginx container
<br/>
<pre>
netstat -an | grep 80
TCP 0.0.0.0:80 0.0.0.0:0 LISTENING
TCP [::]:80 [::]:0 LISTENING
TCP [::1]:80 [::]:0 LISTENING
</pre>
<br/><br/>
If in browser you type "localhost" you should get nginx welcome page (at port 80, default)
<br/><br/>
Now log into container:
<br/>
docker exec -it webserver sh
<br/><br/>
from the container you can connect to
<br/>
curl host.docker.internal
<br/>
curl host.docker.internal:10090
<br/>
they both work, because they "resolve to the internal IP address used by the host"
<br/>
On my Windows host, if I type "ipconfig" I see that I have
<br/>
Ethernet adapter vEthernet (WSL): 172.28.176.1
<br/>
Ethernet adapter Ethernet: 192.168.0.248
<br/>
If I try:
<br/>
curl 172.28.176.1:10090
<br/>
curl 192.168.0.248:10090
<br/>
they both work on both host and container, but the first is a lot more responsive.
<br/>
This proves that from container you can access a service running on host.
<br/><br/>
References:
<br/><br/>
http://man.hubwiz.com/docset/Docker.docset/Contents/Resources/Documents/docs.docker.com/docker-for-windows/networking.html
<br/><br/>
NB: besides host.docker.internal , also docker.for.win.localhost can be used, but they have different values (which?)
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-3195885170348729753.post-25384640036608901382023-03-11T08:23:00.008+01:002023-03-11T15:37:00.810+01:00Intellij Java remote debug with SSH tunnel This is the simplest explanation how to do it:
<br />
<a href="https://arjon.es/2014/remote-debug-of-a-java-app-using-ssh-tunneling-without-opening-server-ports/">https://arjon.es/2014/remote-debug-of-a-java-app-using-ssh-tunneling-without-opening-server-ports/</a> (it is a bit confusing, as is uses localhost for both remote and local)
<br />
and
<br />
<a href="https://www.revsys.com/writings/quicktips/ssh-tunnel.html">https://www.revsys.com/writings/quicktips/ssh-tunnel.html</a> which clearly runs the ssh command locally forwarding to remote and highlights the role of -N parameter)
<br />
also worth reading:
<br />
<a href="https://www.jetbrains.com/help/idea/remote-debugging-via-ssh-tunnel.html#troubleshooting">https://www.jetbrains.com/help/idea/remote-debugging-via-ssh-tunnel.html#troubleshooting</a> this is about PHP debugging
<br /><br />
SSH tunneling explained visually <a href="https://www.youtube.com/watch?v=N8f5zv9UUMI">https://www.youtube.com/watch?v=N8f5zv9UUMI</a>
<br /><br />
this command does the trick:
<br />
ssh -f user@personal-server.com -L 9999:personal-server.com:9999 -N
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-3195885170348729753.post-1387248880655672642023-03-11T08:14:00.006+01:002023-03-11T08:14:34.971+01:00Chrome Developer Tools devtools2 interesting crash courses :
https://www.youtube.com/watch?v=gTVpBbFWry8
<br/>
https://www.youtube.com/watch?v=gTVpBbFWry8
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-3195885170348729753.post-40590892140650760192023-01-09T14:12:00.005+01:002023-01-09T14:37:27.422+01:00Spring DispatcherServlet mappings debuggingclone the project in https://spring.io/guides/gs/actuator-service/ that is https://github.com/spring-guides/gs-actuator-service.git , and start the application in complete folder
<p/>
add in application.properties:
<p/>
<pre>
management.endpoints.web.exposure.include=*
logging.level.org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping: TRACE
logging.level.org.springframework.web: DEBUG
</pre>
<p/>
( see https://stackoverflow.com/a/54636087/651288 )
<p/>
See also <a href="https://www.baeldung.com/spring-boot-logging">https://www.baeldung.com/spring-boot-logging</a> and <a href="https://www.baeldung.com/spring-boot-actuator-enable-endpoints">https://www.baeldung.com/spring-boot-actuator-enable-endpoints</a>
This is what I get:
<pre>
D:\pierre\Java\jdk-17.0.5\bin\java.exe -XX:TieredStopAtLevel=1 -Dspring.output.ansi.enabled=always -Dcom.sun.management.jmxremote -Dspring.jmx.enabled=true -Dspring.liveBeansView.mbeanDomain -Dspring.application.admin.enabled=true "-javaagent:D:\Program Files\JetBrains\IntelliJ IDEA 2022.2.3\lib\idea_rt.jar=61385:D:\Program Files\JetBrains\IntelliJ IDEA 2022.2.3\bin" -Dfile.encoding=UTF-8 -classpath D:\pierre\github\gs-actuator-service\complete\build\classes\java\main;D:\pierre\github\gs-actuator-service\complete\build\resources\main;C:\Users\pierl\.gradle\caches\modules-2\files-2.1\org.springframework.boot\spring-boot-starter-actuator\3.0.0\bc775ac676465e9da4d191d5b8378e1391fc708c\spring-boot-starter-actuator-3.0.0.jar;C:\Users\pierl\.gradle\caches\modules-2\files-2.1\org.springframework.boot\spring-boot-starter-web\3.0.0\5dd6c38f60b915dce2c4a340f4ea68f2e52306f8\spring-boot-starter-web-3.0.0.jar;C:\Users\pierl\.gradle\caches\modules-2\files-2.1\org.springframework.boot\spring-boot-starter\3.0.0\18c02ab19529d866723b40c03021cd731c3edb50\spring-boot-starter-3.0.0.jar;C:\Users\pierl\.gradle\caches\modules-2\files-2.1\org.springframework.boot\spring-boot-actuator-autoconfigure\3.0.0\4d437f988e82692b969fdec4a43002d8857e1c01\spring-boot-actuator-autoconfigure-3.0.0.jar;C:\Users\pierl\.gradle\caches\modules-2\files-2.1\io.micrometer\micrometer-core\1.10.2\ca69ca5d4d1fea81ec5f3e05bc159db4e3c87e1\micrometer-core-1.10.2.jar;C:\Users\pierl\.gradle\caches\modules-2\files-2.1\io.micrometer\micrometer-observation\1.10.2\5b63205c0e9f3acf4b84f852ea707f9f9fffda6f\micrometer-observation-1.10.2.jar;C:\Users\pierl\.gradle\caches\modules-2\files-2.1\org.springframework.boot\spring-boot-starter-json\3.0.0\beb1a175ad3cdec82ebd36dd1ddd08a9738a2d86\spring-boot-starter-json-3.0.0.jar;C:\Users\pierl\.gradle\caches\modules-2\files-2.1\org.springframework\spring-webmvc\6.0.2\cf96960288ba6a95da3488b6d255803c50fa1927\spring-webmvc-6.0.2.jar;C:\Users\pierl\.gradle\caches\modules-2\files-2.1\org.springframework\spring-web\6.0.2\39dde8bfcc9074af0fcec924ca7465cb90eb25d4\spring-web-6.0.2.jar;C:\Users\pierl\.gradle\caches\modules-2\files-2.1\org.springframework.boot\spring-boot-starter-tomcat\3.0.0\cbaf1a7a69a4a4126896bc397c14b9281634f8e7\spring-boot-starter-tomcat-3.0.0.jar;C:\Users\pierl\.gradle\caches\modules-2\files-2.1\org.springframework.boot\spring-boot-autoconfigure\3.0.0\11c57cfd7a6c6ef2cf16cc91c4d9173f6ab16dd2\spring-boot-autoconfigure-3.0.0.jar;C:\Users\pierl\.gradle\caches\modules-2\files-2.1\org.springframework.boot\spring-boot\3.0.0\dcf84aaccdb294b8fe53a92b57efecf16708eb2c\spring-boot-3.0.0.jar;C:\Users\pierl\.gradle\caches\modules-2\files-2.1\org.springframework.boot\spring-boot-starter-logging\3.0.0\af37a21b0be9c0c8cd11e3f8a3330b314af639d3\spring-boot-starter-logging-3.0.0.jar;C:\Users\pierl\.gradle\caches\modules-2\files-2.1\jakarta.annotation\jakarta.annotation-api\2.1.1\48b9bda22b091b1f48b13af03fe36db3be6e1ae3\jakarta.annotation-api-2.1.1.jar;C:\Users\pierl\.gradle\caches\modules-2\files-2.1\org.springframework\spring-core\6.0.2\43f8a6c8b522181d507705aac0e1f1b1e81e7701\spring-core-6.0.2.jar;C:\Users\pierl\.gradle\caches\modules-2\files-2.1\org.yaml\snakeyaml\1.33\2cd0a87ff7df953f810c344bdf2fe3340b954c69\snakeyaml-1.33.jar;C:\Users\pierl\.gradle\caches\modules-2\files-2.1\org.springframework.boot\spring-boot-actuator\3.0.0\647ddeb370cfc79329663b28edc32e1fbf6ca10f\spring-boot-actuator-3.0.0.jar;C:\Users\pierl\.gradle\caches\modules-2\files-2.1\io.micrometer\micrometer-commons\1.10.2\3a97e1874b8ca9c1c08f67d58bf7d567bb748601\micrometer-commons-1.10.2.jar;C:\Users\pierl\.gradle\caches\modules-2\files-2.1\com.fasterxml.jackson.datatype\jackson-datatype-jsr310\2.14.1\f24e8cb1437e05149b7a3049ebd6700f42e664b1\jackson-datatype-jsr310-2.14.1.jar;C:\Users\pierl\.gradle\caches\modules-2\files-2.1\com.fasterxml.jackson.module\jackson-module-parameter-names\2.14.1\2e05a86dba3d4b05074b6a313c4d5b7ff844c8dd\jackson-module-parameter-names-2.14.1.jar;C:\Users\pierl\.gradle\caches\modules-2\files-2.1\com.fasterxml.jackson.datatype\jackson-datatype-jdk8\2.14.1\da194197d187bf24a8699514344ebf0abd7c342a\jackson-datatype-jdk8-2.14.1.jar;C:\Users\pierl\.gradle\caches\modules-2\files-2.1\com.fasterxml.jackson.core\jackson-databind\2.14.1\268524b9056cae1211b9f1f52560ef19347f4d17\jackson-databind-2.14.1.jar;C:\Users\pierl\.gradle\caches\modules-2\files-2.1\org.springframework\spring-context\6.0.2\649dc1c9947da39a0d4e3869d61e7270489aaa25\spring-context-6.0.2.jar;C:\Users\pierl\.gradle\caches\modules-2\files-2.1\org.springframework\spring-aop\6.0.2\fe73295dd65e6b2f53986622c1e622cd3d09aa03\spring-aop-6.0.2.jar;C:\Users\pierl\.gradle\caches\modules-2\files-2.1\org.springframework\spring-beans\6.0.2\87ded7c3d973ec0bfebe0b6511375ffebe178ae5\spring-beans-6.0.2.jar;C:\Users\pierl\.gradle\caches\modules-2\files-2.1\org.springframework\spring-expression\6.0.2\89687daffb67231f6be7783775c1f0d46f4541fe\spring-expression-6.0.2.jar;C:\Users\pierl\.gradle\caches\modules-2\files-2.1\org.apache.tomcat.embed\tomcat-embed-websocket\10.1.1\c5a12c16c7ae8dc39f6dad01e486f6c76ef10343\tomcat-embed-websocket-10.1.1.jar;C:\Users\pierl\.gradle\caches\modules-2\files-2.1\org.apache.tomcat.embed\tomcat-embed-core\10.1.1\d3bbf1c2c71a79c5c472090c31e3c28efea5304e\tomcat-embed-core-10.1.1.jar;C:\Users\pierl\.gradle\caches\modules-2\files-2.1\org.apache.tomcat.embed\tomcat-embed-el\10.1.1\a5282bdc29026cacc8e2941b53c78621beed4c7\tomcat-embed-el-10.1.1.jar;C:\Users\pierl\.gradle\caches\modules-2\files-2.1\ch.qos.logback\logback-classic\1.4.5\28e7dc0b208d6c3f15beefd73976e064b4ecfa9b\logback-classic-1.4.5.jar;C:\Users\pierl\.gradle\caches\modules-2\files-2.1\org.apache.logging.log4j\log4j-to-slf4j\2.19.0\30f4812e43172ecca5041da2cb6b965cc4777c19\log4j-to-slf4j-2.19.0.jar;C:\Users\pierl\.gradle\caches\modules-2\files-2.1\org.slf4j\jul-to-slf4j\2.0.4\37418ab81680501a3a1e58e04d1341a5efe1c162\jul-to-slf4j-2.0.4.jar;C:\Users\pierl\.gradle\caches\modules-2\files-2.1\org.springframework\spring-jcl\6.0.2\5eec2672aab8f80a54ea9047938884813c9eeec8\spring-jcl-6.0.2.jar;C:\Users\pierl\.gradle\caches\modules-2\files-2.1\com.fasterxml.jackson.core\jackson-annotations\2.14.1\2a6ad504d591a7903ffdec76b5b7252819a2d162\jackson-annotations-2.14.1.jar;C:\Users\pierl\.gradle\caches\modules-2\files-2.1\com.fasterxml.jackson.core\jackson-core\2.14.1\7a07bc535ccf0b7f6929c4d0f2ab9b294ef7c4a3\jackson-core-2.14.1.jar;C:\Users\pierl\.gradle\caches\modules-2\files-2.1\ch.qos.logback\logback-core\1.4.5\e9bb2ea70f84401314da4300343b0a246c8954da\logback-core-1.4.5.jar;C:\Users\pierl\.gradle\caches\modules-2\files-2.1\org.slf4j\slf4j-api\2.0.4\30d5eb5360bd113ce96f9e49e3431993bbf1b247\slf4j-api-2.0.4.jar;C:\Users\pierl\.gradle\caches\modules-2\files-2.1\org.apache.logging.log4j\log4j-api\2.19.0\ea1b37f38c327596b216542bc636cfdc0b8036fa\log4j-api-2.19.0.jar;C:\Users\pierl\.gradle\caches\modules-2\files-2.1\org.hdrhistogram\HdrHistogram\2.1.12\6eb7552156e0d517ae80cc2247be1427c8d90452\HdrHistogram-2.1.12.jar;C:\Users\pierl\.gradle\caches\modules-2\files-2.1\org.latencyutils\LatencyUtils\2.0.3\769c0b82cb2421c8256300e907298a9410a2a3d3\LatencyUtils-2.0.3.jar com.example.actuatorservice.HelloWorldApplication
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v3.0.0)
2023-01-09T14:08:30.732+01:00 INFO 17492 --- [ main] c.e.a.HelloWorldApplication : Starting HelloWorldApplication using Java 17.0.5 with PID 17492 (D:\pierre\github\gs-actuator-service\complete\build\classes\java\main started by pierl in D:\pierre\github\gs-actuator-service)
2023-01-09T14:08:30.737+01:00 INFO 17492 --- [ main] c.e.a.HelloWorldApplication : No active profile set, falling back to 1 default profile: "default"
2023-01-09T14:08:32.077+01:00 INFO 17492 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 9000 (http)
2023-01-09T14:08:32.091+01:00 INFO 17492 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2023-01-09T14:08:32.091+01:00 INFO 17492 --- [ main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.1]
2023-01-09T14:08:32.201+01:00 INFO 17492 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2023-01-09T14:08:32.202+01:00 INFO 17492 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1402 ms
2023-01-09T14:08:32.318+01:00 DEBUG 17492 --- [ main] o.s.w.f.ServerHttpObservationFilter : Filter 'serverHttpObservationFilter' configured for use
2023-01-09T14:08:32.490+01:00 DEBUG 17492 --- [ main] s.w.s.m.m.a.RequestMappingHandlerAdapter : ControllerAdvice beans: 0 @ModelAttribute, 0 @InitBinder, 1 RequestBodyAdvice, 1 ResponseBodyAdvice
2023-01-09T14:08:32.580+01:00 TRACE 17492 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping :
c.e.a.HelloWorldController:
{GET [/hello-world]}: sayHello(String)
2023-01-09T14:08:32.583+01:00 TRACE 17492 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping :
o.s.b.a.w.s.e.BasicErrorController:
{ [/error]}: error(HttpServletRequest)
{ [/error], produces [text/html]}: errorHtml(HttpServletRequest,HttpServletResponse)
2023-01-09T14:08:32.586+01:00 DEBUG 17492 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : 3 mappings in 'requestMappingHandlerMapping'
2023-01-09T14:08:32.604+01:00 DEBUG 17492 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Patterns [/webjars/**, /**] in 'resourceHandlerMapping'
2023-01-09T14:08:32.612+01:00 DEBUG 17492 --- [ main] .m.m.a.ExceptionHandlerExceptionResolver : ControllerAdvice beans: 0 @ExceptionHandler, 1 ResponseBodyAdvice
2023-01-09T14:08:32.930+01:00 INFO 17492 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 9000 (http) with context path ''
2023-01-09T14:08:33.007+01:00 INFO 17492 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 9001 (http)
2023-01-09T14:08:33.008+01:00 INFO 17492 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2023-01-09T14:08:33.008+01:00 INFO 17492 --- [ main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.1]
2023-01-09T14:08:33.033+01:00 INFO 17492 --- [ main] o.a.c.c.C.[Tomcat-1].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2023-01-09T14:08:33.034+01:00 INFO 17492 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 100 ms
2023-01-09T14:08:33.054+01:00 INFO 17492 --- [ main] o.s.b.a.e.web.EndpointLinksResolver : Exposing 13 endpoint(s) beneath base path '/actuator'
2023-01-09T14:08:33.075+01:00 TRACE 17492 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping :
o.s.b.a.a.w.s.ManagementErrorEndpoint:
{ [/error]}: invoke(ServletWebRequest)
2023-01-09T14:08:33.075+01:00 DEBUG 17492 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : 1 mappings in 'requestMappingHandlerMapping'
2023-01-09T14:08:33.080+01:00 DEBUG 17492 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Patterns [/webjars/**, /**] in 'resourceHandlerMapping'
2023-01-09T14:08:33.084+01:00 DEBUG 17492 --- [ main] s.w.s.m.m.a.RequestMappingHandlerAdapter : ControllerAdvice beans: 0 @ModelAttribute, 0 @InitBinder, 1 RequestBodyAdvice, 1 ResponseBodyAdvice
2023-01-09T14:08:33.093+01:00 INFO 17492 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 9001 (http) with context path ''
2023-01-09T14:08:33.108+01:00 INFO 17492 --- [ main] c.e.a.HelloWorldApplication : Started HelloWorldApplication in 2.927 seconds (process running for 3.697)
</pre>
<p/>
http://localhost:9001/actuator/mappings this will give also all your endpoints. See https://docs.spring.io/spring-boot/docs/2.1.11.RELEASE/reference/html/production-ready-endpoints.html for all possoble actuators. And here https://www.baeldung.com/spring-boot-actuators for more coverage on actuators.
<p/>
When you actually hit an endpoint, like http://localhost:9001/actuator/mappings , this is what you see:
<pre>
2023-01-09T14:35:33.297+01:00 DEBUG 23248 --- [0.1-9001-exec-1] o.s.web.servlet.DispatcherServlet : GET "/actuator/mappings", parameters={}
2023-01-09T14:35:33.341+01:00 INFO 23248 --- [0.1-9001-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2023-01-09T14:35:33.342+01:00 INFO 23248 --- [0.1-9001-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2023-01-09T14:35:33.342+01:00 DEBUG 23248 --- [0.1-9001-exec-1] o.s.web.servlet.DispatcherServlet : Detected StandardServletMultipartResolver
2023-01-09T14:35:33.342+01:00 DEBUG 23248 --- [0.1-9001-exec-1] o.s.web.servlet.DispatcherServlet : Detected AcceptHeaderLocaleResolver
2023-01-09T14:35:33.342+01:00 DEBUG 23248 --- [0.1-9001-exec-1] o.s.web.servlet.DispatcherServlet : Detected FixedThemeResolver
2023-01-09T14:35:33.343+01:00 DEBUG 23248 --- [0.1-9001-exec-1] o.s.web.servlet.DispatcherServlet : Detected org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator@3f1a2baf
2023-01-09T14:35:33.343+01:00 DEBUG 23248 --- [0.1-9001-exec-1] o.s.web.servlet.DispatcherServlet : Detected org.springframework.web.servlet.support.SessionFlashMapManager@50211373
2023-01-09T14:35:33.343+01:00 DEBUG 23248 --- [0.1-9001-exec-1] o.s.web.servlet.DispatcherServlet : enableLoggingRequestDetails='false': request parameters and headers will be masked to prevent unsafe logging of potentially sensitive data
2023-01-09T14:35:33.343+01:00 INFO 23248 --- [0.1-9001-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 1 ms
2023-01-09T14:35:33.355+01:00 DEBUG 23248 --- [0.1-9001-exec-1] m.m.a.RequestResponseBodyMethodProcessor : Using 'application/vnd.spring-boot.actuator.v3+json;q=0.8', given [text/html, application/xhtml+xml, image/avif, image/webp, application/xml;q=0.9, */*;q=0.8] and supported [application/vnd.spring-boot.actuator.v3+json, application/vnd.spring-boot.actuator.v2+json, application/json]
2023-01-09T14:35:33.357+01:00 DEBUG 23248 --- [0.1-9001-exec-1] m.m.a.RequestResponseBodyMethodProcessor : Writing [org.springframework.boot.actuate.web.mappings.MappingsEndpoint$ApplicationMappingsDescriptor@69771f5 (truncated)...]
2023-01-09T14:35:33.388+01:00 DEBUG 23248 --- [0.1-9001-exec-1] o.s.web.servlet.DispatcherServlet : Completed 200 OK
</pre>
<p/>
but it's always best to check also Tomcat logs
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-3195885170348729753.post-55270976136431784022023-01-08T20:41:00.005+01:002023-01-08T20:41:59.074+01:00React Router explained<a href="https://www.youtube.com/watch?v=Ul3y1LXxzdU">https://www.youtube.com/watch?v=Ul3y1LXxzdU</a>
best tutorial ever - much better than official documentation <a href="https://reactrouter.com/en/main">https://reactrouter.com/en/main</a>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-3195885170348729753.post-80007454802028599262023-01-04T21:08:00.004+01:002023-01-04T22:55:42.822+01:00TypeScript tutorials<a href="https://ts.chibicode.com/todo/">https://ts.chibicode.com/todo/</a> this is really cool beginners tutorial
<p/><p/>
Then this one <a href="https://exploringjs.com/tackling-ts/ch_typescript-essentials.html">https://exploringjs.com/tackling-ts/ch_typescript-essentials.html</a>
Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-3195885170348729753.post-80485682389114241592022-12-26T11:29:00.008+01:002022-12-28T18:21:56.865+01:00Learning React, first experiencesI have bought myself (20 USD) the course <a href="https://www.udemy.com/course/react-tutorial-and-projects-course/">https://www.udemy.com/course/react-tutorial-and-projects-course/</a> by John Smilga.... it's loaded with exercises, but doesn't really focus enough on concepts, besides if there is something that I REALLY hate is watching someone typing code for hours in a row. Also, too many open parenthesis and a very verbose exposition. Here his github repo https://github.com/john-smilga which contains plenty of really nice examples.
</p></p>
I am reading the book "React Quickly, second Edition" and it's a decent book, at least is focuses on concepts, even if way too verbose. Here https://github.com/rq2e/rq2e.git their github repo.
</p></p>
The site react.new is quite cool, but eventually I prefer to run "npm start" locally and code with vscode
</p></p>
This guy <a href="https://blog.webdevsimplified.com/">https://blog.webdevsimplified.com/</a> is awesome, he has a youtube channel really worth exploring. He is offering also a paid video training for 60 USD, a bit steep but his explanations are crisp clear and he doesn't get too lost in bloated projects. His youtube channel here <a href="https://www.youtube.com/watch?v=kK_Wqx3RnHk">https://www.youtube.com/watch?v=kK_Wqx3RnHk</a>
</p>
The official React site offers a nice basic tutorial <a href="https://beta.reactjs.org/learn/">https://beta.reactjs.org/learn/</a>
</p>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-3195885170348729753.post-81100979063591773092022-12-03T20:29:00.002+01:002022-12-03T20:32:25.376+01:00Recommended tutorials for Gitlab Pipelines<p><a href="https://www.youtube.com/watch?v=qP8kir2GUgo">https://www.youtube.com/watch?v=qP8kir2GUgo</a> Pipelines Tutorial by NENA (quite good) </p><p><a href="https://www.youtube.com/watch?v=mnYbOrj-hLY">https://www.youtube.com/watch?v=mnYbOrj-hLY</a> Pipelines Tutorial by MOSS (really good) </p><p><a href="https://www.youtube.com/watch?v=-CyVpfDQAG0">https://www.youtube.com/watch?v=-CyVpfDQAG0</a> Gitlab Runner by MOSS </p><p><a href="https://docs.gitlab.com/ee/ci/pipelines/">https://docs.gitlab.com/ee/ci/pipelines/</a> official doc
</p>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-3195885170348729753.post-4296325354203865152022-09-30T11:48:00.003+02:002022-09-30T11:48:30.615+02:00Intellij loose search for text in filesIf you enable the "regex" option on the far right of the "find in files" dialog, you can enter things like "TODO .* master" and this will find all the lines with both TODO and master . Small trick which can really save your life.Unknownnoreply@blogger.com1