Friday, 7 April 2017

Swagger UI ReST Documentation

Where SOAP gives a clear contract between the client and service, ReST services do not.  This means that the documentation is even more important to allow correct use of the service for the client.  Swagger allows the ReST endpoints to be documented as annotations within the code so that it is easier to write and maintain.

Maven Dependencies

Add the two dependencies below to use swagger and enable the swagger ui.

    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger2</artifactId>
        <version>2.6.1</version>
    </dependency>
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger-ui</artifactId>
        <version>2.6.1</version>
    </dependency>


Spring Integration

With Spring annotation driven configuration this process is easy.  Create a class and annotate it with @Configuration so that spring uses it.  Additionally use @EnableSwagger2 to make sure that swagger is enabled.


@Configuration
@EnableSwagger2
public class SwaggerConfiguration
{
    /**
     * Add to the swagger documentation
     *
     * @return The {@link Docket} class with api information and config
     */
    @Bean
    public Docket getApiDocumentation()
    {
        return new Docket(DocumentationType.SWAGGER_2)
                .groupName("Project ReST Service")
                .apiInfo(new ApiInfoBuilder()
                        .title("My Service")
                        .description("My service which does lots of interesting things.")
                        .build())
                .select()
                .apis(RequestHandlerSelectors.any())
                .paths(PathSelectors.any())
                .build();
    }
}


With spring boot the situation isn't really any different to that above accept that the @EnableSwagger2 can be put on the same class as a the @SpringBootApplication annotation or left exactly as it is above.

Swagger Annotations

In addition to the annotation to enable swagger (@EnableSwagger2) the other main annotations to use are,

@Api - this can be used on a controller to describe the overall behaviour
@ApiOperation - put this on the methods in the controller to describe what they do
@ApiParam - used to describe the particular parameter that is passed to a controller method

A full list of annotations can be found here https://github.com/swagger-api/swagger-core/wiki/Annotations-1.5.X



Thursday, 9 March 2017

Mocking new instances with Powermock

Using Powermock it is possible to mock a new instance to avoid unnecessary depth to your unit test. This is relatively unusual in an IoC environment (inversion of control eg spring) because you'd inject the PropertyLoader and therefore mocking would be easy.  However, particularly in legacy code this can be found.

If a class has this method you many not want to traverse into the PropertyLoader.

public class MyClass {

    /**
     * Method to enrich the object with a property applicable for today.
     *
     * @param myObj The object to be enriched
     */
    public void enrichWithProperties(MyObject myObj) {
        final PropertyLoader propertyLoader = new PropertyLoader();
        myObj.setProperty(propertyLoader.getTodaysProperty());
    }
}

It could be that new PropertyLoader() has a whole series of dependencies that you don't want to end up mocking as this will make the unit test really unclear.  Instead you can use Powermock to return a mocked PropertyLoader instance to greatly simply things.



import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.powermock.api.mockito.PowerMockito.whenNew;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

/**
 * Test class for the .....
 */
@RunWith(PowerMockRunner.class)
@PrepareForTest(MyClass.class)
public class MyClassTest {

    /** The class under test. */
    private MyClass classUnderTest = new MyClass();

    @Test
    public void testEnrichWithProperties() {

        // Arrange
        final String todaysValue = "todaysValue";
        final MyObject myObj = new MyObject();
        final PropertyLoader mockedPropertyLoader = mock(PropertyLoader.class);
        whenNew(PropertyLoader.class).withAnyArguments().thenReturn(mockedPropertyLoader);
        when(mockedPropertyLoader.getTodaysProperty()).thenReturn(todaysValue);

        // Act
        classUnderTest.enrichWithProperties(myObj);

        // Assert
        assertEquals(todaysValue, myObj.getProperty());
    }

}


Note: Unlike the mocking statics, you have to PrepareForTest the class which instantiates the mocked class not the mocked class itself. So above MyClass is prepared not PropertyLoader.

Thursday, 9 February 2017

Eclipse Not Finding com.sun.tools

This is really simple and obvious but took me a while to work out.  I had a maven project which Eclipse would open but one of the maven dependencies has a child of

    <dependency>
        <groupId>com.sun</groupId>
        <artifactId>tools</artifactId>
    </dependency>

The maven plugin couldn't find this dependency and as a result wouldn't build the project, show compilation errors or build unit tests.

It turns out that a recent java installation had changed the path environment variable to put

    C:\ProgramData\Oracle\Java\javapath

