001// --------------------------------------------------------------------------------
002// Copyright 2002-2024 Echo Three, LLC
003//
004// Licensed under the Apache 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.apache.org/licenses/LICENSE-2.0
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
017package com.echothree.model.control.index.server.logic;
018
019import com.echothree.model.control.core.common.ComponentVendors;
020import com.echothree.model.control.core.common.EntityTypes;
021import com.echothree.model.control.core.server.database.EntityInstanceResult;
022import com.echothree.model.control.core.server.database.EntityInstancesByEntityTypeQuery;
023import com.echothree.model.control.core.server.database.EntityInstancesByPartyTypeQuery;
024import com.echothree.model.control.index.common.exception.UnknownIndexNameException;
025import com.echothree.model.control.index.server.control.IndexControl;
026import com.echothree.model.control.party.server.logic.PartyLogic;
027import com.echothree.model.control.queue.common.QueueTypes;
028import com.echothree.model.control.queue.server.control.QueueControl;
029import com.echothree.model.control.queue.server.logic.QueueTypeLogic;
030import com.echothree.model.data.core.server.entity.ComponentVendor;
031import com.echothree.model.data.core.server.entity.EntityType;
032import com.echothree.model.data.core.server.entity.EntityTypeDetail;
033import com.echothree.model.data.index.server.entity.Index;
034import com.echothree.model.data.index.server.entity.IndexStatus;
035import com.echothree.model.data.index.server.entity.IndexType;
036import com.echothree.model.data.index.server.entity.IndexTypeDetail;
037import com.echothree.model.data.party.server.entity.PartyType;
038import com.echothree.model.data.queue.common.pk.QueueTypePK;
039import com.echothree.model.data.queue.server.entity.QueueType;
040import com.echothree.model.data.queue.server.value.QueuedEntityValue;
041import com.echothree.util.common.message.ExecutionErrors;
042import com.echothree.util.server.control.BaseLogic;
043import com.echothree.util.server.message.ExecutionErrorAccumulator;
044import com.echothree.util.server.persistence.Session;
045import java.util.ArrayList;
046import java.util.HashSet;
047import java.util.List;
048import java.util.Set;
049
050public class IndexLogic
051        extends BaseLogic {
052
053    private IndexLogic() {
054        super();
055    }
056
057    private static class IndexLogicHolder {
058        static IndexLogic instance = new IndexLogic();
059    }
060
061    public static IndexLogic getInstance() {
062        return IndexLogicHolder.instance;
063    }
064    
065    public Index getIndexByName(final ExecutionErrorAccumulator eea, final String indexName) {
066        var indexControl = Session.getModelController(IndexControl.class);
067        Index index = indexControl.getIndexByName(indexName);
068
069        if(index == null) {
070            handleExecutionError(UnknownIndexNameException.class, eea, ExecutionErrors.UnknownIndexName.name(), indexName);
071        }
072
073        return index;
074    }
075    
076    private void queueEntityInstances(final Session session, final QueueControl queueControl, final QueueTypePK queueTypePK,
077            final List<EntityInstanceResult> entityInstanceResults) {
078        List<QueuedEntityValue> queuedEntities = new ArrayList<>(entityInstanceResults.size());
079
080        for(var entityInstanceResult : entityInstanceResults) {
081            queuedEntities.add(new QueuedEntityValue(queueTypePK, entityInstanceResult.getEntityInstancePK(), session.START_TIME_LONG));
082        }
083
084        queueControl.createQueuedEntities(queuedEntities);
085    }
086
087    private void queueEntityInstancesByEntityType(final Session session, final ExecutionErrorAccumulator eea, final QueueControl queueControl,
088            final QueueTypePK queueTypePK, final Set<EntityType> queuedEntityTypes, final IndexType indexType) {
089        IndexTypeDetail indexTypeDetail = indexType.getLastDetail();
090        EntityType entityType = indexTypeDetail.getEntityType();
091        EntityTypeDetail entityTypeDetail = entityType.getLastDetail();
092        ComponentVendor componentVendor = entityTypeDetail.getComponentVendor();
093        String entityTypeName = entityTypeDetail.getEntityTypeName();
094        
095        if(entityTypeName.equals(EntityTypes.Party.name())
096                && componentVendor.getLastDetail().getComponentVendorName().equals(ComponentVendors.ECHO_THREE.name())) {
097            // The Party indexes aren't by Language, so we're not worried about de-dupping them.
098            PartyType partyType = PartyLogic.getInstance().getPartyTypeByName(eea, indexTypeDetail.getIndexTypeName());
099
100            if(eea == null || !eea.hasExecutionErrors()) {
101                queueEntityInstances(session, queueControl, queueTypePK, new EntityInstancesByPartyTypeQuery().execute(entityType, partyType));
102            }
103        } else {
104            if(!queuedEntityTypes.contains(entityType)) {
105                queueEntityInstances(session, queueControl, queueTypePK, new EntityInstancesByEntityTypeQuery().execute(entityType));
106
107                queuedEntityTypes.add(entityType);
108            }
109        }
110    }
111    
112    /**
113     * Request that a specific Index or that all Indexes should be reindexed.
114     * @param eea the ExecutionErrorAccumulator that should gather any errors encountered during execution (Required)
115     * @param entityType the EntityType that should be reindexed. If null, all indexes will be reindexed (Optional)
116     */
117    public void reindex(final Session session, final ExecutionErrorAccumulator eea, final EntityType entityType) {
118        QueueType queueType = QueueTypeLogic.getInstance().getQueueTypeByName(eea, QueueTypes.INDEXING.name());
119        
120        if(eea == null || !eea.hasExecutionErrors()) {
121            var indexControl = Session.getModelController(IndexControl.class);
122            var queueControl = Session.getModelController(QueueControl.class);
123            QueueTypePK queueTypePK = queueType.getPrimaryKey();
124            Set<EntityType> queuedEntityTypes = new HashSet<>();
125            List<IndexType> indexTypes = entityType == null ? indexControl.getIndexTypes() : indexControl.getIndexTypesByEntityType(entityType);
126
127            for(var indexType : indexTypes) {
128                List<Index> indexes = indexControl.getIndexesByIndexType(indexType);
129                
130                for(var index : indexes) {
131                    IndexStatus indexStatus = indexControl.getIndexStatusForUpdate(index);
132                    
133                    queueEntityInstancesByEntityType(session, eea, queueControl, queueTypePK, queuedEntityTypes, indexType);
134                    
135                    if(eea.hasExecutionErrors()) {
136                        break;
137                    }
138                    
139                    indexStatus.setCreatedTime(null);
140                }
141                
142                if(eea.hasExecutionErrors()) {
143                    break;
144                }
145            }
146        }
147    }
148
149}