/** * Fetch new HMS notifications appeared since a specified event ID. The returned list may * include notifications with the same specified ID if they were not seen by Sentry. * * @param lastEventId The event ID to use to request notifications. * @return A list of newer notifications unseen by Sentry. * @throws Exception If an error occurs on the HMS communication. */ public List<NotificationEvent> fetchNotifications(long lastEventId) throws Exception { return fetchNotifications(lastEventId, Integer.MAX_VALUE); }
/** * @return the latest notification Id logged by the HMS * @throws Exception when an error occurs when talking to the HMS client */ public long getCurrentNotificationId() throws Exception { CurrentNotificationEventId eventId; try { eventId = getHmsClient().getCurrentNotificationEventId(); } catch (Exception e) { close(); throw e; } if (eventId != null && eventId.isSetEventId()) { return eventId.getEventId(); } return SentryConstants.EMPTY_NOTIFICATION_ID; }
/** * Checks the last notification processed by sentry and the current event-id of * HMS to see if sentry is out of sync. * * @param latestSentryNotificationId The notification Id to check against the HMS * @return True, sentry is out-of-sync, False otherwise * @throws Exception If an error occurs while fetching the current notification from HMS */ private boolean isSentryOutOfSync(long latestSentryNotificationId) throws Exception { long currentHmsNotificationId = notificationFetcher.getCurrentNotificationId(); if (currentHmsNotificationId < latestSentryNotificationId) { LOGGER.info("The current notification ID on HMS = {} is less than the latest processed Sentry " + "notification ID = {}. Sentry, Out-of-sync", currentHmsNotificationId, latestSentryNotificationId); return true; } return false; }
@Test public void testGetEmptyNotificationsWhenHmsReturnsANullResponse() throws Exception { SentryStore store = Mockito.mock(SentryStore.class); HiveConnectionFactory hmsConnection = Mockito.mock(HiveConnectionFactory.class); HiveMetaStoreClient hmsClient = Mockito.mock(HiveMetaStoreClient.class); Mockito.when(hmsConnection.connect()).thenReturn(new HMSClient(hmsClient)); try (HiveNotificationFetcher fetcher = new HiveNotificationFetcher(store, hmsConnection)) { List<NotificationEvent> events; Mockito.when(hmsClient.getNextNotification(0, Integer.MAX_VALUE, null)) .thenReturn(null); events = fetcher.fetchNotifications(0); assertTrue(events.isEmpty()); } }
filter = createNotificationFilterFor(lastEventId); lastEventId--; response = getHmsClient().getNextNotification(lastEventId, maxEvents, filter); } catch (Exception e) { close(); throw e;
client = new SentryHMSClient(authzConf, hiveConnectionFactory); notificationFetcher = new HiveNotificationFetcher(sentryStore, hiveConnectionFactory);
@Override public void close() { if (client != null) { // Close any outstanding connections to HMS try { client.disconnect(); SentryStateBank.disableState(HMSFollowerState.COMPONENT,HMSFollowerState.CONNECTED); } catch (Exception failure) { LOGGER.error("Failed to close the Sentry Hms Client", failure); } } notificationFetcher.close(); }
@Test public void testGetEmptyNotificationsWhenHmsReturnsEmptyEvents() throws Exception { SentryStore store = Mockito.mock(SentryStore.class); HiveConnectionFactory hmsConnection = Mockito.mock(HiveConnectionFactory.class); HiveMetaStoreClient hmsClient = Mockito.mock(HiveMetaStoreClient.class); Mockito.when(hmsConnection.connect()).thenReturn(new HMSClient(hmsClient)); try (HiveNotificationFetcher fetcher = new HiveNotificationFetcher(store, hmsConnection)) { List<NotificationEvent> events; Mockito.when(hmsClient.getNextNotification(0, Integer.MAX_VALUE, null)) .thenReturn(new NotificationEventResponse(Collections.<NotificationEvent>emptyList())); events = fetcher.fetchNotifications(0); assertTrue(events.isEmpty()); } }
try (HiveNotificationFetcher fetcher = new HiveNotificationFetcher(store, hmsConnection)) { List<NotificationEvent> events; events = fetcher.fetchNotifications(1); assertEquals(2, events.size()); assertEquals(1, events.get(0).getEventId());
notifications = notificationFetcher.fetchNotifications(notificationId); } else { notifications = notificationFetcher.fetchNotifications(notificationId, sentryHMSFetchSize);
@Test public void testGetAllNotificationsReturnedByHms() throws Exception { SentryStore store = Mockito.mock(SentryStore.class); HiveConnectionFactory hmsConnection = Mockito.mock(HiveConnectionFactory.class); HiveMetaStoreClient hmsClient = Mockito.mock(HiveMetaStoreClient.class); Mockito.when(hmsConnection.connect()).thenReturn(new HMSClient(hmsClient)); try (HiveNotificationFetcher fetcher = new HiveNotificationFetcher(store, hmsConnection)) { List<NotificationEvent> events; Mockito.when(hmsClient.getNextNotification(0, Integer.MAX_VALUE, null)) .thenReturn(new NotificationEventResponse( Arrays.<NotificationEvent>asList( new NotificationEvent(1L, 0, "CREATE_DATABASE", ""), new NotificationEvent(2L, 0, "CREATE_TABLE", "") ) )); events = fetcher.fetchNotifications(0); assertEquals(2, events.size()); assertEquals(1, events.get(0).getEventId()); assertEquals("CREATE_DATABASE", events.get(0).getEventType()); assertEquals(2, events.get(1).getEventId()); assertEquals("CREATE_TABLE", events.get(1).getEventType()); } }
try (HiveNotificationFetcher fetcher = new HiveNotificationFetcher(store, hmsConnection)) { List<NotificationEvent> events; events = fetcher.fetchNotifications(0, sentryHMSFetchSize); assertEquals(1, events.size()); assertEquals(1, events.get(0).getEventId());