Dienstag, 19. März 2019

How To Resolve GIT Merge Conflicts with IntelliJ

Resolve a Merge Conflict in GIT with IntelliJ


Let us assume you are using Bitbucket or a similar tool to administrate and host your GIT repositories.
You are using the Open Source principle with Pull Request, Review, Merge: 
  • Push changes
  • Assign a reviewer or two
  • Depending on your team agreement, either you or the reviewer will merge the feature onto your main develop branch (I will call it "develop"). The pull request is merged.

In some cases there will be incompatible changes which happened on the develop branch when you are about to merge.
The pull request cannot be merged due to merge conflicts with your develop branch.

1) Checkout the current develop branch from remote locally.
2) Checkout the feature branch locally
3) When you have switched to your feature branch, use this command:
$git merge develop
4) The merge conflicts are now shown.
5) Use IntelliiJ Merge Tool to resolve the merge conflicts: https://www.jetbrains.com/help/idea/resolving-conflicts.html
Note: there is also the standard GIT merge-tool which will work as a stand-alone without an IDE.
6) Push everything to your remote feature branch
7) Merge the pull request via Bitbucket or other tool.

Freitag, 23. November 2018

GIT - Replace local branch with remote branch.


  • Delete the local branch:
  git branch -d local_branch
  • Fetch remote branch: 
 git fetch origin remote_branch
  • Rebuild the local branch with remote content: 
 git checkout -b local_branch origin/remote_branch


Donnerstag, 30. August 2018

GIT Troubleshooting - revert and pull not possible?

Sometimes a file does not differ from the repository version. But GIT shows it as modified and does not accept a revert.

This file, however should not be commited, because it has not changed, but is simply not properly managed by GIT.

This is related to GIT working in file mode.

Try this and then pull again:

$git config core.fileMode false

Dienstag, 21. August 2018

Squash GIT commits

//checkout from a remote branch to a local branch A
$ git branch
...
branch A (highlited)
...
$ git checkout -b B
...
branch B (highlited)
...
  
//do multiple commits to preserve the steps and protect everything with version control
$ git commit -am "[BPA-...] ..."
$ git commit -am "[BPA-...] interim, not compiling"
$ git commit -am "[BPA-...] reverting the change and doing something other"
... 
//done? then checkout to local branch A again and merge, squash the commits
  
$ git checkout A
$ git merge --squash B
// all commits are gathered into one.
  
//finally, push to the remote. One commit, nice and clean
$ git push origin/A A

Donnerstag, 19. Juli 2018

A nice true story about making a difference - Revisiting Michael

Dear reader,

This post is not about technology or frameworks. It is rather focused on the most important thing we have: the people who surround us and how we influence them and how they influence us.

About ten years ago I worked as a Teamleader for a large software company in Germany.
We were hiring developers, but the interviews were quite frustrating. We did simply not find the person we were looking for. Because what we needed at this time was a Can-Do attitude. This was of vital importance, because we had deadlines approaching and were lacking the possibility to change them or release some pressure which was inflicted upon the team. So we needed someone who was positive, eager to learn and willing to go the extra mile.

Michael was someone whom I knew from University. He was unsure about his direction in life but at the same time I saw a lot of potential in him. So I asked him to come by and do a job interview with me. I wanted to hire him and so I did. He was unsure if he would be able to cope with the challenges which were waiting for him but much to my enjoyment, he agreed to work with us.

During the first project we did for a large logistics company in Germany (market leader), he approached me by saying that he would not be able to make it. I knew that the whole situation was challenging for him - even demanding. But I insisted on my view: I told him that I saw great potential and that for him, it was rather about self-confidence but about technical skillsets. He stayed with us. Project was a success. We met the deadline.

Today, a colleage of mine approached me and asked me if I knew this guy (he was talking about Michael). I said yes. The colleague, Frank, said that Michael would send me warm-hearted greetings. He is working with him at the same consulting company (Top 5 in Germany) and he is really good at his job. Considering that I pursued Michael to stay and overcome all obstacles, to become a great software developer (which he is by now), I feel very good. I really wanted to share this story with you because this is how we make a difference.

By encouraging and coaching a person, we can help this person to change her or his mindset from "I am afraid" to "I can do it". we can help to build up self-confidence.
So this person will eventually be able to pursue higher goals and become what he or she wants to be.

And how good is that? ;)

Best,
Tim

Dienstag, 15. Mai 2018

Java: How to do SSL, Basic Authentication and log Request Response in XML/JSON with Jersey JAX WS RS Client

//Example with XML, SSL, Basic Auth


import java.io.InputStream;
import java.security.KeyStore;
import java.security.NoSuchAlgorithmException;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.ClientResponseFilter;
import javax.ws.rs.client.WebTarget;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.glassfish.jersey.client.ClientConfig;
import org.glassfish.jersey.client.ClientProperties;

