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     */
019    package org.apache.directory.server.integ.state;
020    
021    
022    import java.io.FileNotFoundException;
023    import java.io.IOException;
024    import java.io.InputStream;
025    import java.io.StringReader;
026    import java.util.ArrayList;
027    import java.util.List;
028    
029    import javax.naming.NamingException;
030    
031    import org.apache.directory.server.core.DirectoryService;
032    import org.apache.directory.server.core.entry.DefaultServerEntry;
033    import org.apache.directory.server.integ.InheritableServerSettings;
034    import org.apache.directory.shared.ldap.ldif.LdifEntry;
035    import org.apache.directory.shared.ldap.ldif.LdifReader;
036    import org.junit.runner.Description;
037    import org.junit.runner.notification.Failure;
038    import org.junit.runner.notification.RunNotifier;
039    import org.junit.runners.model.Statement;
040    import org.junit.runners.model.TestClass;
041    import org.slf4j.Logger;
042    import org.slf4j.LoggerFactory;
043    
044    
045    /**
046     * The abstract state of a test service, containing the default state 
047     * transitions
048     *
049     * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
050     * @version $Rev$, $Date$
051     */
052    public abstract class AbstractState implements TestServerState
053    {
054        /** The class logger */
055        private static final Logger LOG = LoggerFactory.getLogger( AbstractState.class );
056    
057        /** The context for this test */
058        protected final TestServerContext context;
059    
060        /** Error message when we can't destroy the service */
061        private static final String DESTROY_ERR = "Cannot destroy when service is in NonExistant state";
062        private static final String CLEANUP_ERROR = "Cannot cleanup when service is in NonExistant state";
063        private static final String STARTUP_ERR = "Cannot startup when service is in NonExistant state";
064        private static final String SHUTDOWN_ERR = "Cannot shutdown service in NonExistant state.";
065        private static final String REVERT_ERROR = "Cannot revert when service is in NonExistant state";
066    
067        /**
068         * 
069         * Creates a new instance of AbstractState.
070         *
071         * @param context The associated context
072         */
073        protected AbstractState( TestServerContext context )
074        {
075            this.context = context;
076        }
077    
078    
079        /**
080         * Action where an attempt is made to create the service.  Service
081         * creation in this system is the combined instantiation and
082         * configuration which takes place when the factory is used to get
083         * a new instance of the service.
084         *
085         * @param settings The inherited settings
086         * @throws NamingException if we can't create the service
087         */
088        public void create( InheritableServerSettings settings ) throws NamingException
089        {
090        }
091    
092    
093        /**
094         * Action where an attempt is made to destroy the service. This
095         * entails nulling out reference to it and triggering garbage
096         * collection.
097         */
098        public void destroy()
099        {
100            LOG.error( DESTROY_ERR );
101            throw new IllegalStateException( DESTROY_ERR );
102        }
103    
104    
105        /**
106         * Action where an attempt is made to erase the contents of the
107         * working directory used by the service for various files including
108         * partition database files.
109         *
110         * @throws IOException on errors while deleting the working directory
111         */
112        public void cleanup() throws  IOException
113        {
114            LOG.error( CLEANUP_ERROR );
115            throw new IllegalStateException( CLEANUP_ERROR );
116        }
117    
118    
119        /**
120         * Action where an attempt is made to start up the service.
121         *
122         * @throws Exception on failures to start the core directory service
123         */
124        public void startup() throws Exception
125        {
126            LOG.error( STARTUP_ERR );
127            throw new IllegalStateException( STARTUP_ERR );
128        }
129    
130    
131        /**
132         * Action where an attempt is made to shutdown the service.
133         *
134         * @throws Exception on failures to stop the core directory service
135         */
136        public void shutdown() throws Exception
137        {
138            LOG.error( SHUTDOWN_ERR );
139            throw new IllegalStateException( SHUTDOWN_ERR );
140        }
141    
142    
143        /**
144         * Action where an attempt is made to run a test against the service.
145         *
146         * All annotations should have already been processed for
147         * InheritableServerSettings yet they and others can be processed since we have
148         * access to the method annotations below
149         *
150         * @param testClass the class whose test method is to be run
151         * @param statement the test method which is to be run
152         * @param notifier a notifier to report failures to
153         * @param settings the inherited settings and annotations associated with
154         * the test method
155         */
156        public void test( TestClass testClass, Statement statement, RunNotifier notifier, InheritableServerSettings settings )
157        {
158        }
159    
160    
161        /**
162         * Action where an attempt is made to revert the service to it's
163         * initial start up state by using a previous snapshot.
164         *
165         * @throws Exception on failures to revert the state of the core
166         * directory service
167         */
168        public void revert() throws Exception
169        {
170            LOG.error( REVERT_ERROR );
171            throw new IllegalStateException( REVERT_ERROR );
172        }
173    
174        
175        /**
176         * Inject the Ldifs if any
177         *
178         * @param service the instantiated directory service
179         * @param settings the settings containing the ldif
180         */
181        protected void injectLdifs( DirectoryService service, InheritableServerSettings settings ) throws Exception
182        {
183            List<String> ldifs = new ArrayList<String>();
184            List<String> ldifFiles = new ArrayList<String>();
185    
186            // First inject the LDIF files if any
187            ldifFiles = settings.getLdifFiles( ldifFiles );
188            
189            if ( ldifFiles.size() != 0 )
190            {
191                for ( String ldifFile:ldifFiles )
192                {
193                    String className = settings.getParent().getDescription().getDisplayName();
194                    
195                    if ( className == null )
196                    {
197                        String message = "Cannot inject a LDIF file with a null name";
198                        LOG.error( message );
199                        throw new FileNotFoundException( message );
200                    }
201                    
202                    Class<?> clazz = null;
203                    
204                    try
205                    {
206                        clazz = Class.forName( className );
207                    }
208                    catch ( ClassNotFoundException cnfe )
209                    {
210                        String message = "Cannot inject a LDIF file for this class : " + className;
211                        LOG.error( message );
212                        throw new FileNotFoundException( message );
213                    }
214                    
215                    InputStream in = clazz.getResourceAsStream( ldifFile );
216                    
217                    if ( in == null )
218                    {
219                        String message = "Cannot inject a LDIF for the file " + ldifFile;
220                        LOG.error( message );
221                        throw new FileNotFoundException( message );
222                    }
223                    
224                    LdifReader ldifReader = new LdifReader( in );
225                    
226                    for ( LdifEntry entry : ldifReader )
227                    {
228                        service.getAdminSession().add( 
229                            new DefaultServerEntry( service.getRegistries(), entry.getEntry() ) ); 
230                        LOG.debug( "Successfully injected LDIF enry for test {}: {}", settings.getDescription(), entry );
231                    }
232                }
233            }
234            
235            ldifs =  settings.getLdifs( ldifs );
236            
237            if ( ldifs.size() != 0 )
238            {
239                for ( String ldif:ldifs )
240                {
241                    StringReader in = new StringReader( ldif );
242                    LdifReader ldifReader = new LdifReader( in );
243                    
244                    for ( LdifEntry entry : ldifReader )
245                    {
246                        service.getAdminSession().add( 
247                            new DefaultServerEntry( service.getRegistries(), entry.getEntry() ) ); 
248                        LOG.debug( "Successfully injected LDIF enry for test {}: {}", settings.getDescription(), entry );
249                    }
250                }
251            }
252        }
253        
254        
255        protected void testAborted( RunNotifier notifier, Description description, Throwable cause )
256        {
257            notifier.fireTestStarted( description );
258            notifier.fireTestFailure( new Failure( description, cause ) );
259            notifier.fireTestFinished( description );
260        }
261    }