Surfing through logs with less

shift g: goes to end.
shift f: tails the file.

  – ctrl+c: switch to normal mode (no tails)

?: search upwards
/: search downward
 – n: search next match in current direction
 – shift n: search next match in counter direction
Also useful to find 2 or more words in one line is the regex:
Word1.+Word2 finds both words in the same line
As an extra to review logs, it is also useful the command grep with options after and before:
grep -A: lines after match
grep -B: lines before match

Pass parameters to java main method using graddle

To pass for example a param “-a” with value “192.168.99.100:7051” to the static void main method that tha graddle task will run,  you will need to :

  • add following entry to gradle.build file, or assert that it is already there:
    run {
        if (project.hasProperty("appArgs")) {
            args = Eval.me(appArgs)
        }
    }
  • run graddle on the following form:
    gradle  run  -PappArgs="['-a',  '192.168.99.100:7051']"

Create own collectors

Sometimes it is useful to be able perform several actions extracting several actions with a stream pass. It can be achieved building our own collector. For example, suppose we need to get the maximal and minimal values of a series. So can we achieve it using collectors.

public class MaxMinCollector2 implements Collector<Integer, MaxMinContainer, MaxMinContainer>{

    public void accumulate(MaxMinContainer container, Integer val){

        if(container.max == null){
            container.max = val;
        }else if(container.max < val){
            container.max = val;
        }

        if(container.min == null){
            container.min = val;
        }else if(container.min > val){
            container.min = val;
        }

    }

    public MaxMinContainer combine(MaxMinContainer a, MaxMinContainer b){
        if(a.max == null){
            b.getMax().ifPresent(v -> a.max = v);
        }else {
            b.getMax().ifPresent(v -> a.max = a.max < v ? v : a.max);
        }

        if(a.min == null){
            b.getMin().ifPresent(v -> a.min = v);
        }else {
            b.getMax().ifPresent(v -> a.min = a.min > v ? v : a.min);
        }

        return a;
    }

    @Override
    public Supplier<MaxMinContainer> supplier() {
        return MaxMinContainer::new;
    }

    @Override
    public BiConsumer<MaxMinContainer, Integer> accumulator() {
        return this::accumulate;
    }

    @Override
    public BinaryOperator<MaxMinContainer> combiner() {
        return this::combine;
    }

    @Override
    public Function<MaxMinContainer, MaxMinContainer> finisher() {
        return (a) -> a;
    }

    @Override
    public Set<Characteristics> characteristics() {
        return new HashSet<>(Arrays.asList(Characteristics.IDENTITY_FINISH, Characteristics.UNORDERED));
    }
}

and its corresponding test:

package de.lacambra.utils.collectors;

import org.junit.Before;
import org.junit.Test;

import java.util.stream.IntStream;

import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;

public class MaxMinCollectorTest {

    MaxMinCollector cut;

    @Before
    public void setUp() throws Exception {
        cut = new MaxMinCollector();
    }

    @Test
    public void testMaxMinSerie() {

        MaxMinCollector result = IntStream.of(1, 2, 3, 4, 5, 6)
                .collect(MaxMinCollector::new, MaxMinCollector::accumulate, MaxMinCollector::combine);

        assertThat(result.getMax().get(), is(6));
        assertThat(result.getMin().get(), is(1));

        result = IntStream.of(1000, 2, 3342, 421, 523, 6)
                .collect(MaxMinCollector::new, MaxMinCollector::accumulate, MaxMinCollector::combine);

        assertThat(result.getMax().get(), is(3342));
        assertThat(result.getMin().get(), is(2));
    }

    @Test
    public void emptySerie(){
        MaxMinCollector result = IntStream.of()
                .collect(MaxMinCollector::new, MaxMinCollector::accumulate, MaxMinCollector::combine);

        assertThat(result.getMax().isPresent(), is(false));
        assertThat(result.getMin().isPresent(), is(false));
    }

    @Test
    public void oneValueSerie(){
        MaxMinCollector result = IntStream.of(34)
                .collect(MaxMinCollector::new, MaxMinCollector::accumulate, MaxMinCollector::combine);

        assertThat(result.getMax().get(), is(34));
        assertThat(result.getMin().get(), is(34));
    }
}

Create a correct 201 Created response with JAX-RS

@POST
@Path("project")
public Response createProject(@Context UriInfo uriInfo, JsonObject json) {
        Project project = projectConverter.fromJson(json);
        project.setWorkspace(getCurrentWorkspace());
        project = em.merge(project);

        URI uri = uriInfo.getBaseUriBuilder()
                .path(ProjectResource.class)
                .resolveTemplate(PathExpressions.workspaceId, getCurrentWorkspace().getId())
                .resolveTemplate(PathExpressions.projectId, project.getId())
                .build();

        return Response.created(uri).build();
The @Context UriInfo uriInfo provides information about the current URI. 
The .path(ProjectResource.class)  call will return the path used for the ProjectResource.class. 
The .resolveTemplate("{workspaceId:\\d+}", getCurrentWorkspace().getId())  will replace the workspaceId template variable for the actual wokspace id.

Once the whole path has been created, it is only needed to put it into a created response.

Collect into Jsonp JsonArray using without using foreach

Each collector has three parts:

  • A supplier: provides with instances of the accumulator.
  • An accumulator: accumulates the objects being collected. Several instances of accumulator can be used.
  • A combiner: combines all the accumulator putting all collected objects together.

For the JsonArray the combiner, accumulator  and combiener are respectively:

JsonArrayBuilder createArrayBuilder()
JsonArrayBuilder add(JsonValue value)
JsonArrayBuilder add(JsonArrayBuilder builder)

    public JsonArray getArray(Jsonable[] objects) {
        return Stream.of(objects).map(Jsonable::toJson)
                .collect(
                        Json::createArrayBuilder,
                        JsonArrayBuilder::add,
                        JsonArrayBuilder::add
                ).build();

    }

    public static class Jsonable {

        public JsonObject toJson() {
            return Json.createObjectBuilder().add("someId", LocalTime.now().toString()).build();
        }
    }