Project

General

Profile

1 7542 tao
/**
2
 *  '$RCSfile$'
3
 *    Purpose: A class that gets Accession Number, check for uniqueness
4
 *             and register it into db
5
 *  Copyright: 2000 Regents of the University of California and the
6
 *             National Center for Ecological Analysis and Synthesis
7
 *    Authors: Jivka Bojilova, Matt Jones
8
 *
9
 *   '$Author: leinfelder $'
10
 *     '$Date: 2011-11-02 20:40:12 -0700 (Wed, 02 Nov 2011) $'
11
 * '$Revision: 6595 $'
12
 *
13
 * This program is free software; you can redistribute it and/or modify
14
 * it under the terms of the GNU General Public License as published by
15
 * the Free Software Foundation; either version 2 of the License, or
16
 * (at your option) any later version.
17
 *
18
 * This program is distributed in the hope that it will be useful,
19
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21
 * GNU General Public License for more details.
22
 *
23
 * You should have received a copy of the GNU General Public License
24
 * along with this program; if not, write to the Free Software
25
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26
 */
27
package edu.ucsb.nceas.metacat.index;
28
29 7550 leinfelder
import java.io.FileInputStream;
30 7562 leinfelder
import java.io.FileNotFoundException;
31 7550 leinfelder
import java.io.InputStream;
32 7602 tao
import java.util.ArrayList;
33 7854 tao
import java.util.Calendar;
34 7602 tao
import java.util.List;
35 7550 leinfelder
36
import org.apache.commons.logging.Log;
37
import org.apache.commons.logging.LogFactory;
38 7811 leinfelder
import org.dataone.service.exceptions.ServiceFailure;
39 7854 tao
import org.dataone.service.types.v1.Event;
40 7550 leinfelder
import org.dataone.service.types.v1.Identifier;
41
import org.dataone.service.types.v1.SystemMetadata;
42
43
import com.hazelcast.core.IMap;
44 7812 leinfelder
import com.hazelcast.core.ISet;
45
import com.hazelcast.core.ItemEvent;
46
import com.hazelcast.core.ItemListener;
47 7550 leinfelder
48 7854 tao
import edu.ucsb.nceas.metacat.common.index.event.IndexEvent;
49
import edu.ucsb.nceas.metacat.index.event.EventlogFactory;
50
51 7812 leinfelder
public class SystemMetadataEventListener implements ItemListener<SystemMetadata> {
52 7550 leinfelder
53
	private static Log log = LogFactory.getLog(SystemMetadataEventListener.class);
54
55
	private SolrIndex solrIndex = null;
56 7811 leinfelder
57 7550 leinfelder
    /**
58 7557 leinfelder
     * Default constructor - caller needs to initialize manually
59
     * @see setSolrIndex()
60
     * @see start()
61 7550 leinfelder
     */
62 7557 leinfelder
    public SystemMetadataEventListener() {
63
    }
64
65
    /**
66
     * Sets the SolrIndex instance and initializes the listener
67
     * @param solrIndex
68
     */
69
    public SystemMetadataEventListener(SolrIndex solrIndex) {
70
    	this.solrIndex = solrIndex;
71 7811 leinfelder
    	try {
72
			start();
73
		} catch (Exception e) {
74
			log.error(e.getMessage(), e);
75
		}
76 7557 leinfelder
    }
77
78
    /**
79
     * Get the SolrIndex that this listener communicates with
80
     * @return a SolrIndex instance that indexes the content being listened to
81
     */
82
    public SolrIndex getSolrIndex() {
83
		return solrIndex;
84
	}
85
86
    /**
87
     * Set the SolrIndex instance that the listener modifies
88
     * @param solrIndex
89
     */
90
	public void setSolrIndex(SolrIndex solrIndex) {
91
		this.solrIndex = solrIndex;
92
	}
93
94
	/**
95
     * Registers this instance as a system metadata map event listener
96 7811 leinfelder
	 * @throws ServiceFailure
97
	 * @throws FileNotFoundException
98 7557 leinfelder
     */
99 7811 leinfelder
    public void start() throws FileNotFoundException, ServiceFailure {
100 7550 leinfelder
101 7811 leinfelder
        // get shared structures and add listener
102
        IMap<Identifier, String> objectPathMap = DistributedMapsFactory.getObjectPathMap();
103 7812 leinfelder
        ISet<SystemMetadata> indexQueue = DistributedMapsFactory.getIndexQueue();
104
        indexQueue.addItemListener(this, true);
105
        log.info("System Metadata size: " + indexQueue.size());
106 7811 leinfelder
        log.info("Object path size:" + objectPathMap.size());
107 7550 leinfelder
    }
108
109
    /**
110 7557 leinfelder
     * Removes this instance as a system metadata map event listener
111 7811 leinfelder
     * @throws ServiceFailure
112
     * @throws FileNotFoundException
113 7550 leinfelder
     */
114 7811 leinfelder
    public void stop() throws FileNotFoundException, ServiceFailure {
115 7550 leinfelder
    	log.info("stopping index entry listener...");
116 7812 leinfelder
    	DistributedMapsFactory.getIndexQueue().removeItemListener(this);
117 7550 leinfelder
    }
118 7602 tao
119
    /**
120
     * Get the obsoletes chain of the specified id. The returned list doesn't include
121
     * the specified id itself. The newer version has the lower index number in the list.
122
     * Empty list will be returned if there is no document to be obsoleted by this id.
123
     * @param id
124
     * @return
125 7811 leinfelder
     * @throws ServiceFailure
126
     * @throws FileNotFoundException
127 7602 tao
     */
128 7811 leinfelder
    private List<String> getObsoletes(String id) throws FileNotFoundException, ServiceFailure {
129 7602 tao
        List<String> obsoletes = new ArrayList<String>();
130
        while (id != null) {
131 7811 leinfelder
            SystemMetadata metadata = DistributedMapsFactory.getSystemMetadata(id);
132 7602 tao
            id = null;//set it to be null in order to stop the while loop if the id can't be assinged to a new value in the following code.
133
            if(metadata != null) {
134
                Identifier identifier = metadata.getObsoletes();
135
                if(identifier != null && identifier.getValue() != null && !identifier.getValue().trim().equals("")) {
136
                    obsoletes.add(identifier.getValue());
137
                    id = identifier.getValue();
138
                }
139
            }
140
        }
141
        return obsoletes;
142
    }
143 7604 tao
144 7550 leinfelder
145 7812 leinfelder
	public void itemRemoved(ItemEvent<SystemMetadata> entryEvent) {
146 7556 leinfelder
		// remove from the index
147 7863 tao
		Identifier pid = entryEvent.getItem().getIdentifier();
148
		if(pid != null) {
149
		    try {
150
	            solrIndex.remove(pid.getValue());
151
	        } catch (Exception e) {
152
	            String error = "SystemMetadataEventListener.itemRemoved - couldn't remove the index for the pid "+pid.getValue()+" since "+e.getMessage();
153
	            SystemMetadata systemMetadata = entryEvent.getItem();
154
	            writeEventLog(systemMetadata, pid, error);
155
	            log.error(error, e);
156
	        }
157 7556 leinfelder
		}
158 7550 leinfelder
159 7863 tao
160 7550 leinfelder
	}
161
162 7812 leinfelder
	public void itemAdded(ItemEvent<SystemMetadata> entryEvent) {
163 7684 tao
	    //System.out.println("===================================calling entryUpdated method ");
164 7854 tao
	    log.info("===================================calling SystemMetadataEventListener.itemAdded method ");
165 7556 leinfelder
		// add to the index
166 7812 leinfelder
		Identifier pid = entryEvent.getItem().getIdentifier();
167 7684 tao
		//System.out.println("===================================update the document "+pid.getValue());
168 7854 tao
		log.info("===================================adding the document "+pid.getValue());
169 7812 leinfelder
		SystemMetadata systemMetadata = entryEvent.getItem();
170 7854 tao
		if(systemMetadata == null) {
171
		    writeEventLog(systemMetadata, pid, "SystemMetadataEventListener.itemAdded -could not get the SystemMetadata");
172
		    return;
173
		}
174 7627 tao
		Identifier obsoletes = systemMetadata.getObsoletes();
175
		List<String> obsoletesChain = null;
176 7811 leinfelder
		if (obsoletes != null) {
177
		    try {
178
				obsoletesChain = getObsoletes(pid.getValue());
179
			} catch (Exception e) {
180 7854 tao
			    String error = "SystemMetadataEventListener.itemAdded -could not look up revision history " + e.getMessage();
181
			    writeEventLog(systemMetadata, pid, error);
182
	            log.error(error, e);
183
	            return;
184 7811 leinfelder
			}
185 7627 tao
		}
186 7811 leinfelder
		String objectPath = null;
187
		try {
188
			objectPath = DistributedMapsFactory.getObjectPathMap().get(pid);
189
		} catch (Exception e) {
190 7854 tao
		    String error = "SystemMetadataEventListener.itemAdded - could not look up object path" + e.getMessage();
191
		    writeEventLog(systemMetadata, pid, error);
192
			log.error(error, e);
193 7863 tao
			return;
194 7811 leinfelder
		}
195 7691 tao
		if(objectPath != null) {
196
		    InputStream data = null;
197
	        try {
198
	            data = new FileInputStream(objectPath);
199
	            solrIndex.update(pid.getValue(), obsoletesChain, systemMetadata, data);
200
	        } catch (Exception e) {
201 7854 tao
	            String error = "SystemMetadataEventListener.itemAdded - could not comit the index into the solr server since " + e.getMessage();
202
	            writeEventLog(systemMetadata, pid, error);
203
	            log.error(error, e);
204 7691 tao
	        }
205 7556 leinfelder
		}
206 7691 tao
207 7550 leinfelder
	}
208 7854 tao
209
	private void writeEventLog(SystemMetadata systemMetadata, Identifier pid, String error) {
210
	    IndexEvent event = new IndexEvent();
211
        event.setIdentifier(pid);
212
	    event.setDate(Calendar.getInstance().getTime());
213
	    String action = null;
214
	    if (systemMetadata == null ) {
215
	        action = Event.CREATE.xmlValue();
216
            event.setAction(Event.CREATE);
217
	    }
218 7877 tao
	    else if(systemMetadata.getArchived() || systemMetadata.getObsoletedBy() != null) {
219 7854 tao
            action = Event.DELETE.xmlValue();
220
            event.setAction(Event.DELETE);
221
        } else {
222
            action = Event.CREATE.xmlValue();
223
            event.setAction(Event.CREATE);
224
        }
225
        event.setDescription("Failed to "+action+"the solr index for the id "+pid.getValue()+" since "+error);
226
        try {
227
            EventlogFactory.createIndexEventLog().write(event);
228
        } catch (Exception ee) {
229
            log.error("SolrIndex.insertToIndex - IndexEventLog can't log the index inserting event :"+ee.getMessage());
230
        }
231
	}
232 7550 leinfelder
233 7542 tao
}