/* * Copyright (c) 2013 EMC Corporation * All Rights Reserved */ package com.emc.storageos.systemservices.impl.eventhandler.connectemc; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import com.emc.storageos.coordinator.client.model.PropertyInfoExt; import com.emc.storageos.svcs.errorhandling.resources.APIException; import com.emc.storageos.systemservices.impl.upgrade.CoordinatorClientExt; import org.joda.time.DateTime; import org.joda.time.Days; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import com.emc.storageos.systemservices.impl.licensing.LicenseInfoExt; import com.emc.storageos.systemservices.impl.licensing.LicenseManager; @Component public class CallHomeEventManager { private LicenseManager _licenseManager; // Common date format when storing in coordinator service. public static final String SERIALIZE_DATE_FORMAT = "MM/dd/yyyy"; // used to check if the system.connectemc.transport is configured for SYR. // If it is "None", SYR is turned off. private static final String NONE = "None"; private static final Logger _log = LoggerFactory.getLogger(CallHomeEventManager.class); @Autowired private CoordinatorClientExt coordinatorClientExt; /** * Determines whether it's time to send a new heartbeat event. * * @return boolean * @throws ParseException * @throws Exception */ public boolean doSendHeartBeat(LicenseInfoExt licenseInfo) throws ParseException { if (licenseInfo == null) { return true; } String lastHeartbeatDate = licenseInfo.getLastHeartbeatEventDate(); if (lastHeartbeatDate == null || lastHeartbeatDate.isEmpty() || lastHeartbeatDate.equals(CallHomeConstants.VALUE_NOT_SET)) { _log.info("There is no previous heartbeat event sent."); return true; } _log.info("Previous heartbeat event was sent on: {}", lastHeartbeatDate); // compare today's date to the date stored in the coordinator service. // If it's >= than // the HEARTBEART_EVENT_THRESHOLD, return true. SimpleDateFormat storedDate = new SimpleDateFormat(SERIALIZE_DATE_FORMAT); Date zkDate = storedDate.parse(lastHeartbeatDate); Date today = Calendar.getInstance().getTime(); int days = Days.daysBetween(new DateTime(zkDate), new DateTime(today)).getDays(); if (days > (CallHomeConstants.HEARTBEART_EVENT_THRESHOLD - 1)) { _log.info("It's been {} days since last heartbeat event was sent. Sending another one now. ", days); return true; } _log.info("Heartbeat event was sent {} days back. Will send another one in {} days.", days, (CallHomeConstants.HEARTBEART_EVENT_THRESHOLD - days)); return false; } /** * Determines whether a registration event has already been sent. * * @return boolean * @throws Exception */ public boolean doSendRegistration(LicenseInfoExt licenseInfo) throws Exception { if (licenseInfo == null) { return true; } String registrationDate = licenseInfo.getLastRegistrationEventDate(); if (registrationDate == null || registrationDate.isEmpty() || registrationDate.equals(CallHomeConstants.VALUE_NOT_SET)) { _log.info("There is no previous registration event sent."); return true; } _log.info("Previous registration event was sent on: {}", registrationDate); // compare today's date to the date stored in the coordinator service. // If it's >= than // the HEARTBEART_EVENT_THRESHOLD, return true. SimpleDateFormat storedDate = new SimpleDateFormat(SERIALIZE_DATE_FORMAT); Date zkDate = storedDate.parse(registrationDate); Date today = Calendar.getInstance().getTime(); int days = Days.daysBetween(new DateTime(zkDate), new DateTime(today)).getDays(); if (days > (CallHomeConstants.REGISTRATION_EVENT_THRESHOLD - 1)) { _log.info("It's been {} days since last registration event was sent. Sending another one now. ", days); return true; } _log.info("Registration event was sent {} days back. Will send another one in {} days.", days, (CallHomeConstants.REGISTRATION_EVENT_THRESHOLD - days)); return false; } /** * Determines whether it's time to send a new capacity exceeded event. * * @return boolean * @throws Exception */ public boolean doSendCapicityExceeded(LicenseInfoExt licenseInfo) throws Exception { if (licenseInfo == null) { return true; } String lastCapacityExceedDate = licenseInfo.getLastCapacityExceededEventDate(); if (lastCapacityExceedDate == null || lastCapacityExceedDate.isEmpty() || lastCapacityExceedDate.equals(CallHomeConstants.VALUE_NOT_SET)) { _log.info("There is no previous capacity-exceeded event sent."); return true; } _log.info("Previous capacity-exceeded event was sent on: {}", lastCapacityExceedDate); // compare today's date to the date stored in zookeeper. If it's >= than // the LICENSE_EXPIRATION_EVENT_THRESHOLD, return true. SimpleDateFormat storedDate = new SimpleDateFormat(SERIALIZE_DATE_FORMAT); Date zkDate = storedDate.parse(lastCapacityExceedDate); Date today = Calendar.getInstance().getTime(); int days = Days.daysBetween(new DateTime(zkDate), new DateTime(today)).getDays(); if (days > (CallHomeConstants.CAPACITY_EXCEEDED_EVENT_THRESHOLD - 1)) { _log.info("It's been {} days since last capacity-exceeded event was sent. Sending another one now. ", days); return true; } _log.info("Capacity-exceeded event was sent {} days back. Will send another one in {} days.", days, (CallHomeConstants.CAPACITY_EXCEEDED_EVENT_THRESHOLD - days)); return false; } /** * Returns true if connectemc is configured and it is control node. */ public boolean canSendEvent() { try { validateSendEvent(); return true; } catch (Exception e) { return false; } } /** * The method will determine if the client is eligible for callhome events. * The client must have a Controller license and configured for ConnectEMC * transport. * * @return */ public boolean isConnectEMCConfigured() { try { // Validate if SYR is enabled for customer. String transport = coordinatorClientExt.getPropertyInfo().getProperties().get(PropertyInfoExt.CONNECTEMC_TRANSPORT); if (transport == null || transport.isEmpty() || transport.equalsIgnoreCase(NONE)) { _log.warn("ConnectEMC is not configured. {} property is set to {}", PropertyInfoExt.CONNECTEMC_TRANSPORT, transport); return false; } } catch (Exception e) { throw APIException.internalServerErrors.getObjectFromError(PropertyInfoExt.CONNECTEMC_TRANSPORT, "local repository", e); } return true; } /** * Validates if connect emc is configured and if it is control node. Else throws * exception. */ public void validateSendEvent() { if (!coordinatorClientExt.isControlNode()) { throw APIException.badRequests.eventsNotAllowedOnNonControlNode(); } if (!isConnectEMCConfigured()) { throw APIException.badRequests.connectEMCNotConfigured(); } } /** * Determines whether it's time to send a new license expiration event. * * @return boolean * @throws Exception */ public boolean doSendLicenseExpiration(LicenseInfoExt licenseInfo) throws Exception { if (licenseInfo == null) { return true; } String lastExpirationDate = licenseInfo.getLastLicenseExpirationDateEventDate(); if (lastExpirationDate == null || lastExpirationDate.isEmpty() || lastExpirationDate.equals(CallHomeConstants.VALUE_NOT_SET)) { _log.info("There is no previous license-expiration event sent."); return true; } _log.info("Previous license-expiration event was sent on: {}", lastExpirationDate); // compare today's date to the date stored in zookeeper. If it's >= than // the LICENSE_EXPIRATION_EVENT_THRESHOLD, return true. SimpleDateFormat storedDate = new SimpleDateFormat(SERIALIZE_DATE_FORMAT); Date zkDate = storedDate.parse(lastExpirationDate); Date today = Calendar.getInstance().getTime(); int days = Days.daysBetween(new DateTime(zkDate), new DateTime(today)).getDays(); if (days > (CallHomeConstants.LICENSE_EXPIRATION_EVENT_THRESHOLD - 1)) { _log.info("It's been {} days since last license-expiration event was sent. Sending another one now. ", days); return true; } _log.info("License-expired event was sent {} days back. Will send another one in {} days.", days, (CallHomeConstants.LICENSE_EXPIRATION_EVENT_THRESHOLD - days)); return false; } @Autowired public void setLicenseManager(LicenseManager licenseManager) { _licenseManager = licenseManager; } }