import com.mycompany.exception.MyException;

/**
 *         Purpose of this class is to use jersey/jaxb related connection to an external API via REST WS.
 */
public class RestClient {

    private static final Logger LOG = LogManager.getLogger(RestClient.class);


    private int connectTimeout = 30000;
    private int readTimeout = 30000;
   
private String uri;   
    protected WebTarget service;
    protected MyConfiguration config;
    private Client client;

     public void initialize() throws MyException {
        if (uri == null || uri.trim().isEmpty()) {
            uri = "https://myapi";
        }

        if (!(uri != null && !uri.trim().isEmpty())) {
            throw new MyException("[x] uri wrong: " + uri);
        }

        ClientBuilder builder = ClientBuilder.newBuilder();
        String proxy = "172.00.00.00:1234";
        if (proxy != null) {
            ClientConfig clientConfig = new ClientConfig();
            clientConfig.property(ClientProperties.PROXY_URI, proxy);
            builder = builder.withConfig(clientConfig);
        }
        builder = builder.sslContext(initializeHttpClientWithKeyStoreAndCert());

        client = builder.build();
        client.property(ClientProperties.CONNECT_TIMEOUT, connectTimeout);
        client.property(ClientProperties.READ_TIMEOUT, readTimeout);

        client.register((ClientResponseFilter) (requestContext, responseContext) -> responseContext.getHeaders()
                .putSingle("Content-Type", "application/xml"));

        client.register(new EntityLoggingFilter());

        service = client.target(uri);
        LOG.debug("RestClient initialized.");
    }

    private TrustManager[] getTrustManager() throws Exception {
        try (InputStream inputStream = getClass().getClassLoader().getResourceAsStream("com/mycompany/my_keystore.jks")) {
            KeyStore keyStore = KeyStore.getInstance("JKS");
            keyStore.load(inputStream, "somepassword".toCharArray());
            TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("PKIX");
            trustManagerFactory.init(keyStore);
            TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
            return trustManagers;
        }
    }

    private SSLContext initializeHttpClientWithKeyStoreAndCert() throws MyException {
        try {

            SSLContext sslContext = SSLContext.getInstance("SSL");
            try {
                sslContext.init(null, getTrustManager(), null);
            } catch (Exception e) {
                throw new MyException("[x] Failed to create SSL Context. ", e);
            }

            return sslContext;

        } catch (NoSuchAlgorithmException e) {
            LOG.error(e);
            throw new MyException(e.getClass().getSimpleName() + " while Creating HttpClient: " + e.getMessage(), e);
        }
    }

}



==============  POST a request POJO =====================

    public MyResponsePOJO postRequest(MyRequestPojo myrequestPojo) {
       

        // credentials shown for teaching purpose. Usually they are stored in a properties file or config.
        String basicAuthUser = "someUser";
        String basicAuthPass = "somePassword";
        String base64Creds = Base64.getEncoder()

                                                        .encodeToString((basicAuthUser + ":" + basicAuthPass).getBytes("UTF-8"));

        Response response = service.path("mypath").request().accept("application/xml")

                                                     .header("Content-type", "application/xml")
                                                     .header("Authorization", "Basic " + base64Creds).post(Entity.xml(myRequestPojo));

       return response.readEntity(MyResponsePOJO.class);
      
    }



============== LOG response and request bodies in XML or JSON with the RequestResponseLoggingFilter =======

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.logging.Logger;

import javax.annotation.Priority;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.client.ClientRequestContext;
import javax.ws.rs.client.ClientRequestFilter;
import javax.ws.rs.client.ClientResponseContext;
import javax.ws.rs.client.ClientResponseFilter;
import javax.ws.rs.ext.Provider;
import javax.ws.rs.ext.WriterInterceptor;
import javax.ws.rs.ext.WriterInterceptorContext;

/**
 * @author tim 

 * 
 * Purpose is to log request and response payload as XML.
 */

@Provider
@Priority(Integer.MIN_VALUE)
public class RequestResponseLoggingFilter implements ClientRequestFilter, ClientResponseFilter, WriterInterceptor {

    private static final Logger LOG = Logger.getLogger(RequestResponseLoggingFilter.class.getName());

    private final int maximumSizeForEntity = 1024 * 8;

    private class StreamLogger extends FilterOutputStream {

        private final StringBuilder builder = new StringBuilder();
        private final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

        StreamLogger(OutputStream outputStream) {
            super(outputStream);
        }

        public StringBuilder writeEntity(Charset charset) {
            final byte[] pojo = byteArrayOutputStream.toByteArray();
            builder.append(new String(pojo, 0, pojo.length, charset));
            if (pojo.length > maximumSizeForEntity) {
                builder.append("...more...");
            }
            builder.append('\n');
            return builder;
        }

        @Override
        public void write(final int i) throws IOException {
            if (byteArrayOutputStream.size() <= maximumSizeForEntity) {
                byteArrayOutputStream.write(i);
            }
            out.write(i);
        }
    }

