001    /**
002     * Copyright 2005-2011 The Kuali Foundation
003     *
004     * Licensed under the Educational Community License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     * http://www.opensource.org/licenses/ecl2.php
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    package org.kuali.rice.kim.test.service;
017    
018    import org.junit.Test;
019    import org.kuali.rice.core.api.config.property.ConfigContext;
020    import org.kuali.rice.core.api.resourceloader.GlobalResourceLoader;
021    import org.kuali.rice.kew.api.KewApiServiceLocator;
022    import org.kuali.rice.kew.api.document.DocumentStatus;
023    import org.kuali.rice.kew.api.document.DocumentStatusCategory;
024    import org.kuali.rice.kim.impl.identity.IdentityArchiveService;
025    import org.kuali.rice.kim.api.identity.entity.EntityDefault;
026    import org.kuali.rice.kim.api.identity.principal.Principal;
027    import org.kuali.rice.kim.impl.identity.EntityDefaultInfoCacheBo;
028    import org.kuali.rice.kim.service.KIMServiceLocatorInternal;
029    import org.kuali.rice.kim.service.impl.IdentityArchiveServiceImpl;
030    import org.kuali.rice.kim.test.KIMTestCase;
031    import org.kuali.rice.krad.service.KRADServiceLocator;
032    import org.kuali.rice.test.BaselineTestCase;
033    
034    import java.lang.reflect.Field;
035    import java.lang.reflect.Method;
036    import java.util.ArrayList;
037    import java.util.Collections;
038    import java.util.List;
039    import java.util.Map;
040    import java.util.UUID;
041    
042    import static org.junit.Assert.*;
043    
044    /**
045     * Unit test for the IdentityArchiveService
046     *
047     * @author Kuali Rice Team (rice.collab@kuali.org)
048     */
049    @BaselineTestCase.BaselineMode(BaselineTestCase.Mode.NONE)
050    public class IdentityArchiveServiceTest extends KIMTestCase {
051        public static final String KIM_IDENTITY_ARCHIVE_SERVICE = "kimIdentityArchiveService";
052    
053            private IdentityArchiveService identityArchiveService;
054    
055        public static IdentityArchiveService getIdentityArchiveService() {
056            return GlobalResourceLoader.getService(KIM_IDENTITY_ARCHIVE_SERVICE);
057        }
058    
059            public void setUp() throws Exception {
060                    super.setUp();
061                    final Map<String, Object> emptyMap = Collections.emptyMap();
062                    KRADServiceLocator.getBusinessObjectService().deleteMatching(EntityDefaultInfoCacheBo.class, emptyMap);
063                    if (null == identityArchiveService) {
064                            identityArchiveService = getIdentityArchiveService();
065                    }
066            }
067    
068            /**
069             * This tests
070             * <ol><li>trying to retrieve a non-existant {@link EntityDefault}
071             * <li>saving a {@link EntityDefault} and retrieving it.
072             * </ol>
073             * This test is specific to {@link IdentityArchiveServiceImpl}
074             */
075            @Test
076            public void testArchiveFlushesWhenQueueIsFull() throws Exception {
077                    final int maxWriteQueueSize =
078                            Integer.valueOf(ConfigContext.getCurrentContextConfig().getProperty("kim.identityArchiveServiceImpl.maxWriteQueueSize"));
079    
080    
081            //flush the archive service before trying this to make sure no records are sitting waiting for flush
082            identityArchiveService.flushToArchive();
083            // give it a second or 2 to flush
084            log.info("Sleeping, waiting for the flush!");
085            for (int j=2; j >= 0; j--) {
086                Thread.sleep(1000);
087                log.info(String.valueOf(j));
088            }
089            log.info("Done sleeping!");
090    
091                    List<EntityDefault> added = new ArrayList<EntityDefault>();
092    
093                    // exceed the max write queue size to initiate a flush
094                    for (int i=1; i<=(maxWriteQueueSize); i++) {
095                            MinimalKEDIBuilder builder = new MinimalKEDIBuilder("bogusUser" + i);
096                            builder.setEntityId("bogusUser" + i);
097                            EntityDefault bogusUserInfo = builder.build();
098    
099                            EntityDefault retrieved = identityArchiveService.getEntityDefaultFromArchiveByPrincipalId(
100                        builder.getPrincipalId());
101                            assertNull(retrieved);
102                            retrieved = identityArchiveService.getEntityDefaultFromArchiveByPrincipalName(builder.getPrincipalName());
103                            assertNull(retrieved);
104                            retrieved = identityArchiveService.getEntityDefaultFromArchive(builder.getEntityId());
105                            assertNull(retrieved);
106    
107                            identityArchiveService.saveEntityDefaultToArchive(bogusUserInfo);
108                            added.add(bogusUserInfo);
109                    }
110    
111                    // give it a second or 10 to flush
112                    log.info("Sleeping, hoping for a flush to occur!");
113            for (int j=10; j >= 0; j--) {
114                Thread.sleep(1000);
115                log.info(String.valueOf(j));
116            }
117                    log.info("Done sleeping!");
118    
119                    // these should have been flushed by now, test retrieval
120    
121                    for (EntityDefault kedi : added) {
122                            // retrieve it every way we can
123                            EntityDefault retrieved = identityArchiveService.getEntityDefaultFromArchiveByPrincipalId(
124                        kedi.getPrincipals().get(0).getPrincipalId());
125                assertNotNull("no value retrieved for principalId: " + kedi.getPrincipals().get(0).getPrincipalId(), retrieved);
126                            assertTrue(kedi.getPrincipals().get(0).getPrincipalId().equals(retrieved.getPrincipals().get(0).getPrincipalId()));
127                            retrieved = identityArchiveService.getEntityDefaultFromArchiveByPrincipalName(
128                        kedi.getPrincipals().get(0).getPrincipalName());
129                            assertTrue(kedi.getPrincipals().get(0).getPrincipalId().equals(retrieved.getPrincipals().get(0).getPrincipalId()));
130                            retrieved = identityArchiveService.getEntityDefaultFromArchive(kedi.getEntityId());
131                            assertTrue(kedi.getPrincipals().get(0).getPrincipalId().equals(retrieved.getPrincipals().get(0).getPrincipalId()));
132                    }
133            }
134    
135            private static class MinimalKEDIBuilder {
136                    private String entityId;
137                    private String principalId;
138                    private String principalName;
139                    private Boolean active;
140    
141                    public MinimalKEDIBuilder(String name) {
142                            entityId = UUID.randomUUID().toString();
143                            principalId = principalName = name;
144                    }
145    
146                    public EntityDefault build() {
147                            if (entityId == null) entityId = UUID.randomUUID().toString();
148                            if (principalId == null) principalId = UUID.randomUUID().toString();
149                            if (principalName == null) principalName = principalId;
150                            if (active == null) active = true;
151    
152                            Principal.Builder principal = Principal.Builder.create(principalName);
153                            principal.setActive(active);
154                            principal.setEntityId(entityId);
155                            principal.setPrincipalId(principalId);
156    
157                            EntityDefault.Builder kedi = EntityDefault.Builder.create();
158                            kedi.setPrincipals(Collections.singletonList(principal));
159                            kedi.setEntityId(entityId);
160    
161                            return kedi.build();
162                    }
163    
164                    /**
165                     * @return the entityId
166                     */
167                    public String getEntityId() {
168                            return this.entityId;
169                    }
170    
171                    /**
172                     * @param entityId the entityId to set
173                     */
174                    public void setEntityId(String entityId) {
175                            this.entityId = entityId;
176                    }
177    
178                    /**
179                     * @return the principalId
180                     */
181                    public String getPrincipalId() {
182                            return this.principalId;
183                    }
184    
185                    /**
186                     * @param principalId the principalId to set
187                     */
188                    public void setPrincipalId(String principalId) {
189                            this.principalId = principalId;
190                    }
191    
192                    /**
193                     * @return the principalName
194                     */
195                    public String getPrincipalName() {
196                            return this.principalName;
197                    }
198    
199                    /**
200                     * @param principalName the principalName to set
201                     */
202                    public void setPrincipalName(String principalName) {
203                            this.principalName = principalName;
204                    }
205    
206                    /**
207                     * @return the active
208                     */
209                    public Boolean getActive() {
210                            return this.active;
211                    }
212    
213                    /**
214                     * @param active the active to set
215                     */
216                    public void setActive(Boolean active) {
217                            this.active = active;
218                    }
219    
220    
221            }
222    
223    }