<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Fabio Peluso</title>
    <description>The latest articles on DEV Community by Fabio Peluso (@fpeluso).</description>
    <link>https://dev.to/fpeluso</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F448825%2F21be65d8-af43-4790-beb2-f063c8c5b36c.jpg</url>
      <title>DEV Community: Fabio Peluso</title>
      <link>https://dev.to/fpeluso</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/fpeluso"/>
    <language>en</language>
    <item>
      <title>Debugger Rhapsody</title>
      <dc:creator>Fabio Peluso</dc:creator>
      <pubDate>Wed, 17 Feb 2021 13:48:07 +0000</pubDate>
      <link>https://dev.to/fpeluso/debugger-rhapsody-5420</link>
      <guid>https://dev.to/fpeluso/debugger-rhapsody-5420</guid>
      <description>&lt;p&gt;Mama, just rewrote a song.&lt;br&gt;
I hope I'm not breaking any copyright. If so, please tell me and I will delete this post.&lt;/p&gt;

&lt;p&gt;Is this the real bug? Is this just regression?&lt;br&gt;
Caught in a failure, no escape from deploy&lt;br&gt;
Open your eyes, look up to the logs and see&lt;br&gt;
I'm just a poor dev, I need no sympathy&lt;br&gt;
Because I'm easy Rust, easy Go, little Spring, little Node&lt;br&gt;
Any way the build blows doesn't really matter to me, to me&lt;/p&gt;

&lt;p&gt;Mama, just spot a bug&lt;br&gt;
Put a test against this build&lt;br&gt;
Pulled my install, now it's blown&lt;br&gt;
Mama, build had just begun&lt;br&gt;
But now I've an error and thrown it all away&lt;/p&gt;

&lt;p&gt;Mama, ooh&lt;br&gt;
Didn't mean to break the feature&lt;br&gt;
If I've not deployed this time tomorrow&lt;br&gt;
Carry on, carry on as if servers really runs&lt;/p&gt;

&lt;p&gt;Too late, my built is done&lt;br&gt;
Sent shivers down my spine&lt;br&gt;
Try-catching all the time&lt;br&gt;
Goodbye, everybody, I've got to go&lt;br&gt;
Gotta leave you all behind and face the boss&lt;/p&gt;

&lt;p&gt;Mama, ooh&lt;br&gt;
I don't wanna test&lt;br&gt;
Sometimes I wish I'd never developed at all&lt;/p&gt;

</description>
      <category>fun</category>
      <category>song</category>
      <category>devops</category>
      <category>bug</category>
    </item>
    <item>
      <title>Git garbage: what if your local have a lot of old branches?</title>
      <dc:creator>Fabio Peluso</dc:creator>
      <pubDate>Tue, 24 Nov 2020 15:12:22 +0000</pubDate>
      <link>https://dev.to/fpeluso/git-garbage-what-if-you-local-have-a-lot-of-old-branches-2h0</link>
      <guid>https://dev.to/fpeluso/git-garbage-what-if-you-local-have-a-lot-of-old-branches-2h0</guid>
      <description>&lt;p&gt;In the last few days I've seen that my local git repository had a lot of old branches that are no more on remote. So I asked Google this question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;git how to remove branch locally and not remotely&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And then I come out with a solution by reading some stackoverflow stuff.&lt;/p&gt;

&lt;p&gt;First of all: you check the branches in your local repository to discover if they are &lt;strong&gt;gone&lt;/strong&gt; on the remote; you can use the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git branch &lt;span class="nt"&gt;-vv&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will give you a list of all branches on your local repository, the current commit of the branch and the corresponding remote branch if there is one and the indication &lt;em&gt;gone&lt;/em&gt; that indicates that the branch was deleted on remote.&lt;/p&gt;

&lt;p&gt;Now you may want to delete all the branches that are on your local but are no longer present on remote, but if there are to many of them you will need an automated procedure. I've find that one usefull:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git fetch &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; git branch &lt;span class="nt"&gt;-vv&lt;/span&gt; | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'/: gone]/{print $1}'&lt;/span&gt; | xargs git branch &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that my local repository was finally cleared of all the dead branches.&lt;br&gt;
And you? Have you ever faced this problem? How did you faced it?&lt;br&gt;
Leave a comment if you have!&lt;/p&gt;

