Java tutorial
/** * Copyright 2015 Smart Society Services B.V. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 */ package com.alliander.osgp.acceptancetests.devicemanagement; import static org.mockito.Matchers.any; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.net.InetAddress; import java.util.ArrayList; import java.util.List; import org.givwenzen.annotations.DomainStep; import org.givwenzen.annotations.DomainSteps; import org.mockito.ArgumentCaptor; import org.mockito.Captor; import org.mockito.Matchers; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Configurable; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.data.jpa.domain.Specifications; import com.alliander.osgp.adapter.ws.core.application.mapping.DeviceManagementMapper; import com.alliander.osgp.adapter.ws.core.application.services.DeviceManagementService; import com.alliander.osgp.adapter.ws.core.endpoints.DeviceManagementEndpoint; import com.alliander.osgp.adapter.ws.infra.specifications.JpaEventSpecifications; import com.alliander.osgp.adapter.ws.schema.core.devicemanagement.FindEventsRequest; import com.alliander.osgp.adapter.ws.schema.core.devicemanagement.FindEventsResponse; import com.alliander.osgp.domain.core.entities.Device; import com.alliander.osgp.domain.core.entities.DeviceAuthorization; import com.alliander.osgp.domain.core.entities.DeviceAuthorizationBuilder; import com.alliander.osgp.domain.core.entities.DeviceBuilder; import com.alliander.osgp.domain.core.entities.Event; import com.alliander.osgp.domain.core.entities.EventBuilder; import com.alliander.osgp.domain.core.entities.Organisation; import com.alliander.osgp.domain.core.entities.Ssld; import com.alliander.osgp.domain.core.exceptions.ArgumentNullOrEmptyException; import com.alliander.osgp.domain.core.repositories.DeviceAuthorizationRepository; import com.alliander.osgp.domain.core.repositories.DeviceFunctionMappingRepository; import com.alliander.osgp.domain.core.repositories.DeviceRepository; import com.alliander.osgp.domain.core.repositories.EventRepository; import com.alliander.osgp.domain.core.repositories.OrganisationRepository; import com.alliander.osgp.domain.core.repositories.SsldRepository; import com.alliander.osgp.domain.core.specifications.EventSpecifications; import com.alliander.osgp.domain.core.valueobjects.DeviceFunction; import com.alliander.osgp.domain.core.valueobjects.DeviceFunctionGroup; import com.alliander.osgp.domain.core.valueobjects.EventType; import com.alliander.osgp.domain.core.valueobjects.PlatformFunctionGroup; @DomainSteps @Configurable public class RetrieveReceivedEventNotificationsSteps { private static final Logger LOGGER = LoggerFactory.getLogger(RetrieveReceivedEventNotificationsSteps.class); private static final String ORGANISATION_PREFIX = "ORG"; private static final int PAGESIZELIMIT = 300; private static final Integer DEFAULT_PAGE = 1; private static final Integer DEFAULT_PAGESIZE = 50; // Domain fields private DeviceManagementEndpoint deviceManagementEndpoint; @Autowired @Qualifier("wsCoreDeviceManagementService") private DeviceManagementService deviceManagementService; @Autowired @Qualifier("coreDeviceManagementMapper") private DeviceManagementMapper deviceManagementMapper; private Organisation organisation; private Ssld device; private final EventSpecifications eventSpecifications = new JpaEventSpecifications(); @SuppressWarnings("unused") private Specifications<Event> specifications; private Event event; private Pageable pageRequest; private Page<Event> eventsPage; private FindEventsRequest request; private FindEventsResponse response; @Captor private ArgumentCaptor<Specifications<Event>> actualSpecifications; @Captor private ArgumentCaptor<Pageable> actualPageRequest; // Repository Mocks @Autowired private OrganisationRepository organisationRepositoryMock; @Autowired private EventRepository eventRepositoryMock; @Autowired private DeviceRepository deviceRepositoryMock; @Autowired private SsldRepository ssldRepositoryMock; @Autowired private DeviceAuthorizationRepository deviceAuthorizationRepositoryMock; @Autowired private DeviceFunctionMappingRepository deviceFunctionMappingRepositoryMock; // === SET UP === private void setUp() { // init mocks to set ArgumentCaptors MockitoAnnotations.initMocks(this); // reset the mocks Mockito.reset( new Object[] { this.deviceRepositoryMock, this.ssldRepositoryMock, this.organisationRepositoryMock, this.eventRepositoryMock, this.deviceAuthorizationRepositoryMock }); this.deviceManagementEndpoint = new DeviceManagementEndpoint(this.deviceManagementService, this.deviceManagementMapper); this.request = null; this.response = null; } // === GIVEN === @DomainStep("an OSGP client (.*)") public void givenAnOsgpClientOrganisation(final String organisation) { LOGGER.info("GIVEN: an OSGP client {}", organisation); this.setUp(); // Create the organisation this.organisation = new Organisation(organisation, organisation, ORGANISATION_PREFIX, PlatformFunctionGroup.USER); when(this.organisationRepositoryMock.findByOrganisationIdentification(organisation)) .thenReturn(this.organisation); } @DomainStep("an authorized device (.*)") public void givenAnAuthorizedDevice(final String deviceIdentification) { LOGGER.info("GIVEN: an authorized device: {}", deviceIdentification); // Create the device this.device = (Ssld) new DeviceBuilder().withDeviceIdentification(deviceIdentification) .withNetworkAddress(InetAddress.getLoopbackAddress()).isActivated(true).build(); when(this.deviceRepositoryMock.findByDeviceIdentification(deviceIdentification)).thenReturn(this.device); when(this.ssldRepositoryMock.findByDeviceIdentification(deviceIdentification)).thenReturn(this.device); when(this.ssldRepositoryMock.findOne(1L)).thenReturn(this.device); final List<DeviceAuthorization> authorizations = new ArrayList<>(); authorizations.add(new DeviceAuthorization(this.device, this.organisation, DeviceFunctionGroup.MANAGEMENT)); when(this.deviceAuthorizationRepositoryMock.findByOrganisationAndDevice(this.organisation, this.device)) .thenReturn(authorizations); final List<DeviceFunction> deviceFunctions = new ArrayList<>(); deviceFunctions.add(DeviceFunction.GET_EVENT_NOTIFICATIONS); when(this.deviceFunctionMappingRepositoryMock.findByDeviceFunctionGroups(any(ArrayList.class))) .thenReturn(deviceFunctions); } @DomainStep("a received event notification (.*), (.*) and (.*) from (.*)") public void givenAReceivedEventNotificationFrom(final String event, final String description, final String index, final String device) { LOGGER.info("GIVEN: a received event notification {}, {} and {} from (.*)", new Object[] { event, description, index, device }); this.event = new Event(this.device, EventType.valueOf(event), description, Integer.parseInt(index)); final List<Event> eventList = new ArrayList<Event>(); eventList.add(this.event); this.pageRequest = new PageRequest(DEFAULT_PAGE, DEFAULT_PAGESIZE, Sort.Direction.DESC, "creationTime"); this.eventsPage = new PageImpl<Event>(eventList, this.pageRequest, eventList.size()); when(this.eventRepositoryMock.findAll(Matchers.<Specifications<Event>>any(), any(PageRequest.class))) .thenReturn(this.eventsPage); } @DomainStep("a retrieve event notification request") public void givenARetrieveEventNotificationsRequest() { LOGGER.info("GIVEN: a retrieve event notification request"); // Create the request this.request = new FindEventsRequest(); this.request.setPage(DEFAULT_PAGE); this.request.setPageSize(DEFAULT_PAGESIZE); this.request.setDeviceIdentification(this.device.getDeviceIdentification()); } @DomainStep("a retrieve event notification request with requested page (.*) and pageSize (.*)") public void givenARetrieveEventNotificationsRequestWithRequestPageAndPageSize(final String requestedPage, final String pageSize) throws ArgumentNullOrEmptyException { LOGGER.info("GIVEN: a retrieve event notification request with requested page {} and pageSize {}", requestedPage, pageSize); // Create the request this.request = new FindEventsRequest(); this.request.setPage(Integer.parseInt(requestedPage)); this.request.setPageSize(Integer.parseInt(pageSize)); this.request.setDeviceIdentification(this.device.getDeviceIdentification()); this.specifications = Specifications.where(this.eventSpecifications.isAuthorized(this.organisation)); this.pageRequest = new PageRequest(Integer.parseInt(requestedPage), Math.min(Integer.parseInt(pageSize), PAGESIZELIMIT), Sort.Direction.DESC, "creationTime"); } @DomainStep("a received event notification at (.*) from (.*)") public void givenAReceivedEventNotificationAtFrom(final String timestamp, final String device) { LOGGER.info("GIVEN: a received event notification at (.*) from (.*)", timestamp, device); this.event = new EventBuilder().withDevice(new DeviceBuilder().withDeviceIdentification(device).build()) .build(); final List<Event> eventList = new ArrayList<Event>(); eventList.add(this.event); this.eventsPage = new PageImpl<Event>(eventList); LOGGER.info("events: {}", this.eventsPage.getContent().size()); when(this.eventRepositoryMock.findAll(Matchers.<Specifications<Event>>any(), any(PageRequest.class))) .thenReturn(this.eventsPage); } @DomainStep("(.*) received event notifications") public void givenNumberReceivedEventNotifications(final String count) { LOGGER.info("GIVEN: {} received event notifications", count); final List<Event> eventList = new ArrayList<Event>(); int totalPages = 0; if (count != null && count != "EMPTY") { for (int i = 0; i < Math.min(Integer.parseInt(count), Math.min(this.request.getPageSize(), PAGESIZELIMIT)); i++) { eventList.add(new Event(this.device, this.event.getEventType(), this.event.getDescription(), this.event.getIndex())); } totalPages = Integer.parseInt(count); } this.eventsPage = new PageImpl<Event>(eventList, new PageRequest(this.request.getPage(), Math.min(this.request.getPageSize(), PAGESIZELIMIT)), totalPages); when(this.eventRepositoryMock.findAll(Matchers.<Specifications<Event>>any(), any(PageRequest.class))) .thenReturn(this.eventsPage); } @DomainStep("the event notification must be filtered on (.*), (.*), and (.*)") public void givenTheEventNotificationMustBeFilteredOn(final String deviceIdentification, final String fromTimestamp, final String untilTimestamp) { LOGGER.info("GIVEN: the event notification must be filtered on {}, {}, and {}", new Object[] { deviceIdentification, fromTimestamp, untilTimestamp }); // implement filter on fromTimestamp // implement filter on untilTimestamp if (deviceIdentification != null && !deviceIdentification.equals("EMPTY")) { this.request.setDeviceIdentification(deviceIdentification); when(this.deviceRepositoryMock.findByDeviceIdentification(deviceIdentification)) .thenReturn(this.device); when(this.ssldRepositoryMock.findByDeviceIdentification(deviceIdentification)).thenReturn(this.device); when(this.ssldRepositoryMock.findOne(1L)).thenReturn(this.device); final List<DeviceAuthorization> authorizations = new ArrayList<DeviceAuthorization>(); authorizations.add(new DeviceAuthorizationBuilder().withOrganisation(this.organisation) .withDevice(new DeviceBuilder().withDeviceIdentification(deviceIdentification).build()) .withFunctionGroup(DeviceFunctionGroup.MANAGEMENT).build()); when(this.deviceAuthorizationRepositoryMock.findByOrganisationAndDevice(any(Organisation.class), any(Device.class))).thenReturn(authorizations); } } // === WHEN === @DomainStep("the retrieve event notification request is received") public void whenTheRetrieveEventNotificationRequestIsReceived() { LOGGER.info("WHEN: the retrieve event notification request is received"); try { // Send the find events request. this.response = this.deviceManagementEndpoint .findEventsRequest(this.organisation.getOrganisationIdentification(), this.request); if (this.response == null) { LOGGER.info("Response is null"); } } catch (final Throwable t) { LOGGER.error("Exception [{}]: {}\nStacktrace: {}", t.getClass().getSimpleName(), t.getMessage(), t.getStackTrace()); } } // === THEN === @DomainStep("the OSGP should send an event notification response") public boolean thenTheOSGPShouldSendAnEventNotificationResponse() { LOGGER.info("THEN: the OSGP should send an event notification response"); try { verify(this.eventRepositoryMock, times(1)).findAll(this.actualSpecifications.capture(), this.actualPageRequest.capture()); } catch (final Throwable t) { LOGGER.error("Exception [{}]: {}", t.getClass().getSimpleName(), t.getMessage()); return false; } // Expect the response to be returned. return this.response != null; } @DomainStep("the response should contain the event notification (.*), (.*), (.*), (.*) and (.*)") public boolean thenTheResponseShouldContainTheEventNotification(final String timestamp, final String deviceIdentification, final String event, final String description, final String index) { LOGGER.info("THEN: the response should contain the event notification (.*), (.*), (.*), (.*) and (.*)", new Object[] { timestamp, deviceIdentification, event, description, index }); final boolean sizeCorrect = this.response.getEvents().size() == 1; final com.alliander.osgp.adapter.ws.schema.core.devicemanagement.Event eventInstance = this.response .getEvents().get(0); final boolean deviceIdentificationCorrect = eventInstance.getDeviceIdentification() .equals(deviceIdentification); final boolean descriptionCorrect = eventInstance.getDescription().equals(description); final boolean eventCorrect = eventInstance.getEventType().ordinal() == EventType.valueOf(event).ordinal(); boolean indexCorrect = true; if (index != null && index != "" && index != "EMPTY") { indexCorrect = this.response.getEvents().get(0).getIndex().equals(Integer.parseInt(index)); } return sizeCorrect && deviceIdentificationCorrect && descriptionCorrect && eventCorrect && indexCorrect; } /** * Verify that the correct number events are returned. * * @param number * The number of expected events * @return */ @DomainStep("the response should contain (.*) event notifications") public boolean andTheResponseShouldContainNumberEventNotifications(final String number) { LOGGER.info("THEN: the response should contain {} event notifications", number); if (this.response == null) { LOGGER.info("the actual response is null"); return false; } if (this.response.getEvents() == null) { LOGGER.info("the events list in the actual response is null"); return false; } if (this.response.getEvents().size() != Integer.parseInt(number)) { LOGGER.info("the actual response contains {} events", this.response.getEvents().size()); return false; } return true; } /** * Verify that the page object has the correct total values for total entities and total pages. * * @param totalNofEventNotifications * @param totalNofPages * @return */ @DomainStep("the response should contain total number of pages (.*)") public boolean andTheResponseShouldContainTotalNumberOfPages(final String totalNofPages) { LOGGER.info("THEN: the response should contain total number of pages (.*)", totalNofPages); if (this.response == null) { LOGGER.info("the actual response is null"); return false; } if (this.response.getPage() == null) { LOGGER.info("the page in the actual response is null"); return false; } if (this.response.getPage().getTotalPages() != Integer.parseInt(totalNofPages)) { LOGGER.info("the actual total number of pages is {}", this.response.getPage().getTotalPages()); return false; } return true; } }