/** * Returns the log file that is just after the provided log file wrt the order defined on keys, or * {@code null} if the provided log file is the last one (the head log file). */ private LogFile<K, V> getNextLogFile(final LogFile<K, V> currentLogFile) throws ChangelogException { if (isHeadLogFile(currentLogFile)) { return null; } final Pair<K, K> bounds = getKeyBounds(currentLogFile); return logFiles.higherEntry(bounds.getSecond()).getValue(); }
/** * Disable the cursors opened on the head log file log, by closing their underlying cursor. * Returns the state of each cursor just before the close operation. * * @return the pairs (cursor, cursor state) for each cursor pointing to head log file. * @throws ChangelogException If an error occurs. */ private List<Pair<AbortableLogCursor<K, V>, CursorState<K, V>>> disableOpenedCursorsOnHead() throws ChangelogException { final List<Pair<AbortableLogCursor<K, V>, CursorState<K, V>>> openCursorsStates = new ArrayList<>(); final LogFile<K, V> headLogFile = getHeadLogFile(); for (AbortableLogCursor<K, V> cursor : openCursors) { if (cursor.isAccessingLogFile(headLogFile)) { openCursorsStates.add(Pair.of(cursor, cursor.getState())); cursor.closeUnderlyingCursor(); } } return openCursorsStates; }
/** * Returns the key bounds for the provided log file. * * @return the pair of (lowest key, highest key) that correspond to records stored in the * corresponding log file. * @throws ChangelogException if an error occurs while retrieving the keys */ private Pair<K, K> getKeyBounds(final LogFile<K, V> logFile) throws ChangelogException { try { final String name = logFile.getFile().getName(); final String[] keys = name.substring(0, name.length() - Log.LOG_FILE_SUFFIX.length()) .split(LOG_FILE_NAME_SEPARATOR); return Pair.of( recordParser.decodeKeyFromString(keys[0]), recordParser.decodeKeyFromString(keys[1])); } catch (Exception e) { throw new ChangelogException( ERR_CHANGELOG_UNABLE_TO_RETRIEVE_KEY_BOUNDS_FROM_FILE.get(logFile.getFile().getPath()), e); } }
/** * Adds listeners for service names that match the provided predicate. * * @param l Listener to be added. * @param servicePredicate The predicate. */ public void addServiceListener(ConfigurationListener l, Predicate<String> servicePredicate) { serviceListeners.add(Pair.of(l, servicePredicate)); }
/** * Adds listener for all services. * * @param l Listener to be added. */ public void addListener(ConfigurationListener l) { serviceListeners.add(Pair.<ConfigurationListener, Predicate<String>>of(l, null)); }
/** * Will validate the Map representation of the service configuration against the serviceSchema and * return a corresponding JSON representation * * @param attributeValuePairs The schema attribute values. * @param realm The realm, or null if global. * @return Json representation of attributeValuePairs */ public JsonValue toJson(String realm, Map<String, Set<String>> attributeValuePairs) { if (!initialised) { init(); } final boolean validAttributes; try { if (realm == null) { validAttributes = schema.validateAttributes(attributeValuePairs); } else { validAttributes = schema.validateAttributes(attributeValuePairs, realm); } } catch (SMSException e) { debug.error( "schema validation threw an exception while validating the attributes: realm=" + realm + " attributes: " + attributeValuePairs, e); throw new JsonException("Unable to validate attributes", e); } JsonValue parentJson = json(new HashMap<String, Object>()); if (validAttributes) { for (String attributeName : attributeValuePairs.keySet()) { String jsonResourceName = attributeNameToResourceName.get(attributeName); String name; if (jsonResourceName != null) { name = jsonResourceName; } else { name = attributeName; } AttributeSchema attributeSchema = schema.getAttributeSchema(attributeName); if (shouldBeIgnored(attributeName)) { continue; } AttributeSchema.Type type = attributeSchema.getType(); final Set<String> object = attributeValuePairs.get(attributeName); Object jsonAttributeValue = null; if (type == null) { throw new JsonException("Type not defined."); } AttributeSchemaConverter attributeSchemaConverter = attributeSchemaConverters.get(name); if (isASingleValue(type)) { if (!object.isEmpty()) { jsonAttributeValue = attributeSchemaConverter.toJson(object.iterator().next()); } } else if (containsMultipleValues(type)) { if (isAMap(attributeSchema.getUIType())) { Map<String, Object> map = new HashMap<String, Object>(); Iterator<String> itr = object.iterator(); while (itr.hasNext()) { Pair<String, String> entry = nameValueParser.parse(itr.next()); map.put(entry.getFirst(), attributeSchemaConverter.toJson(entry.getSecond())); } jsonAttributeValue = map; } else { List<Object> list = new ArrayList<Object>(); Iterator<String> itr = object.iterator(); while (itr.hasNext()) { list.add(attributeSchemaConverter.toJson(itr.next())); } jsonAttributeValue = list; } } String sectionName = attributeNameToSection.get(attributeName); if (sectionName != null) { parentJson.putPermissive( new JsonPointer("/" + sectionName + "/" + name), jsonAttributeValue); } else { parentJson.put(name, jsonAttributeValue); } } } else { throw new JsonException("Invalid attributes"); } return parentJson; }
private void openReadOnlyLogFile(final File logFilePath) throws ChangelogException { final LogFile<K, V> logFile = LogFile.newReadOnlyLogFile(logFilePath, recordParser); final Pair<K, K> bounds = getKeyBounds(logFile); logFiles.put(bounds.getSecond(), logFile); }