    @Override
    public void filter(ClientRequestContext requestContext) throws IOException {
        if (requestContext.hasEntity()) {
            final OutputStream stream = new StreamLogger(requestContext.getEntityStream());
            requestContext.setEntityStream(stream);
            requestContext.setProperty("EntityLoggingFilter.entityStream", stream);
        } else {
            // nop
        }
    }

    @Override
    public void filter(ClientRequestContext requestCtx, ClientResponseContext responseCtx) throws IOException {
        final StringBuilder stringBuilder = new StringBuilder();
        if (responseCtx.hasEntity()) {
            responseCtx.setEntityStream(logIncoming(stringBuilder, responseCtx.getEntityStream(), StandardCharsets.UTF_8));
            LOG.info(stringBuilder.toString());
        }

    }

    @Override
    public void aroundWriteTo(WriterInterceptorContext ctx) throws IOException, WebApplicationException {
        final StreamLogger stream = (StreamLogger) ctx.getProperty("EntityLoggingFilter.entityStream");
        ctx.proceed();
        if (stream != null) {
            LOG.info(stream.writeEntity(StandardCharsets.UTF_8).toString());
        } else {
            // nop
        }
    }

    private InputStream logIncoming(final StringBuilder b, InputStream stream, final Charset charset) throws IOException {
        if (!stream.markSupported()) {
            stream = new BufferedInputStream(stream);
        }
        stream.mark(maximumSizeForEntity + 1);
        final byte[] pojo = new byte[maximumSizeForEntity + 1];
        final int entitySize = stream.read(pojo);
        b.append(new String(pojo, 0, Math.min(entitySize, maximumSizeForEntity), charset));
        if (entitySize > maximumSizeForEntity) {
            b.append("...more...");
        } else {
            // nop
        }
        b.append('\n');
        stream.reset();
        return stream;
    }
}


================ DEPENDENCIES ================================

org="org.apache.logging.log4j" name="log4j" version = 2.5
org="org.glassfish.jersey" name="jersey" version =2.25.1
org="org.eclipse.persistence" name="eclipse-persistence" version = 2.6.0


<!-- required for Eclipse moxy, jaxb alternative) -->
org="javax.validation" name="validation-api" version = 1.1.0.Final





Freitag, 4. Mai 2018

Java UNIT Test Exception Handling with @Rule

A nice way to get rid of manual Exception handling in JUnit Tests is this:

 @Rule
 public ExpectedException thrownException = ExpectedException.none();


 @Test
 public void testSomething() {


      // given
        thrownException.expect(MyExpectedException.class);
        thrownException.expectMessage("my expected msg");
        thrownException.reportMissingExceptionWithMessage("my custom msg");
 

      /*  possibly doing setup of mocks which throw the Exception... */

      // when / then
      testee.doSomething(); // throws the Exception...
 }

Donnerstag, 3. Mai 2018

Java Logging Log4j vs. SLF4J

Very good article which I recently found:
https://blog.frankel.ch/thoughts-on-java-logging-and-slf4j/https://blog.frankel.ch/thoughts-on-java-logging-and-slf4j/

Java Optional Example

Some people say that Optionals should only be used for API designs.

I think there is more to it and we can modernize our code. In this example we get rid of this:

if(myParam == null || myParam.toCharArray().length == 0){
   myList.add(myParam);
}

In favor of that:

Optional.ofNullable(myParam).ifPresent(myList::add);
//.of(myParam) would have thrown a Nullpointer if not present...

And for Exceptions, we get rid of this:

if (token == null) {
    throw new MyException("message");

}

In favor of that:


Optional.ofNullable(token).orElseThrow(() -> new MyException("message"));


Donnerstag, 19. April 2018

Remove ns2 in default namespace - JAXB, Entity XML Mapping

Just create a package-info.java file for your package in which you have your POJO:

@javax.xml.bind.annotation.XmlSchema(namespace = "http://myNameSpace", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package my.package;


The ns2 will be gone when you perform the usual Entity.xml(...)

Mittwoch, 18. April 2018

Generate JAXB Java Classes from XSD File

This is a fine one: if you only do have XML and nothing else, you can generate an XSD from the XML (here) and use the XSD to generate your Java POJOS.

I am currently forced to use windows, so I will use this example.

Download jaxb-ri-2.3.0 (Version may differ for you, what ever is the newest version).
Open CMD window and change to the directory  jaxb-ri-2.3.0\jaxb-ri\bin
Copy your XSD into the folder and type:
xjc.bat <yourfile.xsd> -d <yourDirectory>

And your POJOs will be generated, ready to use.

How To Resolve GIT Merge Conflicts with IntelliJ

Resolve a Merge Conflict in GIT with IntelliJ Let us assume you are using Bitbucket or a similar tool to administrate and host your GI...