package com.thinkbiganalytics.metadata.sla.api.core;
/*-
* #%L
* thinkbig-sla-metrics-default
* %%
* Copyright (C) 2017 ThinkBig Analytics
* %%
* 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
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import com.thinkbiganalytics.metadata.api.event.MetadataEventListener;
import com.thinkbiganalytics.metadata.api.event.MetadataEventService;
import com.thinkbiganalytics.metadata.api.event.feed.FeedOperationStatusEvent;
import com.thinkbiganalytics.metadata.api.op.FeedOperation;
import org.joda.time.DateTime;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
import javax.annotation.Nonnull;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;
/**
* Service to listen for feed failure events and notify listeners when a feed fails
*/
@Component
public class FeedFailureService {
/**
* Event listener for failure events
*/
private final MetadataEventListener<FeedOperationStatusEvent> failedFeedEventListener = new FailedFeedEventDispatcher();
@Inject
private MetadataEventService eventService;
/**
* Map with the Latest recorded Feed Failure
*/
private Map<String, LastFeedFailure> lastFeedFailureMap = new HashMap<>();
/**
* Map with the Latest recorded failure that has been assessed by the FeedFailureMetricAssessor
*/
private Map<String, LastFeedFailure> lastAssessedFeedFailureMap = new HashMap<>();
/**
* Adds listeners for transferring events.
*/
@PostConstruct
public void addEventListener() {
eventService.addListener(failedFeedEventListener);
}
/**
* Removes listeners and stops transferring events.
*/
@PreDestroy
public void removeEventListener() {
eventService.removeListener(failedFeedEventListener);
}
/**
* Should we assess the failure. If so mark the latest as being assesed as a failure
*/
public boolean hasFailure(String feedName) {
LastFeedFailure lastFeedFailure = lastFeedFailureMap.get(feedName);
LastFeedFailure lastAssessedFailure = lastAssessedFeedFailureMap.get(feedName);
if (lastFeedFailure != null) {
if (lastAssessedFailure == null || (lastAssessedFailure != null && lastFeedFailure.isAfter(lastAssessedFailure.getDateTime()))) {
//reassign it as the lastAssessedFailure
lastAssessedFeedFailureMap.put(feedName, lastFeedFailure);
return true;
}
}
return false;
}
public static class LastFeedFailure {
private String feedName;
private DateTime dateTime;
public LastFeedFailure() {
}
public LastFeedFailure(String feedName) {
this.feedName = feedName;
this.dateTime = DateTime.now();
}
public String getFeedName() {
return feedName;
}
public void setFeedName(String feedName) {
this.feedName = feedName;
}
public DateTime getDateTime() {
return dateTime;
}
public void setDateTime(DateTime dateTime) {
this.dateTime = dateTime;
}
public boolean isAfter(DateTime time) {
return dateTime != null && dateTime.isAfter(time);
}
}
/**
* populate latest failure events
*/
private class FailedFeedEventDispatcher implements MetadataEventListener<FeedOperationStatusEvent> {
@Override
public void notify(@Nonnull final FeedOperationStatusEvent event) {
if (FeedOperation.State.FAILURE.equals(event.getData().getState())) {
event.getData().getFeedName();
lastFeedFailureMap.put(event.getData().getFeedName(), new LastFeedFailure(event.getData().getFeedName()));
}
}
}
}