public synchronized void removeAttributes(Set attrNames) { if ((attrNames != null) && (!attrNames.isEmpty())) { stringAttributes.removeKeys(attrNames); byteAttributes.removeKeys(attrNames); // Remove them from the list of readble attributes of each principal Iterator itr = cacheEntries.keySet().iterator(); while (itr.hasNext()) { String principalDN = (String) itr.next(); removeAttributes(principalDN, attrNames); } } }
/** * Should be cleared, only if the entry is still valid only the data has changed. If entry has * been deleted then should be removed. */ public synchronized void clear() { if (isValidEntry) { // Clear only if it is a valid entry // If entry is not valid then all these maps will be null stringAttributes.clear(); byteAttributes.clear(); cacheEntries.clear(); } // Don't have to change isValidEntry as it would have been updated if // the entry was deleted. Also do not change the object type here // it is need. Ideally the object type won't change for a DN lastModifiedTime = 0; // => expired organizationDN = null; // Could have been renamed }
private AMHashMap getPluginAttrsAndUpdateCache( SSOToken token, String principalDN, String entryDN, CacheBlock cb, AMHashMap attributes, Set missAttrNames, boolean byteValues, int profileType) throws AMException { // Get all external attributes by calling plugin modules. // Note these attributes should not be cached. Map extAttributes = getExternalAttributes(token, entryDN, missAttrNames, profileType); if (extAttributes != null && !extAttributes.isEmpty()) { // Remove these external attributes from Cache Set extAttrNames = extAttributes.keySet(); cb.removeAttributes(extAttrNames); if (getDebug().messageEnabled()) { getDebug() .message( "CachedRemoteServicesImpl." + "getPluginAttrsAndUpdateCache(): External " + "attributes present. Adding them with original" + " list. External Attributes: " + extAttrNames); } // Note the attributes stored in the cache are already copied // to a new map. Hence modifying this attributes is okay. attributes.putAll(extAttributes); } return attributes; }
public synchronized boolean hasCompleteSet(String principalDN) { CacheEntry ce = (CacheEntry) cacheEntries.get(principalDN); boolean completeSet = false; if (ce != null && !hasExpiredAndUpdated()) { completeSet = ce.isCompleteSet(); } return completeSet; }
public String toString() { StringBuffer sb = new StringBuffer(); sb.append("\n----------- START CACHE BLOCK -----------"); sb.append("\nEntry DN: ").append(entryDN); sb.append(" Valid Entry: ").append(isValidEntry); sb.append("\nOrganization: ").append(organizationDN); sb.append("\nString Attributes: "); if ((stringAttributes != null) && (!stringAttributes.isEmpty())) { sb.append(MiscUtils.mapSetToString(stringAttributes)); } sb.append("\nByte Attributes: "); sb.append(MiscUtils.mapSetToString(byteAttributes)); sb.append("\nByte Negative Attributes: "); if ((byteAttributes != null) && (!byteAttributes.isEmpty())) { sb.append(byteAttributes.getNegativeByteAttrClone().toString()); } sb.append("\nCache Entries: "); if (cacheEntries != null && !cacheEntries.isEmpty()) { Iterator itr = cacheEntries.keySet().iterator(); while (itr.hasNext()) { String principal = (String) itr.next(); CacheEntry ce = (CacheEntry) cacheEntries.get(principal); sb.append("\nPrincipal: ").append(principal); sb.append(ce.toString()); } } else { sb.append("<empty>"); } sb.append("\n----------- END CACHE BLOCK -----------"); return sb.toString(); }
public synchronized void putAttributes( String principalDN, Map attributes, Set inAccessibleAttrNames, boolean isCompleteSet, boolean byteValues) { CacheEntry ce = (CacheEntry) cacheEntries.get(principalDN); if (ce == null) { ce = new CacheEntry(); cacheEntries.put(principalDN, ce); } // Copy only the attributes in the common place. Store the invalid/ // unreadable attrs per principal. if (!byteValues) { Set attrsWithValues = stringAttributes.copyValuesOnly(attributes); ce.putAttributes(attrsWithValues, inAccessibleAttrNames, isCompleteSet); } else { Set attrsWithValues = byteAttributes.copyValuesOnly(attributes); ce.putAttributes(attrsWithValues, inAccessibleAttrNames, isCompleteSet); } updateLastModifiedTime(); }
private synchronized void removeAttributes(String principalDN, Set attrNames) { CacheEntry ce = (CacheEntry) cacheEntries.get(principalDN); if (ce != null) { ce.removeAttributeNames(attrNames); } }
public synchronized void removeAttributes(String principalDN) { CacheEntry ce = (CacheEntry) cacheEntries.remove(principalDN); if (ce != null) { ce.clear(); // To remove all used references } }
public synchronized Map getAttributes(String principalDN, Set attrNames, boolean byteValues) { Map attributes = new AMHashMap(byteValues); // Get the cache entry for the principal CacheEntry ce = (CacheEntry) cacheEntries.get(principalDN); if (ce != null && !hasExpiredAndUpdated()) { // Get the names of attributes that this principal can access Set accessibleAttrs = null; if (attrNames == null) { accessibleAttrs = ce.getReadableAttrNames(); } else { accessibleAttrs = ce.getReadableAttrNames(attrNames); } // Get the attribute values from cache if (!byteValues) { attributes = stringAttributes.getCopy(accessibleAttrs); if (ce.isCompleteSet() && !attributes.keySet().containsAll(accessibleAttrs) && !byteAttributes.isEmpty()) { // Since the flag for complete set does not distingusih // between string and binary attributes, check for // missing attributes in byteAttributes for (Iterator items = accessibleAttrs.iterator(); items.hasNext(); ) { Object key = items.next(); if (!attributes.containsKey(key) && byteAttributes.containsKey(key)) { byte[][] values = (byte[][]) byteAttributes.get(key); Set valueSet = new HashSet(values.length * 2); for (int i = 0; i < values.length; i++) { try { valueSet.add(new String(values[i], "UTF8")); } catch (UnsupportedEncodingException uee) { // Use default encoding valueSet.add(new String(values[i])); } } attributes.put(key, valueSet); } } } } else { attributes = byteAttributes.getCopy(accessibleAttrs); if (ce.isCompleteSet() && !attributes.keySet().containsAll(accessibleAttrs) && !stringAttributes.isEmpty()) { // Since the flag for complete set does not distingusih // between string and binary attributes, check for // missing attributes in stringAttributes for (Iterator items = accessibleAttrs.iterator(); items.hasNext(); ) { Object key = items.next(); if (!attributes.containsKey(key) && stringAttributes.containsKey(key)) { Set valueSet = (Set) stringAttributes.get(key); byte[][] values = new byte[valueSet.size()][]; int item = 0; for (Iterator vals = valueSet.iterator(); vals.hasNext(); ) { String val = (String) vals.next(); values[item] = new byte[val.length()]; byte[] src = null; try { src = val.getBytes("UTF8"); } catch (UnsupportedEncodingException uee) { // Use default encoding src = val.getBytes(); } System.arraycopy(src, 0, values[item], 0, val.length()); item++; } attributes.put(key, values); } } } } // Get the names of attributes that are invalid/not accessible Set inAccessibleAttrs = ce.getInaccessibleAttrNames(attrNames); ((AMHashMap) attributes).addEmptyValues(inAccessibleAttrs); } return attributes; }
public synchronized boolean hasCache(String principalDN) { CacheEntry ce = (CacheEntry) cacheEntries.get(principalDN); return (ce != null && !hasExpiredAndUpdated()); }
/** * Gets the specific attributes corresponding to the entryDN. This method obtains the DC Tree node * attributes and also performs compliance related verification checks in compliance mode. Note: * In compliance mode you can skip the compliance checks by setting ignoreCompliance to "false". * * @param token a valid SSOToken * @param entryDN the DN of the entry whose attributes need to retrieved * @param attrNames a Set of names of the attributes that need to be retrieved. The attrNames * should not be null * @param ignoreCompliance a boolean value specificying if compliance related entries need to * ignored or not. Ignored if true. * @return a Map containing attribute names as keys and Set of values corresponding to each key. * @throws AMException if an error is encountered in fetching the attributes */ public Map getAttributes( SSOToken token, String entryDN, Set attrNames, boolean ignoreCompliance, boolean byteValues, int profileType) throws AMException, SSOException { if (attrNames == null || attrNames.isEmpty()) { return getAttributes(token, entryDN, ignoreCompliance, byteValues, profileType); } // Attributes are being requested; increment cache stats request counter cacheStats.incrementRequestCount(getSize()); // Load the whole attrset in the cache, if in DCTree mode // Not good for performance, but fix later TODO (Deepa) if (dcTreeServicesImpl.isRequired()) { // TODO: This needs to be fixed! getAttributes(token, entryDN, ignoreCompliance, byteValues, profileType); } String principalDN = MiscUtils.getPrincipalDN(token); if (getDebug().messageEnabled()) { getDebug() .message( "In CachedRemoteServicesImpl.getAttributes(" + "SSOToken entryDN, attrNames, ignoreCompliance, " + "byteValues) " + "(" + principalDN + ", " + entryDN + ", " + attrNames + ", " + ignoreCompliance + ", " + byteValues + " method."); } String dn = MiscUtils.formatToRFC(entryDN); CacheBlock cb = (CacheBlock) sdkCache.get(dn); if (cb == null) { // Entry not present in cache if (getDebug().messageEnabled()) { getDebug() .message( "CachedRemoteServicesImpl." + "getAttributes(): NO entry found in Cache. Getting" + " all these attributes from DS: " + attrNames); } // If the attributes returned here have an empty set as value, then // such attributes do not have a value or invalid attributes. // Internally keep track of these attributes. AMHashMap attributes = (AMHashMap) super.getAttributes( token, entryDN, attrNames, ignoreCompliance, byteValues, profileType); // These attributes are either not present or not found in DS. // Try to check if they need to be fetched by external // plugins Set missAttrNames = attributes.getMissingAndEmptyKeys(attrNames); cb = new CacheBlock(dn, true); cb.putAttributes(principalDN, attributes, missAttrNames, false, byteValues); sdkCache.put(dn, cb); if (!missAttrNames.isEmpty()) { attributes = getPluginAttrsAndUpdateCache( token, principalDN, entryDN, cb, attributes, missAttrNames, byteValues, profileType); } return attributes; } else { // Entry present in cache validateEntry(token, cb); // Entry may be an invalid entry AMHashMap attributes = (AMHashMap) cb.getAttributes(principalDN, attrNames, byteValues); // Find the missing attributes that need to be obtained from DS // Only find the missing keys as the ones with empty sets are not // found in DS Set missAttrNames = attributes.getMissingKeys(attrNames); if (!missAttrNames.isEmpty()) { boolean isComplete = cb.hasCompleteSet(principalDN); AMHashMap dsAttributes = null; if (!isComplete || // Check for "nsRole" and "nsRoleDN" attributes missAttrNames.contains(NSROLEDN_ATTR) || missAttrNames.contains(NSROLE_ATTR)) { if (getDebug().messageEnabled()) { getDebug() .message( "CachedRemoteServicesImpl." + "getAttributes(): Trying to get these missing" + " attributes from DS: " + missAttrNames); } dsAttributes = (AMHashMap) super.getAttributes( token, entryDN, missAttrNames, ignoreCompliance, byteValues, profileType); if (dsAttributes != null) { attributes.putAll(dsAttributes); // Add these attributes, may be found in DS or just mark // as invalid (Attribute level Negative caching) Set newMissAttrNames = dsAttributes.getMissingAndEmptyKeys(missAttrNames); // Update dsAttributes with rest of the attributes // in cache dsAttributes.putAll(cb.getAttributes(principalDN, byteValues)); // Update the cache cb.putAttributes(principalDN, dsAttributes, newMissAttrNames, isComplete, byteValues); missAttrNames = newMissAttrNames; } } else { // Update cache with invalid attributes cb.putAttributes( principalDN, cb.getAttributes(principalDN, byteValues), missAttrNames, isComplete, byteValues); } if (!missAttrNames.isEmpty()) { attributes = getPluginAttrsAndUpdateCache( token, principalDN, entryDN, cb, attributes, missAttrNames, byteValues, profileType); } } else { // All attributes found in cache if (getDebug().messageEnabled()) { getDebug() .message( "CachedRemoteServicesImpl." + "getAttributes(): found all attributes in " + "Cache."); } cacheStats.updateHitCount(getSize()); } // Remove all the empty values from the return attributes return attributes; } }
/** * Gets all attributes corresponding to the entryDN. This method obtains the DC Tree node * attributes and also performs compliance related verification checks in compliance mode. Note: * In compliance mode you can skip the compliance checks by setting ignoreCompliance to "false". * * @param token a valid SSOToken * @param entryDN the DN of the entry whose attributes need to retrieved * @param ignoreCompliance a boolean value specificying if compliance related entries need to * ignored or not. Ignored if true. * @param byteValues if false StringValues are fetched, if true byte values are fetched. * @param profileType the oject type of entryDN * @return a Map containing attribute names as keys and Set of values corresponding to each key. * @throws AMException if an error is encountered in fetching the attributes */ public Map getAttributes( SSOToken token, String entryDN, boolean ignoreCompliance, boolean byteValues, int profileType) throws AMException, SSOException { // Attributes are being requested; increment cache stats request counter cacheStats.incrementRequestCount(getSize()); String principalDN = MiscUtils.getPrincipalDN(token); String dn = MiscUtils.formatToRFC(entryDN); if (getDebug().messageEnabled()) { getDebug() .message( "In CachedRemoteServicesImpl.getAttributes(" + "SSOToken entryDN, ignoreCompliance) " + "(" + principalDN + ", " + entryDN + ", " + ignoreCompliance + " method."); } CacheBlock cb = (CacheBlock) sdkCache.get(dn); AMHashMap attributes = null; if (cb != null) { validateEntry(token, cb); if (cb.hasCompleteSet(principalDN)) { cacheStats.updateHitCount(getSize()); if (getDebug().messageEnabled()) { getDebug() .message( "CachedRemoteServicesImpl." + "getAttributes(): found all attributes in " + "Cache."); } attributes = (AMHashMap) cb.getAttributes(principalDN, byteValues); } else { // Get the whole set from DS and store it; // ignore incomplete set if (getDebug().messageEnabled()) { getDebug() .message( "CachedRemoteServicesImpl." + "getAttributes(): complete attribute set NOT " + "found in cache. Getting from DS."); } attributes = (AMHashMap) super.getAttributes(token, entryDN, ignoreCompliance, byteValues, profileType); cb.putAttributes(principalDN, attributes, null, true, byteValues); } } else { // Attributes not cached // Get all the attributes from DS and store them attributes = (AMHashMap) super.getAttributes(token, entryDN, ignoreCompliance, byteValues, profileType); cb = new CacheBlock(entryDN, true); cb.putAttributes(principalDN, attributes, null, true, byteValues); sdkCache.put(dn, cb); if (getDebug().messageEnabled()) { getDebug() .message( "CachedRemoteServicesImpl." + "getAttributes(): attributes NOT found in cache. " + "Fetched from DS."); } } // Get all external DS attributes by calling plugin modules. // Note these attributes should not be cached. Map extAttributes = getExternalAttributes(token, entryDN, null, profileType); if (extAttributes != null && !extAttributes.isEmpty()) { // Note the attributes stored in the cache are already copied to a // new map. Hence modifying this attributes is okay. if (getDebug().messageEnabled()) { getDebug() .message( "CachedRemoteServicesImpl." + "getAttributes(): External attributes present. Adding" + " them with original list"); } attributes.putAll(extAttributes); } return attributes; }