at the front of the PATH variable.  The contents of this folder are shortcuts to the runtime (JRE) environment.  This means that when I was starting Eclipse it was running a jre and not a jdk.  Sorting out the PATH environment variable and moving the offending new entry to the end meant that I was using my own JAVA_PATH again which was pointing to the jdk.  Restarting Eclipse then meant that the problem was sorted.

Friday, 11 November 2016

Mocking Static Classes with Powermock

I always forget how to do this and have to look it up every time so here is a quick example for future reference!

- Annotate the class with @RunWith(PowerMockRunner.class)
- Annotate the class with @PrepareForTest(<class-to-mock>.class)
- Mock the static in @Before or in @Test PowerMockito.mockStatic(<class-to-mock>.class)
- Set expectations with when(<class-to-mock.class>.something()).thenReturn(something_else)

Example

This is a simple example which mocks StringUtils (apache commons-lang3).  This shows that the StringUtils.isBlank() method can be mocked to return different values.

    import static org.junit.Assert.assertFalse;
    import static org.junit.Assert.assertTrue;
    import static org.mockito.Mockito.when;

    import org.apache.commons.lang3.StringUtils;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.powermock.api.mockito.PowerMockito;
    import org.powermock.core.classloader.annotations.PrepareForTest;
    import org.powermock.modules.junit4.PowerMockRunner;

    /**
     * An example of using powermock to mock a static class.
     */
    @RunWith(PowerMockRunner.class)
    @PrepareForTest(StringUtils.class)
    public class ExampleTest {

        /**
         * Test blank when mocked to return that an empty string isn't blank!
         */
        @Test
        public void testBlankMocked()
        {
            // Arrange
            PowerMockito.mockStatic(StringUtils.class);
            when(StringUtils.isBlank("")).thenReturn(false);
        
            // Act
            final boolean blank = StringUtils.isBlank("");

            // Assert
            assertFalse(blank);
        }
    
        /**
         * Test blank using the standard non-mocked behaviour.
         */
        @Test
        public void testBlankNormal()
        {
            // Act
            final boolean blank = StringUtils.isBlank("");

            // Assert
            assertTrue(blank);
        }
    }


Maven Dependencies

The powermock dependencies used for this test are,

    <dependency>
        <groupId>org.powermock</groupId>
        <artifactId>powermock-module-junit4</artifactId>
        <version>1.6.5</version>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>org.powermock</groupId>
        <artifactId>powermock-api-mockito</artifactId>
        <version>1.6.5</version>
        <scope>test</scope>
    </dependency>




Friday, 29 July 2016

Angular JS Directive For Decimal Places

Here is a simple example for creating an Angular JS Directive.  In this particular case the input is limited to two decimal places but other code could be created here to limit the input in other ways.

Angular Directive

The directive is in javascript and needs to be imported into the page.

(function() {
    'use strict';

    angular.module('myApp').directive('limitedDecimalPlaces',['$filter', function ($filter) {
    return {
        require: 'ngModel',
        link: function (scope, element, attr, ngModelCtrl) {

            if (!ngModelCtrl) return;

            function round(value)
            {
                return Math.floor(value * 100) / 100;
            }

            ngModelCtrl.$parsers.push(function (value) {
            var cleanValue = value;
                if (value != value.toFixed(2))
                {
                    cleanValue = (value) ? round(value) : value;
                    ngModelCtrl.$setViewValue(cleanValue.toString());
                    ngModelCtrl.$render();
                }
                return cleanValue;
            });
        }
    };
}]);
})();

The ngModelCtrl is the model controller for this angular input.
$parsers is an array of the parsers that are applied to this input.  $parsers.push adds the function to the array (push is a standard Arrays.push() javascript function)

ngModelCtrl.$setViewValue(...) sets the value into the view part and must be a string.  Overall the function rounds the number to two decimal places if necessary and assigns it to the cleanValue.  This is then set into the view and returned so that the model is updated.  Whatever is returned from this function is what is set into the model.

Usage

The standard input can have this directive added to it so that the validation is wired into the input.

    <input type="number" name="myNumber" ng-model="myNumber" limited-decimal-places>

Tuesday, 26 July 2016

AEM Sightly Templates

When repetitive code is used within an html page, such as capturing an address, using a Sightly Template is really useful to avoid unnecessary duplication and improve maintenance.

Template