</description>
      <category>git</category>
      <category>bash</category>
    </item>
    <item>
      <title>A simple WebSocket between Java and React (with hooks)</title>
      <dc:creator>Fabio Peluso</dc:creator>
      <pubDate>Thu, 19 Nov 2020 10:17:52 +0000</pubDate>
      <link>https://dev.to/fpeluso/a-simple-websocket-between-java-and-react-5c98</link>
      <guid>https://dev.to/fpeluso/a-simple-websocket-between-java-and-react-5c98</guid>
      <description>&lt;h1&gt;
  
  
  Async comunication: the phantom menace
&lt;/h1&gt;

&lt;p&gt;When you are working as a Software Engineer or developer, it's only a matter of time since you encounter a great enemy: asynchronous behaviour! You can find it in communication between client and server, or maybe it's included in the programming language or in the framework that you are using.&lt;/p&gt;

&lt;h2&gt;
  
  
  Websockets: a new hope
&lt;/h2&gt;

&lt;p&gt;During my current project we (me and my team) faced the following problem: after a certain action of the user, the application should prevent every other action and wait for an &lt;strong&gt;OK&lt;/strong&gt;/&lt;strong&gt;KO&lt;/strong&gt; from the server. It was unknown how much time can take the server to send a response, but the requirement was clear: no matter how much time, the user &lt;strong&gt;must&lt;/strong&gt; wait until the response or call the customer service if he thinks it's taking to long.&lt;br&gt;
After a small discussion we decided to try to implement a websocket to let the client wait for a message (even forever if necessary).&lt;/p&gt;
&lt;h3&gt;
  
  
  What is a Websocket?
&lt;/h3&gt;

&lt;p&gt;I don't want to bother you with informations that you can retrieve by yourself from more authoritative sources. In simple words Websocket is a protocol that allow a full-duplex communication over TCP, allowing both client and server to send/receive message from each other and to manage events based on the message received.&lt;/p&gt;

&lt;p&gt;Now, the Frontend is purely React + TypeScript, while the Backend is written in Java in an OSGi framework, so it is not possible to use &lt;em&gt;simple&lt;/em&gt; solutions like &lt;a href="https://socket.io/"&gt;socket.io&lt;/a&gt; that allows deleoper to use the same tech on both FE and BE.&lt;/p&gt;
&lt;h2&gt;
  
  
  Let's code together - Frontend
&lt;/h2&gt;

&lt;p&gt;Since I was responsible for the Frontend part, I will first describe my React code. Another requirement to keep in mind was that the Websocket is opened at the start of the application.&lt;br&gt;
So I decided to use a &lt;a href="https://reactjs.org/docs/hooks-reference.html#useref"&gt;&lt;em&gt;ref&lt;/em&gt; hook&lt;/a&gt; to manage the WebSocket Object and check if it is closed or open and a boolean &lt;code&gt;shouldKeepWSAlive&lt;/code&gt; to enable/disable a function that keep alive the connection while waiting for the response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;connection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useRef&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;WebSocket&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;shouldKeepWSAlive&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useRef&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that, we need to what is the event that start the websocket.&lt;br&gt;
Now I had this &lt;em&gt;variable&lt;/em&gt; called &lt;em&gt;isWaitingSomething&lt;/em&gt; that is responsible for blocking the application as said before so I decided to use a &lt;em&gt;useEffect&lt;/em&gt; hook to manage the opening of the Websocket (&lt;a href="https://reactjs.org/docs/hooks-effect.html"&gt;what is a useEffect?&lt;/a&gt;)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;connection&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; 
        &lt;span class="nx"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; 
        &lt;span class="nx"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;readyState&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;WebSocket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ws://path-to-websocket&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onopen&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="c1"&gt;//do something, maybe just log that the websocket is open;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="nx"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onclose&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="c1"&gt;//do something, maybe just log that the websocket is closed;&lt;/span&gt;
      &lt;span class="p"&gt;};&lt;/span&gt;
      &lt;span class="nx"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onmessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;aFunction&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;dependencies&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Just a little explanation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the if statement on the top helps me to check if connection is already open;&lt;/li&gt;
