Package com.springsource.insight.plugin.ldap

Source Code of com.springsource.insight.plugin.ldap.DirContextSearchCollectionAspectTest

/**
* Copyright (c) 2009-2011 VMware, Inc. All Rights Reserved.
*
* 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.
*/
package com.springsource.insight.plugin.ldap;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.net.URISyntaxException;
import java.text.Format;
import java.text.MessageFormat;
import java.util.Hashtable;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.concurrent.TimeUnit;

import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.naming.ldap.LdapName;

import org.junit.Test;
import org.mockito.Mockito;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.ReflectionUtils.FieldCallback;

import com.springsource.insight.collection.OperationCollectionAspectSupport;
import com.springsource.insight.collection.OperationCollector;
import com.springsource.insight.intercept.operation.Operation;

public class DirContextSearchCollectionAspectTest
        extends LdapOperationCollectionAspectTestSupport {

    public DirContextSearchCollectionAspectTest() {
        super();
    }

    @Test
    public void testResolveScopesCoverage() {
        final Map<String, Integer> knownScopes = new TreeMap<String, Integer>();
        ReflectionUtils.doWithFields(SearchControls.class, new FieldCallback() {
            public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
                int mod = field.getModifiers();
                if (Modifier.isPublic(mod)
                        && Modifier.isStatic(mod)
                        && Modifier.isFinal(mod)) {
                    String name = field.getName();
                    if (name.endsWith("_SCOPE")) {
                        assertNull("Multiple mappings for field=" + name,
                                knownScopes.put(name, Integer.valueOf(field.getInt(null))));
                    }
                }
            }
        });

        assertEquals("Mismatched supported num of scopes",
                knownScopes.size(),
                DirContextSearchCollectionAspect.scopes.size());
        for (Map.Entry<String, Integer> se : knownScopes.entrySet()) {
            String name = se.getKey();
            Integer value = se.getValue();
            SearchControls sc = createSearchControls(value.intValue(), 0L, false, false, 1);
            String expScope = DirContextSearchCollectionAspect.scopes.get(value),
                    actScope = DirContextSearchCollectionAspect.resolveScope(sc);
            assertEquals("Mismatched scope names for " + name, expScope, actScope);
        }
    }

    @Test
    public void testLiveLdapSearches() throws Exception {
        runLiveSearchControlsActions(new DirContextCreator() {
            public InitialDirContext createDirContext() throws NamingException {
                return new InitialDirContext(createEnvironment());
            }
        });
    }

    @Test
    public void testMissingProviderUrlLdapSearches() throws NamingException {
        DirContext context = new TestLdapContext(new Hashtable<Object, Object>());
        try {
            runNonLdapSearchControlsActions(context);
        } finally {
            context.close();
        }
    }

    @Test
    public void testNonLdapProviderUrlSearches() throws NamingException {
        DirContext context = new TestLdapContext(new Hashtable<Object, Object>() {
            private static final long serialVersionUID = 1L;

            {
                put(Context.PROVIDER_URL, "jndi:test/url");
            }
        });

        try {
            runNonLdapSearchControlsActions(context);
        } finally {
            context.close();
        }
    }

    @Override
    public DirContextSearchCollectionAspect getAspect() {
        return DirContextSearchCollectionAspect.aspectOf();
    }

    private void runNonLdapSearchControlsActions(DirContext context) throws NamingException {
        OperationCollectionAspectSupport aspectInstance = getAspect();

        for (final SearchControlsActions action : SearchControlsActions.values()) {
            aspectInstance.setCollector(new OperationCollector() {
                public void enter(Operation operation) {
                    fail(action + ": Unexpected enter call");
                }

                public void exitNormal() {
                    fail(action + ": Unexpected exitNormal call");
                }

                public void exitNormal(Object returnValue) {
                    fail(action + ": Unexpected exitNormal call with value");
                }

                public void exitAbnormal(Throwable throwable) {
                    fail(action + ": Unexpected exitAbnormal call");
                }

                public void exitAndDiscard() {
                    fail(action + ": Unexpected exitAndDiscard call");
                }

                public void exitAndDiscard(Object returnValue) {
                    fail(action + ": Unexpected exitAndDiscard call with value");
                }
            });
            NamingEnumeration<SearchResult> result =
                    action.search(context, "type=test", "blah blah", action);
            try {
                assertNotNull(action + ": no result", result);
                assertFalse(action + ": unexpected result", result.hasMore());
            } finally {
                result.close();
            }
        }
    }

    private void runLiveSearchControlsActions(DirContextCreator creator)
            throws NamingException, URISyntaxException {
        final String DN_PROPNAME = "objectclass", DN_PROPVAL = "person", BASE_DN = "ou=people";
        final String ARGS_FILTER = "(&(" + DN_PROPNAME + "=" + DN_PROPVAL + ")(uid={0})(sn={1}))";
        final Format userSearchFilter = new MessageFormat(ARGS_FILTER);

        for (Map<String, Set<String>> ldifEntry : LDIF_ENTRIES) {
            Set<String> classValues = ldifEntry.get(DN_PROPNAME);
            if (!classValues.contains(DN_PROPVAL)) {
                continue;
            }
            Set<String> values = ldifEntry.get("cn");
            assertNotNull("No CN for " + ldifEntry, values);
            assertEquals("Multiple CB(s) for " + ldifEntry, 1, values.size());

            /*
             * The LDIF is set up in such a way that for person(s), the
             * 'uid' value is same as the 1st name in lowercase, and the
             * 'sn' value is same as the 2nd name
             */
            String cnValue = values.iterator().next().trim();
            int spacePos = cnValue.indexOf(' ');
            String uidValue = cnValue.substring(0, spacePos).toLowerCase();
            String snValue = cnValue.substring(spacePos + 1);
            Object[] filterArgs = {uidValue, snValue};
            String noArgsFilter = userSearchFilter.format(filterArgs);
            for (SearchControlsActions action : SearchControlsActions.values()) {
                final String TEST_NAME = cnValue + "[" + action + "]";
                final String TEST_FILTER = action.isRequiredFilterArgs()
                        ? ARGS_FILTER
                        : noArgsFilter;
                final Object[] SEARCH_ARGS = action.isRequiredFilterArgs()
                        ? filterArgs
                        : null;
                logger.info("Running test: " + TEST_NAME);
                DirContext context = creator.createDirContext();
                Hashtable<?, ?> environment;
                try {
                    // save a copy just in case it changes on context close
                    environment = new Hashtable<Object, Object>(context.getEnvironment());

                    NamingEnumeration<SearchResult> result =
                            action.search(context, BASE_DN, TEST_FILTER, SEARCH_ARGS);
                    assertNotNull(TEST_NAME + ": No result", result);
                    try {
                        if (!checkMatchingSearchResult(result, "cn", cnValue)) {
                            fail(TEST_NAME + ": No match found");
                        }
                    } finally {
                        result.close();
                    }
                } catch (NamingException e) {
                    logger.warn("search(" + TEST_NAME + ")"
                            + " " + e.getClass().getSimpleName()
                            + ": " + e.getMessage(), e);
                    throw e;
                } finally {
                    context.close();
                }

                Operation op = assertContextOperation(TEST_NAME, BASE_DN, environment);
                assertEquals(TEST_NAME + ": Mismatched filter",
                        TEST_FILTER, op.get(LdapDefinitions.LOOKUP_FILTER_ATTR, String.class));
                assertExternalResourceAnalysis(TEST_NAME, op, (String) environment.get(Context.PROVIDER_URL));
                Mockito.reset(spiedOperationCollector); // prepare for next iteration
            }
        }
    }

    static boolean checkMatchingSearchResult(NamingEnumeration<SearchResult> result,
                                             String attrName,
                                             Object expValue)
            throws NamingException {
        while ((result != null) && result.hasMore()) {
            SearchResult sr = result.nextElement();
            Attributes attrs = sr.getAttributes();

            NamingEnumeration<? extends Attribute> attrVals = attrs.getAll();
            try {
                while ((attrVals != null) && attrVals.hasMore()) {
                    Attribute a = attrVals.next();
                    String attrID = a.getID();
                    if (!attrName.equalsIgnoreCase(attrID)) {
                        continue;
                    }

                    Object attrVal = a.get();
                    if (expValue.equals(attrVal)) {
                        return true;
                    }
                }
            } finally {
                if (attrVals != null) {
                    attrVals.close();
                }
            }
        }

        return false;
    }

    static enum SearchControlsActions {
        StringAndArgs {
            @Override
            public NamingEnumeration<SearchResult> search(DirContext context,
                                                          String name, String filterExpr, Object... filterArgs)
                    throws NamingException {
                return context.search(name, filterExpr, filterArgs,
                        createSearchControls());
            }

            @Override
            public boolean isRequiredFilterArgs() {
                return true;
            }
        },
        NameAndArgs {
            @Override
            public NamingEnumeration<SearchResult> search(DirContext context,
                                                          String name, String filterExpr, Object... filterArgs)
                    throws NamingException {
                return context.search(new LdapName(name), filterExpr,
                        filterArgs, createSearchControls());
            }

            @Override
            public boolean isRequiredFilterArgs() {
                return true;
            }
        },
        NameOnly {
            @Override
            public NamingEnumeration<SearchResult> search(
                    DirContext context, String name, String filterExpr, Object... filterArgs)
                    throws NamingException {
                return context.search(new LdapName(name), filterExpr, createSearchControls());
            }

            @Override
            public boolean isRequiredFilterArgs() {
                return false;
            }
        },
        StringOnly {
            @Override
            public NamingEnumeration<SearchResult> search(
                    DirContext context, String name, String filterExpr, Object... filterArgs)
                    throws NamingException {
                return context.search(name, filterExpr, createSearchControls());
            }

            @Override
            public boolean isRequiredFilterArgs() {
                return false;
            }
        };

        public abstract NamingEnumeration<SearchResult> search(
                DirContext context, String name, String filterExpr, Object... filterArgs)
                throws NamingException;

        public abstract boolean isRequiredFilterArgs();

        static SearchControls createSearchControls() {
            SearchControls sc = new SearchControls();
            sc.setSearchScope(SearchControls.SUBTREE_SCOPE);
            sc.setTimeLimit((int) TimeUnit.SECONDS.toMillis(30L));
            return sc;
        }
    }

    static SearchControls createSearchControls(
            int scope, long countLimit, boolean derefFlag, boolean retobjFlag, int timeLimit, String... attrs) {
        SearchControls sc = new SearchControls();
        sc.setCountLimit(countLimit);
        sc.setDerefLinkFlag(derefFlag);
        sc.setReturningObjFlag(retobjFlag);
        sc.setReturningAttributes(attrs);
        sc.setSearchScope(scope);
        return sc;
    }
}
TOP

Related Classes of com.springsource.insight.plugin.ldap.DirContextSearchCollectionAspectTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.