The template can be created at the top of the page as

    <template data-sly-template.address> 
        <div class="address">
            Street:  <input type="text" name="street">
            <br>
            Town: <input type="text" name="town">
            <br>
            Postcode: <input type="text" name="postcode">
        </div>
    </template>

Usage

The template usage is very straight forward.  Simply use the Sightly 'call' function,

    <div data-sly-call="${address}"></div>

Separate File

As templates get bigger or for maintainability a separate file can be used.  AEM will do the work of gathering the template files together for a given page so there is no problem about the paths in AEM being available.

To use a separate file the template must be imported in the html page and then called with the extra selector which defines the file it lives in

address.html
    <template data-sly-template.address> 
        <div class="address">
            Street:  <input type="text" name="street">
            <br>
            Town: <input type="text" name="town">
            <br>
            Postcode: <input type="text" name="postcode">
        </div>
    </template>

Import
Import the template file

    <div data-sly-use.details="address.html"></div>

Use
The usage changes very slightly as it has to reference the import ('details') as well as the template ('address') within the file.

    <div data-sly-call="${details.address}"></div>

Using Parameters

Parameters can also be used within a template.  This is useful if you want the template to behave a particular way or if you want to name the fields slightly differently for each instance of the template.


    <template data-sly-template.address="${@ instance}"> 
        <div class="address">
            Street:  <input type="text" name="${instance}Street">
            <br>
            Town: <input type="text" name="${instance}Town">
            <br>
            Postcode: <input type="text" name="${instance}Postcode">
        </div>
    </template>

Here the instance of the template is passed in so that each of the fields can have a unique name even if the template is used multiple times.  In the example below the Invoice address and Delivery address can have different instances and therefore different names for the fields.


    <div data-sly-call="${details.address @ instance='InvoiceAddress'}"></div>

    <div data-sly-call="${details.address @ instance='DeliveryAddress'}"></div>
This usage of sightly to generate templates can be very useful.

Monday, 4 July 2016

AEM QueryBuilder

Here are some examples for using the AEM QueryBuilder.  This took me a bit of time to get used to so it is worth the memory jogger!

Basic Structure

The basic structure uses the AEM adaptTo() to get a QueryBuilder object.

Here the session and builder classes are obtained.  The Query is created with the map of search values (see later).  The SearchResults object would by default be paginated so setting the query.setHitsPerPage(Integer.MAX_VALUE) means we get everything we want.  An iterator is obtained so that we can loop through the results and convert to JSON or further filter if necessary.

    final Session session = request.getResourceResolver().adaptTo(Session.class);
    final QueryBuilder builder = request.getResourceResolver().adaptTo(QueryBuilder.class);
    final Query query = builder.createQuery(PredicateGroup.create(map), session);
    query.setHitsPerPage(Integer.MAX_VALUE);
    final SearchResult result = query.getResult();

    // Iterate over the results
    final Iterator<Resource> resources = result.getResources();



Query Map

The map of values is used to create a PredicateGroup.  This is a group of Predicate objects which are used to match the JCR values against.  The names of the properties will define the predicates that are created for that value.

Create a map to hold the search values.

    final Map<String, Object> map = new HashMap<>();

The 'type' uses the TypePredicate

    map.put("type", "nt:unstructured");

The 'path' uses the PathPredicate

    map.put("path", "/content/mysite/mypages");

The 'boolproperty' defines a JcrBoolPropertyPredicate check. If the search is for 'false' then this is correct if the value is 'false' or not present at all.

    map.put("boolproperty", "live");

    map.put("boolproperty.value", "true");

A numeric range check is possible using the 'rangeproperty'.  This uses the RangePropertyPredicate. There are options for the lower and upper bounds.

    map.put("rangeproperty.property", "age");
    map.put("rangeproperty.lowerBound", age);
    map.put("rangeproperty.lowerOperation", ">=");
Note: even though this is numeric the value provided here should be a string

A number of properties can be matched against.  You can prefix with a #_ to allow multiple properties to be matched on.  These values use a JcrPropertyPredicate

    map.put("1_property", "firstname");
    map.put("1_property.value", "fred");
    map.put("2_property", "surname");
    map.put("2_property.value", "bloggs");

Debugging

Get the Iterator from the PredicateGroup and loop through to see which Predicates have been created for your map.

Always add the values into the map as strings otherwise the predicates don't match.

Use the query debugger to check your map,

    http://localhost:4502/libs/cq/search/content/querydebug.html