Java tutorial
package tv.arte.resteventapi.core.services.impl; /* * #%L * RestEventAPI * %% * Copyright (C) 2014 ARTE G.E.I.E * %% * This program is free software: you can redistribute it and/or modify * it under the terms of The MIT License (MIT) as published by the Open Source * Initiative. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See The * MIT License (MIT) for more details. * * You should have received a copy of The MIT License (MIT) * along with this program. If not, see <http://opensource.org/licenses/MIT> * #L% */ import java.net.URI; import java.net.URISyntaxException; import java.util.Arrays; import java.util.Calendar; import java.util.Date; import java.util.List; import java.util.UUID; import org.apache.commons.lang.StringUtils; import org.joda.time.MutableDateTime; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import tv.arte.resteventapi.core.RestEventApiError; import tv.arte.resteventapi.core.RestEventApiRuntimeException; import tv.arte.resteventapi.core.clients.RestClientCallState; import tv.arte.resteventapi.core.clients.RestClientExecutionResult; import tv.arte.resteventapi.core.clients.RestEventApiRestClient; import tv.arte.resteventapi.core.domain.entities.RestEvent; import tv.arte.resteventapi.core.domain.entities.enums.RestEventStatus; import tv.arte.resteventapi.core.domain.repositories.DomainAuthorizationRepository; import tv.arte.resteventapi.core.domain.repositories.RestEventRepository; import tv.arte.resteventapi.core.services.EventService; import tv.arte.resteventapi.core.transferobjects.RestEventPostRequestParam; import tv.arte.resteventapi.core.transferobjects.RestEventSearchRequestParam; import tv.arte.resteventapi.core.validation.FieldValidationError; import tv.arte.resteventapi.core.validation.RestEventApiValidationException; /** * The default implementation of {@link EventService} * * @author Simeon Petev * @since 0.1 */ @Service public class EventServiceImpl implements EventService { private Logger logger = LoggerFactory.getLogger(getClass()); @Autowired private RestEventRepository restEventRepository; @Autowired private DomainAuthorizationRepository domainAuthorizationRepository; /** * {@inheritDoc} */ public RestEvent retrieveRestEventById(String eventId) { return restEventRepository.findById(eventId); } /** * {@inheritDoc} */ public List<RestEvent> retrieveRestEventForSearchParams( RestEventSearchRequestParam restEventSearchRequestParam) { return restEventRepository.findRestEventForSearchParams(restEventSearchRequestParam); } /** * {@inheritDoc} */ public RestEvent createRestEvent(RestEventPostRequestParam restEventPostRequestParam) throws RestEventApiValidationException { /* * Database access validations - START */ if (logger.isDebugEnabled()) logger.debug("Start advanced validations requiring database access"); if (restEventPostRequestParam.getId() != null || restEventRepository.exists(restEventPostRequestParam.getId())) { throw new RestEventApiValidationException(Arrays.asList( new FieldValidationError(RestEventApiError.PRE_DEFINED.RIA_ERR_V_ID_NOT_AVAILABLE, "id"))); } try { URI urlToCall = new URI(restEventPostRequestParam.getUrl()); String domain = urlToCall.getHost(); String wwwPrefix = "www."; if (domain.startsWith(wwwPrefix)) { domain = domain.substring(wwwPrefix.length()); } if (!domainAuthorizationRepository.exists(domain)) { throw new RestEventApiValidationException( Arrays.asList(RestEventApiError.PRE_DEFINED.RIA_ERR_V_DOMAIN_NOT_QUERYABLE)); } } catch (URISyntaxException e) { throw new RestEventApiValidationException(Arrays.asList(new FieldValidationError( RestEventApiError.PRE_DEFINED.RIA_ERR_V_URL_DOMAIN_UNEXTRACTABLE, "url"))); } if (logger.isDebugEnabled()) logger.debug("End advanced validations requiring database access. Validations passed."); /* * Database access validations - END */ RestEvent newRestEvent = new RestEvent(); if (StringUtils.isNotBlank(restEventPostRequestParam.getId())) { newRestEvent.setId(restEventPostRequestParam.getId()); } else { String newId = UUID.randomUUID().toString(); final int maxLoops = 10000; int currentLoop = 0; while (restEventRepository.exists(newId)) { newId = UUID.randomUUID().toString(); currentLoop++; if (currentLoop >= maxLoops) { throw new RestEventApiRuntimeException( "Cannot generate id for a new rest event. The maximum number of loops has been reached."); } } newRestEvent.setId(newId); } newRestEvent.setBody(restEventPostRequestParam.getBody()); newRestEvent.setHeaders(restEventPostRequestParam.getHeaders()); newRestEvent.setInterval(restEventPostRequestParam.getInterval()); newRestEvent.setMaxAttempts(restEventPostRequestParam.getMaxAttempts()); newRestEvent.setMethod(restEventPostRequestParam.getMethod()); newRestEvent.setTimeout(restEventPostRequestParam.getTimeout()); newRestEvent.setTriggerDate(restEventPostRequestParam.getTriggerDate()); newRestEvent.setUrl(restEventPostRequestParam.getUrl()); newRestEvent.setCounter(0); newRestEvent.setStatus(RestEventStatus.BUFFER); newRestEvent.setNextExecution(restEventPostRequestParam.getTriggerDate()); //TODO: Remove the automatic increment of the version once the @Version annotation is working properly newRestEvent.setVersion(1L); newRestEvent.setCreationDate(Calendar.getInstance().getTime()); restEventRepository.save(newRestEvent); return newRestEvent; } /** * {@inheritDoc} */ public void deleteRestEventForId(String eventId) throws RestEventApiValidationException { RestEvent eventToDelete = restEventRepository.findById(eventId); if (eventToDelete != null) { restEventRepository.delete(eventToDelete); } else { logger.error("Attempt to delete a non existing event with id: " + eventId); throw new RestEventApiValidationException( Arrays.asList(RestEventApiError.PRE_DEFINED.RIA_ERR_V_UNEXISTING)); } } /** * {@inheritDoc} */ public List<RestEvent> eventsForScheduling(Date beforeDate) { return restEventRepository.findEventsForScheduling(beforeDate); } /** * {@inheritDoc} */ public RestEvent processRestEvent(String id) { RestEvent restEvent = restEventRepository.findById(id); if (restEvent == null) { logger.warn("Unable to process event with id " + id + ". The event do not exists."); return restEvent; } if (RestEventStatus.SENT.equals(restEvent.getStatus())) { logger.info( "No action will be performed for event with id " + id + ". The event has already been sent."); return restEvent; } if (restEvent.getMaxAttempts() <= restEvent.getCounter()) { logger.info("No action will be performed for event with id " + id + ". The event has no more attempts left."); return restEvent; } if (logger.isDebugEnabled()) logger.debug("Event scheduled for " + restEvent.getNextExecution().toString() + ", is acctualy executed at " + Calendar.getInstance().getTime().toString()); try { RestClientExecutionResult executionResult = RestEventApiRestClient.execute(restEvent); restEvent.setHttpResponseCode(executionResult.getResponseCode()); if (RestClientCallState.OK.equals(executionResult.getState()) && ((executionResult.getResponseCode() >= 200 && executionResult.getResponseCode() < 300) || executionResult.getResponseCode() == 304)) { restEvent.setStatus(RestEventStatus.SENT); } else { if (RestClientCallState.TIMEOUT.equals(executionResult.getState())) { logger.info("The request for RestEvent with id " + id + " has been timed out."); } restEvent.setStatus(RestEventStatus.ERROR); } } catch (Exception e) { restEvent.setStatus(RestEventStatus.ERROR); } restEvent.setCounter(restEvent.getCounter() != null ? restEvent.getCounter() + 1 : 1); if (!RestEventStatus.SENT.equals(restEvent.getStatus()) && restEvent.getCounter() < restEvent.getMaxAttempts()) { MutableDateTime nextExecution = new MutableDateTime(); nextExecution.addSeconds(restEvent.getInterval()); restEvent.setNextExecution(nextExecution.toDate()); } restEvent.setVersion(restEvent.getVersion() != null ? restEvent.getVersion() + 1L : 1L); restEvent.setLastModified(Calendar.getInstance().getTime()); restEventRepository.save(restEvent); return restEvent; } }