001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *  http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied.  See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 */
019package org.apache.directory.server.core.integ;
020
021
022import org.apache.directory.api.util.FileUtils;
023import org.apache.directory.server.core.annotations.CreateDS;
024import org.apache.directory.server.core.api.DirectoryService;
025import org.apache.directory.server.core.api.changelog.Tag;
026import org.apache.directory.server.core.factory.DSAnnotationProcessor;
027import org.junit.rules.TestRule;
028import org.junit.runner.Description;
029import org.junit.runners.model.Statement;
030import org.slf4j.Logger;
031import org.slf4j.LoggerFactory;
032
033
034/**
035 * A {@link TestRule} for processing {@link CreateDS @CreateDS} annotations.
036 *
037 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
038 */
039public class CreateDsRule implements TestRule
040{
041    private static final Logger LOG = LoggerFactory.getLogger( CreateDsRule.class );
042
043    private DirectoryService directoryService;
044    private CreateDsRule outerCreateDsRule;
045
046
047    public CreateDsRule()
048    {
049    }
050
051
052    public CreateDsRule( CreateDsRule outerCreateDsRule )
053    {
054        this.outerCreateDsRule = outerCreateDsRule;
055    }
056
057
058    public DirectoryService getDirectoryService()
059    {
060        return directoryService == null
061            ? ( outerCreateDsRule == null
062                ? null
063                : outerCreateDsRule.getDirectoryService() )
064            : directoryService;
065    }
066
067
068    @Override
069    public Statement apply( final Statement base, final Description description )
070    {
071        final CreateDS createDs = description.getAnnotation( CreateDS.class );
072        
073        if ( createDs == null )
074        {
075            final DirectoryService directoryService = getDirectoryService();
076            if ( directoryService != null && directoryService.getChangeLog().isEnabled() )
077            {
078                return new Statement()
079                {
080                    @Override
081                    public void evaluate() throws Throwable
082                    {
083                        Tag tag = directoryService.getChangeLog().tag();
084                        DSAnnotationProcessor.applyLdifs( description, directoryService );
085                        LOG.debug( "Tagged change log: {}", tag );
086                        try
087                        {
088                            base.evaluate();
089                        }
090                        finally
091                        {
092                            if ( directoryService.getChangeLog().getCurrentRevision() > tag.getRevision() )
093                            {
094                                LOG.debug( "Reverting to tag: {}", tag );
095                                directoryService.revert( tag.getRevision() );
096                            }
097                            else
098                            {
099                                LOG.debug( "No changes made, nothing to revert" );
100                            }
101                        }
102                    }
103                };
104            }
105            else
106            {
107                LOG.trace( "no @CreateDS and no outer @CreateDS on: {}", description );
108                return base;
109            }
110        }
111        else
112        {
113            return new Statement()
114            {
115                @Override
116                public void evaluate() throws Throwable
117                {
118                    LOG.trace( "Creating directory service" );
119                    directoryService = DSAnnotationProcessor.getDirectoryService( description );
120                    DSAnnotationProcessor.applyLdifs( description, directoryService );
121
122                    try
123                    {
124                        base.evaluate();
125                    }
126                    finally
127                    {
128                        LOG.trace( "Shutting down directory service" );
129                        directoryService.shutdown();
130                        FileUtils.deleteDirectory( directoryService.getInstanceLayout().getInstanceDirectory() );
131                    }
132                }
133            };
134        }
135    }
136}