&lt;li&gt;if the connection is not open, the code block inside the if open a new connection;&lt;/li&gt;
&lt;li&gt;onopen and onclose are default events that are triggered when the connection is started and closed;&lt;/li&gt;
&lt;li&gt;onmessage is the important part: it is the event that is triggered when a message is received on the frontend;&lt;/li&gt;
&lt;li&gt;aFunction() is my custom function that do the logic that I want;&lt;/li&gt;
&lt;li&gt;with the correct dependencies the Websocket is opened when the application start;&lt;/li&gt;
&lt;li&gt;since even the Websocket do timeout, you may need to reopen it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, if the server takes to much time to send a message, while waiting the Websocket can timeout and close, so I've added a simple &lt;code&gt;keepAlive()&lt;/code&gt; function in this way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;keepAlive&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useCallback&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;shouldKeepWSAlive&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; 
          &lt;span class="nx"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
          &lt;span class="nx"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;readyState&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="nx"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;keepAlive&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;20000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;

  &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isWaitingVendi&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;shouldKeepWSAlive&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nx"&gt;keepAlive&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;shouldKeepWSAlive&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;isWaitingVendi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;keepAlive&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that my Websockt was working and performing well.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's code together - Backend
&lt;/h2&gt;

&lt;p&gt;In this section I will briefly describe the Java part of the Websocket.&lt;br&gt;
The BE was managed by another team member, so I will not insert detailed explanations, but I've asked him to write a dedicated post.&lt;/p&gt;

&lt;p&gt;We are developing in &lt;strong&gt;OSGi framework&lt;/strong&gt; and we use &lt;strong&gt;Jetty&lt;/strong&gt;. The list of required imports is quite long (I have hidden some...):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.google.gson.Gson&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;it.hiddenstuff.common.topic.TopicConstants&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.eclipse.jetty.websocket.api.RemoteEndpoint&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.eclipse.jetty.websocket.api.Session&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.eclipse.jetty.websocket.api.annotations.WebSocket&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.osgi.framework.BundleContext&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.osgi.framework.FrameworkUtil&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.osgi.service.event.Event&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.osgi.service.event.EventAdmin&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.osgi.service.event.EventConstants&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.osgi.service.event.EventHandler&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.slf4j.Logger&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.slf4j.LoggerFactory&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.Hashtable&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and here you have the declaration of the Class with correct annotations and the constructor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@WebSocket&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SellWebSocket&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;EventHandler&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;SellWebSocket&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;BundleContext&lt;/span&gt; &lt;span class="n"&gt;bundleContext&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FrameworkUtil&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
            &lt;span class="nf"&gt;getBundle&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;SellWebSocket&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;getBundleContext&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="nc"&gt;Hashtable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;stringStringHashMap&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Hashtable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;
        &lt;span class="n"&gt;stringStringHashMap&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
            &lt;span class="nf"&gt;put&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="nc"&gt;EventConstants&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;EVENT_TOPIC&lt;/span&gt; &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;TopicConstants&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;TOPIC_END_SELL&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;bundleContext&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
            &lt;span class="nf"&gt;registerService&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;EventHandler&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt; &lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="o"&gt;,&lt;/span&gt;  &lt;span class="n"&gt;stringStringHashMap&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then you need to add some declarations to manage the session, the logs and the endpoints:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;Session&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;RemoteEndpoint&lt;/span&gt; &lt;span class="n"&gt;remote&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;Logger&lt;/span&gt; &lt;span class="n"&gt;log&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;LoggerFactory&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getLogger&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;getClass&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Session&lt;/span&gt; &lt;span class="nf"&gt;getSession&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setSession&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Session&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;RemoteEndpoint&lt;/span&gt; &lt;span class="nf"&gt;getRemote&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;remote&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As for the Frontend, you need to &lt;em&gt;listen&lt;/em&gt; to the events (&lt;em&gt;open&lt;/em&gt;, &lt;em&gt;close&lt;/em&gt;, &lt;em&gt;send&lt;/em&gt;, &lt;em&gt;receive&lt;/em&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;    &lt;span class="nd"&gt;@OnWebSocketConnect&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;onConnect&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Session&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;setSession&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;remote&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getRemote&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@OnWebSocketClose&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;onClose&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;statusCode&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;reason&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@OnWebSocketMessage&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;onText&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;debug&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"null session"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="c1"&gt;// no connection, do nothing.&lt;/span&gt;
            &lt;span class="c1"&gt;// this is possible due to async behavior&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="c1"&gt;//do something&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="cm"&gt;/**
     * Called by the {@link EventAdmin} service to notify the listener of an
     * event.
     *
     * @param event The event that occurred.
     */&lt;/span&gt;
    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;handleEvent&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Event&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;//do what you need to do&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;Before that, I was not quite familiar with all this stuff, and googleing made me a little crazy since it was hard to find a solution with all the right characteristics: sometimes you find &lt;em&gt;socket.io&lt;/em&gt;, sometimes you find old React classes while you need Hooks, and some problems like that.&lt;br&gt;
Anyway I managed to pack all together coming out with this solution. Since I don't pretend to be an expert, feel free to comment and add usefull suggestions.&lt;br&gt;
If instead you think this article is usefull, I'd very happy to know 😀&lt;/p&gt;

</description>
      <category>java</category>
      <category>react</category>
      <category>websocket</category>
      <category>hooks</category>
    </item>
    <item>
      <title>How to clone a GitLab repository after enabling 2FA</title>
      <dc:creator>Fabio Peluso</dc:creator>
      <pubDate>Wed, 23 Sep 2020 12:25:55 +0000</pubDate>
      <link>https://dev.to/fpeluso/how-to-clone-a-gitlab-repository-after-enabling-2fa-6oc</link>
      <guid>https://dev.to/fpeluso/how-to-clone-a-gitlab-repository-after-enabling-2fa-6oc</guid>
      <description>&lt;p&gt;I've recently started to enable &lt;strong&gt;2FA&lt;/strong&gt; (Two Factor Authentication) on most of my online accounts, including &lt;a href="https://www.gitlab.com"&gt;&lt;strong&gt;GitLab&lt;/strong&gt;&lt;/a&gt;. But what happen when you try to &lt;em&gt;clone&lt;/em&gt; a repository against https after that?&lt;/p&gt;

&lt;p&gt;When I tried the first time I run the usual git clone:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; git clone https://gitlab.com/username/project.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;but it didn't work, giving me this output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Cloning into 'mypersonalbalance'...
remote: HTTP Basic: Access denied
remote: You must use a personal access token with 'read_repository' or 'write_repository' scope for Git over HTTP.
remote: You can generate one at https://gitlab.com/profile/personal_access_tokens
fatal: Authentication failed for 'https://gitlab.com/f.peluso/mypersonalbalance.git/'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I googled a little bit, finding that the problems was the 2 factor authentication, and then I found the following solution:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Log in into the GitLab account;&lt;/li&gt;
&lt;li&gt;Go to the Settings section (at the moment, top right, hover the profile image and wait for the menu);&lt;/li&gt;
&lt;li&gt;Go to &lt;code&gt;Access Tokens&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;Now here you can create a temporary token; if you need to pull/push you must enable &lt;em&gt;read_repository&lt;/em&gt; and &lt;em&gt;write_repository&lt;/em&gt; flags.&lt;/li&gt;
&lt;li&gt;A token is shown in the page. Don't close or refresh the page, or you won't be able to retrieve the same token again!!!&lt;/li&gt;
&lt;li&gt;Save the token somewhere safe if you need to use it more than once (I needed only once, so I just copypasted it, and then deleted it).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;After these steps you can clone the repository using&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone https://oauth2:PERSONAL_ACCESS_TOKEN@gitlab.com/username/project.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;where &lt;code&gt;PERSONAL_ACCESS_TOKEN&lt;/code&gt; is the token you retrieved before.&lt;/p&gt;

&lt;p&gt;GitLab explains that the tokens act like passwords after one enables the 2FA, so, in order to improve your security, you can manage one of more tokens to work with different repositories, devices and applications.&lt;/p&gt;

</description>
      <category>git</category>
      <category>gitlab</category>
      <category>2fa</category>
    </item>
  </channel>
</rss>
