Modified: manifoldcf/trunk/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/system/JobResetThread.java URL: http://svn.apache.org/viewvc/manifoldcf/trunk/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/system/JobResetThread.java?rev=1647585&r1=1647584&r2=1647585&view=diff ============================================================================== --- manifoldcf/trunk/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/system/JobResetThread.java (original) +++ manifoldcf/trunk/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/system/JobResetThread.java Tue Dec 23 14:46:43 2014 @@ -56,6 +56,9 @@ public class JobResetThread extends Thre IJobManager jobManager = JobManagerFactory.make(threadContext); IRepositoryConnectionManager connectionManager = RepositoryConnectionManagerFactory.make(threadContext); + INotificationConnectionManager notificationManager = NotificationConnectionManagerFactory.make(threadContext); + INotificationConnectorPool notificationPool = NotificationConnectorPoolFactory.make(threadContext); + // Loop while (true) { @@ -67,6 +70,25 @@ public class JobResetThread extends Thre ArrayList jobStops = new ArrayList(); jobManager.finishJobStops(currentTime,jobStops); + ArrayList jobResumes = new ArrayList(); + jobManager.finishJobResumes(currentTime,jobResumes); + ArrayList jobCompletions = new ArrayList(); + jobManager.resetJobs(currentTime,jobCompletions); + + // If there were any job aborts, we must reprioritize all active documents, since we've done something + // not predicted by the algorithm that assigned those priorities. This is, of course, quite expensive, + // but it cannot be helped (at least, I cannot find a way to avoid it). + // + if (jobStops.size() > 0 || jobResumes.size() > 0) + { + Logging.threads.debug("Job reset thread reprioritizing documents..."); + + ManifoldCF.resetAllDocumentPriorities(threadContext,processID); + + Logging.threads.debug("Job reset thread done reprioritizing documents."); + + } + int k = 0; while (k < jobStops.size()) { @@ -74,10 +96,10 @@ public class JobResetThread extends Thre connectionManager.recordHistory(desc.getConnectionName(), null,connectionManager.ACTIVITY_JOBSTOP,null, desc.getID().toString()+"("+desc.getDescription()+")",null,null,null); + // As a courtesy, call all the notification connections (if any) + doStopNotifications(desc,notificationManager,notificationPool); } - ArrayList jobResumes = new ArrayList(); - jobManager.finishJobResumes(currentTime,jobResumes); k = 0; while (k < jobResumes.size()) { @@ -87,8 +109,6 @@ public class JobResetThread extends Thre desc.getID().toString()+"("+desc.getDescription()+")",null,null,null); } - ArrayList jobCompletions = new ArrayList(); - jobManager.resetJobs(currentTime,jobCompletions); k = 0; while (k < jobCompletions.size()) { @@ -96,23 +116,11 @@ public class JobResetThread extends Thre connectionManager.recordHistory(desc.getConnectionName(), null,connectionManager.ACTIVITY_JOBEND,null, desc.getID().toString()+"("+desc.getDescription()+")",null,null,null); + // As a courtesy, call all the notification connections (if any) + doEndNotifications(desc,notificationManager,notificationPool); } - // If there were any job aborts, we must reprioritize all active documents, since we've done something - // not predicted by the algorithm that assigned those priorities. This is, of course, quite expensive, - // but it cannot be helped (at least, I cannot find a way to avoid it). - // - if (jobStops.size() > 0 || jobResumes.size() > 0) - { - Logging.threads.debug("Job reset thread reprioritizing documents..."); - - ManifoldCF.resetAllDocumentPriorities(threadContext,processID); - - Logging.threads.debug("Job reset thread done reprioritizing documents."); - - } - else - ManifoldCF.sleep(10000L); + ManifoldCF.sleep(10000L); } catch (ManifoldCFException e) { @@ -171,4 +179,82 @@ public class JobResetThread extends Thre } } + protected static void doStopNotifications(IJobDescription jobDescription, INotificationConnectionManager notificationManager, + INotificationConnectorPool notificationPool) + throws ManifoldCFException + { + for (int j = 0; j < jobDescription.countNotifications(); j++) + { + String notificationConnectionName = jobDescription.getNotificationConnectionName(j); + try + { + INotificationConnection c = notificationManager.load(notificationConnectionName); + if (c != null) + { + INotificationConnector connector = notificationPool.grab(c); + if (connector != null) + { + try + { + connector.notifyOfJobStop(jobDescription.getNotificationSpecification(j)); + } + finally + { + notificationPool.release(c,connector); + } + } + } + } + catch (ServiceInterruption e) + { + Logging.connectors.warn("Can't notify right now: "+e.getMessage(),e); + } + catch (ManifoldCFException e) + { + if (e.getErrorCode() == ManifoldCFException.INTERRUPTED) + throw e; + Logging.connectors.warn("Error notifying: "+ e.getMessage(),e); + } + } + } + + protected static void doEndNotifications(IJobDescription jobDescription, INotificationConnectionManager notificationManager, + INotificationConnectorPool notificationPool) + throws ManifoldCFException + { + for (int j = 0; j < jobDescription.countNotifications(); j++) + { + String notificationConnectionName = jobDescription.getNotificationConnectionName(j); + try + { + INotificationConnection c = notificationManager.load(notificationConnectionName); + if (c != null) + { + INotificationConnector connector = notificationPool.grab(c); + if (connector != null) + { + try + { + connector.notifyOfJobEnd(jobDescription.getNotificationSpecification(j)); + } + finally + { + notificationPool.release(c,connector); + } + } + } + } + catch (ServiceInterruption e) + { + Logging.connectors.warn("Can't notify right now: "+e.getMessage(),e); + } + catch (ManifoldCFException e) + { + if (e.getErrorCode() == ManifoldCFException.INTERRUPTED) + throw e; + Logging.connectors.warn("Error notifying: "+ e.getMessage(),e); + } + } + } + }
Modified: manifoldcf/trunk/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/system/ManifoldCF.java URL: http://svn.apache.org/viewvc/manifoldcf/trunk/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/system/ManifoldCF.java?rev=1647585&r1=1647584&r2=1647585&view=diff ============================================================================== --- manifoldcf/trunk/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/system/ManifoldCF.java (original) +++ manifoldcf/trunk/framework/pull-agent/src/main/java/org/apache/manifoldcf/crawler/system/ManifoldCF.java Tue Dec 23 14:46:43 2014 @@ -113,6 +113,15 @@ public class ManifoldCF extends org.apac if (Logging.root != null) Logging.root.warn("Exception tossed on repository connector pool cleanup: "+e.getMessage(),e); } + try + { + NotificationConnectorPoolFactory.make(tc).closeAllConnectors(); + } + catch (ManifoldCFException e) + { + if (Logging.root != null) + Logging.root.warn("Exception tossed on notification connector pool cleanup: "+e.getMessage(),e); + } } /** Create system database using superuser properties from properties.xml. @@ -198,6 +207,7 @@ public class ManifoldCF extends org.apac protected static final String NODE_TRANSFORMATIONCONNECTOR = "transformationconnector"; protected static final String NODE_MAPPINGCONNECTOR = "mappingconnector"; protected static final String NODE_AUTHORITYCONNECTOR = "authorityconnector"; + protected static final String NODE_NOTIFICATIONCONNECTOR = "notificationconnector"; protected static final String NODE_REPOSITORYCONNECTOR = "repositoryconnector"; protected static final String ATTRIBUTE_NAME = "name"; protected static final String ATTRIBUTE_CLASS = "class"; @@ -214,6 +224,7 @@ public class ManifoldCF extends org.apac Map<String,String> desiredTransformationConnectors = new HashMap<String,String>(); Map<String,String> desiredMappingConnectors = new HashMap<String,String>(); Map<String,String> desiredAuthorityConnectors = new HashMap<String,String>(); + Map<String,String> desiredNotificationConnectors = new HashMap<String,String>(); Map<String,String> desiredRepositoryConnectors = new HashMap<String,String>(); Map<String,String> desiredDomains = new HashMap<String,String>(); @@ -253,6 +264,12 @@ public class ManifoldCF extends org.apac String className = cn.getAttributeValue(ATTRIBUTE_CLASS); desiredAuthorityConnectors.put(className,name); } + else if (cn.getType().equals(NODE_NOTIFICATIONCONNECTOR)) + { + String name = cn.getAttributeValue(ATTRIBUTE_NAME); + String className = cn.getAttributeValue(ATTRIBUTE_CLASS); + desiredNotificationConnectors.put(className,name); + } else if (cn.getType().equals(NODE_REPOSITORYCONNECTOR)) { String name = cn.getAttributeValue(ATTRIBUTE_NAME); @@ -407,6 +424,49 @@ public class ManifoldCF extends org.apac System.err.println("Successfully unregistered all authority connectors"); } + // Notification connectors... + { + INotificationConnectorManager mgr = NotificationConnectorManagerFactory.make(tc); + IJobManager jobManager = JobManagerFactory.make(tc); + INotificationConnectionManager connManager = NotificationConnectionManagerFactory.make(tc); + IResultSet classNames = mgr.getConnectors(); + int i = 0; + while (i < classNames.getRowCount()) + { + IResultRow row = classNames.getRow(i++); + String className = (String)row.getValue("classname"); + String description = (String)row.getValue("description"); + if (desiredNotificationConnectors.get(className) == null || !desiredNotificationConnectors.get(className).equals(description)) + { + // Deregistration should be done in a transaction + database.beginTransaction(); + try + { + // Find the connection names that come with this class + String[] connectionNames = connManager.findConnectionsForConnector(className); + // For each connection name, modify the jobs to note that the connector is no longer installed + jobManager.noteNotificationConnectorDeregistration(connectionNames); + // Now that all jobs have been placed into an appropriate state, actually do the deregistration itself. + mgr.unregisterConnector(className); + } + catch (ManifoldCFException e) + { + database.signalRollback(); + throw e; + } + catch (Error e) + { + database.signalRollback(); + throw e; + } + finally + { + database.endTransaction(); + } + } + } + } + // Repository connectors... { IConnectorManager mgr = ConnectorManagerFactory.make(tc); @@ -562,6 +622,41 @@ public class ManifoldCF extends org.apac mgr.registerConnector(name,className); System.err.println("Successfully registered mapping connector '"+className+"'"); } + else if (cn.getType().equals(NODE_NOTIFICATIONCONNECTOR)) + { + String name = cn.getAttributeValue(ATTRIBUTE_NAME); + String className = cn.getAttributeValue(ATTRIBUTE_CLASS); + INotificationConnectorManager mgr = NotificationConnectorManagerFactory.make(tc); + IJobManager jobManager = JobManagerFactory.make(tc); + INotificationConnectionManager connManager = NotificationConnectionManagerFactory.make(tc); + // Deregistration should be done in a transaction + database.beginTransaction(); + try + { + // First, register connector + mgr.registerConnector(name,className); + // Then, signal to all jobs that might depend on this connector that they can switch state + // Find the connection names that come with this class + String[] connectionNames = connManager.findConnectionsForConnector(className); + // For each connection name, modify the jobs to note that the connector is now installed + jobManager.noteNotificationConnectorRegistration(connectionNames); + } + catch (ManifoldCFException e) + { + database.signalRollback(); + throw e; + } + catch (Error e) + { + database.signalRollback(); + throw e; + } + finally + { + database.endTransaction(); + } + System.err.println("Successfully registered notification connector '"+className+"'"); + } else if (cn.getType().equals(NODE_REPOSITORYCONNECTOR)) { String name = cn.getAttributeValue(ATTRIBUTE_NAME); @@ -611,11 +706,15 @@ public class ManifoldCF extends org.apac { IConnectorManager repConnMgr = ConnectorManagerFactory.make(threadcontext); IRepositoryConnectionManager repCon = RepositoryConnectionManagerFactory.make(threadcontext); + INotificationConnectorManager notConnMgr = NotificationConnectorManagerFactory.make(threadcontext); + INotificationConnectionManager notCon = NotificationConnectionManagerFactory.make(threadcontext); IJobManager jobManager = JobManagerFactory.make(threadcontext); IBinManager binManager = BinManagerFactory.make(threadcontext); org.apache.manifoldcf.authorities.system.ManifoldCF.installSystemTables(threadcontext); repConnMgr.install(); repCon.install(); + notConnMgr.install(); + notCon.install(); jobManager.install(); binManager.install(); } @@ -628,10 +727,14 @@ public class ManifoldCF extends org.apac { IConnectorManager repConnMgr = ConnectorManagerFactory.make(threadcontext); IRepositoryConnectionManager repCon = RepositoryConnectionManagerFactory.make(threadcontext); + INotificationConnectorManager notConnMgr = NotificationConnectorManagerFactory.make(threadcontext); + INotificationConnectionManager notCon = NotificationConnectionManagerFactory.make(threadcontext); IJobManager jobManager = JobManagerFactory.make(threadcontext); IBinManager binManager = BinManagerFactory.make(threadcontext); binManager.deinstall(); jobManager.deinstall(); + notCon.deinstall(); + notConnMgr.deinstall(); repCon.deinstall(); repConnMgr.deinstall(); org.apache.manifoldcf.authorities.system.ManifoldCF.deinstallSystemTables(threadcontext); @@ -652,6 +755,7 @@ public class ManifoldCF extends org.apac ITransformationConnectionManager transManager = TransformationConnectionManagerFactory.make(threadContext); IAuthorityGroupManager groupManager = AuthorityGroupManagerFactory.make(threadContext); IRepositoryConnectionManager connManager = RepositoryConnectionManagerFactory.make(threadContext); + INotificationConnectionManager notificationConnManager = NotificationConnectionManagerFactory.make(threadContext); IMappingConnectionManager mappingManager = MappingConnectionManagerFactory.make(threadContext); IAuthorityConnectionManager authManager = AuthorityConnectionManagerFactory.make(threadContext); IJobManager jobManager = JobManagerFactory.make(threadContext); @@ -728,6 +832,11 @@ public class ManifoldCF extends org.apac connManager.exportConfiguration(zos); zos.closeEntry(); + java.util.zip.ZipEntry notConnEntry = new java.util.zip.ZipEntry("notifications"); + zos.putNextEntry(notConnEntry); + notificationConnManager.exportConfiguration(zos); + zos.closeEntry(); + java.util.zip.ZipEntry jobsEntry = new java.util.zip.ZipEntry("jobs"); zos.putNextEntry(jobsEntry); jobManager.exportConfiguration(zos); @@ -787,6 +896,7 @@ public class ManifoldCF extends org.apac ITransformationConnectionManager transManager = TransformationConnectionManagerFactory.make(threadContext); IAuthorityGroupManager groupManager = AuthorityGroupManagerFactory.make(threadContext); IRepositoryConnectionManager connManager = RepositoryConnectionManagerFactory.make(threadContext); + INotificationConnectionManager notificationConnManager = NotificationConnectionManagerFactory.make(threadContext); IMappingConnectionManager mappingManager = MappingConnectionManagerFactory.make(threadContext); IAuthorityConnectionManager authManager = AuthorityConnectionManagerFactory.make(threadContext); IJobManager jobManager = JobManagerFactory.make(threadContext); @@ -845,6 +955,8 @@ public class ManifoldCF extends org.apac authManager.importConfiguration(zis); else if (name.equals("connections")) connManager.importConfiguration(zis); + else if (name.equals("notifications")) + notificationConnManager.importConfiguration(zis); else if (name.equals("jobs")) jobManager.importConfiguration(zis); else @@ -1200,11 +1312,13 @@ public class ManifoldCF extends org.apac protected static final String API_AUTHORIZATIONDOMAINNODE = "authorizationdomain"; protected static final String API_AUTHORITYGROUPNODE = "authoritygroup"; protected static final String API_REPOSITORYCONNECTORNODE = "repositoryconnector"; + protected static final String API_NOTIFICATIONCONNECTORNODE = "notificationconnector"; protected static final String API_OUTPUTCONNECTORNODE = "outputconnector"; protected static final String API_TRANSFORMATIONCONNECTORNODE = "transformationconnector"; protected static final String API_AUTHORITYCONNECTORNODE = "authorityconnector"; protected static final String API_MAPPINGCONNECTORNODE = "mappingconnector"; protected static final String API_REPOSITORYCONNECTIONNODE = "repositoryconnection"; + protected static final String API_NOTIFICATIONCONNECTIONNODE = "notificationconnection"; protected static final String API_OUTPUTCONNECTIONNODE = "outputconnection"; protected static final String API_TRANSFORMATIONCONNECTIONNODE = "transformationconnection"; protected static final String API_AUTHORITYCONNECTIONNODE = "authorityconnection"; @@ -1524,6 +1638,47 @@ public class ManifoldCF extends org.apac return READRESULT_FOUND; } + /** Read a notification connection status */ + protected static int apiReadNotificationConnectionStatus(IThreadContext tc, Configuration output, String connectionName) + throws ManifoldCFException + { + try + { + INotificationConnectorPool notificationConnectorPool = NotificationConnectorPoolFactory.make(tc); + INotificationConnectionManager connectionManager = NotificationConnectionManagerFactory.make(tc); + INotificationConnection connection = connectionManager.load(connectionName); + if (connection == null) + { + createErrorNode(output,"Connection '"+connectionName+"' does not exist"); + return READRESULT_NOTFOUND; + } + + String results; + // Grab a connection handle, and call the test method + INotificationConnector connector = notificationConnectorPool.grab(connection); + try + { + results = connector.check(); + } + catch (ManifoldCFException e) + { + results = e.getMessage(); + } + finally + { + notificationConnectorPool.release(connection,connector); + } + + ConfigurationNode response = new ConfigurationNode(API_CHECKRESULTNODE); + response.setValue(results); + output.addChild(output.getChildCount(),response); + } + catch (ManifoldCFException e) + { + createErrorNode(output,e); + } + return READRESULT_FOUND; + } /** Read an output connection's info */ protected static int apiReadOutputConnectionInfo(IThreadContext tc, Configuration output, String connectionName, String command) @@ -1624,6 +1779,39 @@ public class ManifoldCF extends org.apac return READRESULT_FOUND; } + /** Read a notification connection's info */ + protected static int apiReadNotificationConnectionInfo(IThreadContext tc, Configuration output, String connectionName, String command) + throws ManifoldCFException + { + try + { + INotificationConnectorPool notificationConnectorPool = NotificationConnectorPoolFactory.make(tc); + INotificationConnectionManager connectionManager = NotificationConnectionManagerFactory.make(tc); + INotificationConnection connection = connectionManager.load(connectionName); + if (connection == null) + { + createErrorNode(output,"Connection '"+connectionName+"' does not exist"); + return READRESULT_NOTFOUND; + } + + // Grab a connection handle, and call the test method + INotificationConnector connector = notificationConnectorPool.grab(connection); + try + { + return connector.requestInfo(output,command)?READRESULT_FOUND:READRESULT_NOTFOUND; + } + finally + { + notificationConnectorPool.release(connection,connector); + } + } + catch (ManifoldCFException e) + { + createErrorNode(output,e); + } + return READRESULT_FOUND; + } + /** Get api job statuses */ protected static int apiReadJobStatuses(IThreadContext tc, Configuration output, Map<String,List<String>> queryParameters) throws ManifoldCFException @@ -2042,6 +2230,57 @@ public class ManifoldCF extends org.apac return READRESULT_FOUND; } + /** Get notification connections */ + protected static int apiReadNotificationConnections(IThreadContext tc, Configuration output) + throws ManifoldCFException + { + try + { + INotificationConnectionManager connManager = NotificationConnectionManagerFactory.make(tc); + INotificationConnection[] connections = connManager.getAllConnections(); + int i = 0; + while (i < connections.length) + { + ConfigurationNode connectionNode = new ConfigurationNode(API_NOTIFICATIONCONNECTIONNODE); + formatNotificationConnection(connectionNode,connections[i++]); + output.addChild(output.getChildCount(),connectionNode); + } + } + catch (ManifoldCFException e) + { + createErrorNode(output,e); + } + return READRESULT_FOUND; + } + + /** Read notification connection */ + protected static int apiReadNotificationConnection(IThreadContext tc, Configuration output, String connectionName) + throws ManifoldCFException + { + try + { + INotificationConnectionManager connectionManager = NotificationConnectionManagerFactory.make(tc); + INotificationConnection connection = connectionManager.load(connectionName); + if (connection != null) + { + // Fill the return object with job information + ConfigurationNode connectionNode = new ConfigurationNode(API_NOTIFICATIONCONNECTIONNODE); + formatNotificationConnection(connectionNode,connection); + output.addChild(output.getChildCount(),connectionNode); + } + else + { + createErrorNode(output,"Notification connection '"+connectionName+"' does not exist"); + return READRESULT_NOTFOUND; + } + } + catch (ManifoldCFException e) + { + createErrorNode(output,e); + } + return READRESULT_FOUND; + } + /** List output connectors */ protected static int apiReadOutputConnectors(IThreadContext tc, Configuration output) throws ManifoldCFException @@ -2265,6 +2504,42 @@ public class ManifoldCF extends org.apac return READRESULT_FOUND; } + /** List notification connectors */ + protected static int apiReadNotificationConnectors(IThreadContext tc, Configuration output) + throws ManifoldCFException + { + // List registered notification connectors + try + { + IConnectorManager manager = ConnectorManagerFactory.make(tc); + IResultSet resultSet = manager.getConnectors(); + int j = 0; + while (j < resultSet.getRowCount()) + { + IResultRow row = resultSet.getRow(j++); + ConfigurationNode child = new ConfigurationNode(API_NOTIFICATIONCONNECTORNODE); + String description = (String)row.getValue("description"); + String className = (String)row.getValue("classname"); + ConfigurationNode node; + if (description != null) + { + node = new ConfigurationNode(CONNECTORNODE_DESCRIPTION); + node.setValue(description); + child.addChild(child.getChildCount(),node); + } + node = new ConfigurationNode(CONNECTORNODE_CLASSNAME); + node.setValue(className); + child.addChild(child.getChildCount(),node); + + output.addChild(output.getChildCount(),child); + } + } + catch (ManifoldCFException e) + { + createErrorNode(output,e); + } + return READRESULT_FOUND; + } protected final static Map<String,Integer> docState; static @@ -2954,6 +3229,10 @@ public class ManifoldCF extends org.apac { return apiReadRepositoryConnectionStatus(tc,output,connectionName); } + else if (connectionType.equals("notificationconnections")) + { + return apiReadNotificationConnectionStatus(tc,output,connectionName); + } else { createErrorNode(output,"Unknown connection type '"+connectionType+"'."); @@ -2993,6 +3272,10 @@ public class ManifoldCF extends org.apac { return apiReadRepositoryConnectionInfo(tc,output,connectionName,command); } + else if (connectionType.equals("notificationconnections")) + { + return apiReadNotificationConnectionInfo(tc,output,connectionName,command); + } else { createErrorNode(output,"Unknown connection type '"+connectionType+"'."); @@ -3071,6 +3354,15 @@ public class ManifoldCF extends org.apac String connectionName = decodeAPIPathElement(path.substring("repositoryconnections/".length())); return apiReadRepositoryConnection(tc,output,connectionName); } + else if (path.equals("notificationconnections")) + { + return apiReadNotificationConnections(tc,output); + } + else if (path.startsWith("notificationconnections/")) + { + String connectionName = decodeAPIPathElement(path.substring("notificationconnections/".length())); + return apiReadNotificationConnection(tc,output,connectionName); + } else if (path.equals("outputconnectors")) { return apiReadOutputConnectors(tc,output); @@ -3091,6 +3383,10 @@ public class ManifoldCF extends org.apac { return apiReadRepositoryConnectors(tc,output); } + else if (path.equals("notificationconnectors")) + { + return apiReadNotificationConnectors(tc,output); + } else if (path.equals("authorizationdomains")) { return apiReadAuthorizationDomains(tc,output); @@ -3546,6 +3842,41 @@ public class ManifoldCF extends org.apac return WRITERESULT_FOUND; } + /** Write notification connection. + */ + protected static int apiWriteNotificationConnection(IThreadContext tc, Configuration output, Configuration input, String connectionName) + throws ManifoldCFException + { + ConfigurationNode connectionNode = findConfigurationNode(input,API_NOTIFICATIONCONNECTIONNODE); + if (connectionNode == null) + throw new ManifoldCFException("Input argument must have '"+API_NOTIFICATIONCONNECTIONNODE+"' field"); + + // Turn the configuration node into an NotificationConnection + org.apache.manifoldcf.crawler.notification.NotificationConnection notificationConnection = new org.apache.manifoldcf.crawler.notification.NotificationConnection(); + processNotificationConnection(notificationConnection,connectionNode); + + if (notificationConnection.getName() == null) + notificationConnection.setName(connectionName); + else + { + if (!notificationConnection.getName().equals(connectionName)) + throw new ManifoldCFException("Connection name in path and in object must agree"); + } + + try + { + // Save the connection. + INotificationConnectionManager connectionManager = NotificationConnectionManagerFactory.make(tc); + if (connectionManager.save(notificationConnection)) + return WRITERESULT_CREATED; + } + catch (ManifoldCFException e) + { + createErrorNode(output,e); + } + return WRITERESULT_FOUND; + } + /** Reset output connection (reset version of all recorded documents). */ protected static int apiWriteClearVersionsOutputConnection(IThreadContext tc, Configuration output, String connectionName) @@ -3665,6 +3996,11 @@ public class ManifoldCF extends org.apac String connectionName = decodeAPIPathElement(path.substring("repositoryconnections/".length())); return apiWriteRepositoryConnection(tc,output,input,connectionName); } + else if (path.startsWith("notificationconnections/")) + { + String connectionName = decodeAPIPathElement(path.substring("notificationconnections/".length())); + return apiWriteNotificationConnection(tc,output,input,connectionName); + } else if (path.startsWith("clearhistory/")) { int firstSeparator = "clearhistory/".length(); @@ -3802,6 +4138,23 @@ public class ManifoldCF extends org.apac } return DELETERESULT_FOUND; } + + /** Delete notification connection. + */ + protected static int apiDeleteNotificationConnection(IThreadContext tc, Configuration output, String connectionName) + throws ManifoldCFException + { + try + { + INotificationConnectionManager connectionManager = NotificationConnectionManagerFactory.make(tc); + connectionManager.delete(connectionName); + } + catch (ManifoldCFException e) + { + createErrorNode(output,e); + } + return DELETERESULT_FOUND; + } /** Execute specified delete command. *@param tc is the thread context. @@ -3837,6 +4190,11 @@ public class ManifoldCF extends org.apac String connectionName = decodeAPIPathElement(path.substring("repositoryconnections/".length())); return apiDeleteRepositoryConnection(tc,output,connectionName); } + else if (path.startsWith("notificationconnections/")) + { + String connectionName = decodeAPIPathElement(path.substring("notificationconnections/".length())); + return apiDeleteNotificationConnection(tc,output,connectionName); + } else { createErrorNode(output,"Unrecognized resource."); @@ -3882,6 +4240,7 @@ public class ManifoldCF extends org.apac protected static final String JOBNODE_STAGECONNECTIONNAME = "stage_connectionname"; protected static final String JOBNODE_STAGEDESCRIPTION = "stage_description"; protected static final String JOBNODE_STAGESPECIFICATION = "stage_specification"; + protected static final String JOBNODE_NOTIFICATIONSTAGE = "notificationstage"; /** Convert a node into a job description. *@param jobDescription is the job to be filled in. @@ -3947,6 +4306,39 @@ public class ManifoldCF extends org.apac pipelineStages.put(stageID,new PipelineStage(stagePrerequisite,stageIsOutput.equals("true"), stageConnectionName,stageDescription,stageSpecification)); } + else if (childType.equals(JOBNODE_NOTIFICATIONSTAGE)) + { + String stageConnectionName = null; + String stageDescription = null; + ConfigurationNode stageSpecification = null; + for (int q = 0; q < child.getChildCount(); q++) + { + ConfigurationNode cn = child.findChild(q); + if (cn.getType().equals(JOBNODE_STAGECONNECTIONNAME)) + stageConnectionName = cn.getValue(); + else if (cn.getType().equals(JOBNODE_STAGEDESCRIPTION)) + stageDescription = cn.getValue(); + else if (cn.getType().equals(JOBNODE_STAGESPECIFICATION)) + { + stageSpecification = cn; + } + else + throw new ManifoldCFException("Found an unexpected node type: '"+cn.getType()+"'"); + } + if (stageConnectionName == null) + throw new ManifoldCFException("Missing required field: '"+JOBNODE_STAGECONNECTIONNAME+"'"); + Specification os = jobDescription.addNotification(stageConnectionName,stageDescription); + os.clearChildren(); + if (stageSpecification != null) + { + for (int j = 0; j < stageSpecification.getChildCount(); j++) + { + ConfigurationNode cn = stageSpecification.findChild(j); + os.addChild(os.getChildCount(),new SpecificationNode(cn)); + } + } + + } else if (childType.equals(JOBNODE_DOCUMENTSPECIFICATION)) { // Get the job's document specification, clear out the children, and copy new ones from the child. @@ -4149,7 +4541,7 @@ public class ManifoldCF extends org.apac } } - + /** Convert a job description into a ConfigurationNode. *@param jobNode is the node to be filled in. *@param job is the job description. @@ -4231,6 +4623,34 @@ public class ManifoldCF extends org.apac jobNode.addChild(jobNode.getChildCount(),child); } + for (int j = 0; j < job.countNotifications(); j++) + { + child = new ConfigurationNode(JOBNODE_NOTIFICATIONSTAGE); + ConfigurationNode stage; + stage = new ConfigurationNode(JOBNODE_STAGEID); + stage.setValue(Integer.toString(j)); + child.addChild(child.getChildCount(),stage); + stage = new ConfigurationNode(JOBNODE_STAGECONNECTIONNAME); + stage.setValue(job.getNotificationConnectionName(j)); + child.addChild(child.getChildCount(),stage); + String description = job.getNotificationDescription(j); + if (description != null) + { + stage = new ConfigurationNode(JOBNODE_STAGEDESCRIPTION); + stage.setValue(description); + child.addChild(child.getChildCount(),stage); + } + Specification spec = job.getNotificationSpecification(j); + stage = new ConfigurationNode(JOBNODE_STAGESPECIFICATION); + for (int k = 0; k < spec.getChildCount(); k++) + { + ConfigurationNode cn = spec.getChild(k); + stage.addChild(stage.getChildCount(),cn); + } + child.addChild(child.getChildCount(),stage); + jobNode.addChild(jobNode.getChildCount(),child); + } + // Start mode child = new ConfigurationNode(JOBNODE_STARTMODE); child.setValue(startModeMap(job.getStartMethod())); @@ -5362,6 +5782,118 @@ public class ManifoldCF extends org.apac } + // Notification connection node handling + + /** Convert input hierarchy into a NotificationConnection object. + */ + protected static void processNotificationConnection(org.apache.manifoldcf.crawler.notification.NotificationConnection connection, ConfigurationNode connectionNode) + throws ManifoldCFException + { + // Walk through the node's children + int i = 0; + while (i < connectionNode.getChildCount()) + { + ConfigurationNode child = connectionNode.findChild(i++); + String childType = child.getType(); + if (childType.equals(CONNECTIONNODE_ISNEW)) + { + if (child.getValue() == null) + throw new ManifoldCFException("Connection isnew node requires a value"); + connection.setIsNew(child.getValue().equals("true")); + } + else if (childType.equals(CONNECTIONNODE_NAME)) + { + if (child.getValue() == null) + throw new ManifoldCFException("Connection name node requires a value"); + connection.setName(child.getValue()); + } + else if (childType.equals(CONNECTIONNODE_CLASSNAME)) + { + if (child.getValue() == null) + throw new ManifoldCFException("Connection classname node requires a value"); + connection.setClassName(child.getValue()); + } + else if (childType.equals(CONNECTIONNODE_MAXCONNECTIONS)) + { + if (child.getValue() == null) + throw new ManifoldCFException("Connection maxconnections node requires a value"); + try + { + connection.setMaxConnections(Integer.parseInt(child.getValue())); + } + catch (NumberFormatException e) + { + throw new ManifoldCFException("Error parsing max connections: "+e.getMessage(),e); + } + } + else if (childType.equals(CONNECTIONNODE_DESCRIPTION)) + { + if (child.getValue() == null) + throw new ManifoldCFException("Connection description node requires a value"); + connection.setDescription(child.getValue()); + } + else if (childType.equals(CONNECTIONNODE_CONFIGURATION)) + { + // Get the connection's configuration, clear out the children, and copy new ones from the child. + ConfigParams cp = connection.getConfigParams(); + cp.clearChildren(); + int j = 0; + while (j < child.getChildCount()) + { + ConfigurationNode cn = child.findChild(j++); + cp.addChild(cp.getChildCount(),new ConfigNode(cn)); + } + } + else + throw new ManifoldCFException("Unrecognized notification connection field: '"+childType+"'"); + } + if (connection.getClassName() == null) + throw new ManifoldCFException("Missing connection field: '"+CONNECTIONNODE_CLASSNAME+"'"); + + } + + /** Format a notification connection. + */ + protected static void formatNotificationConnection(ConfigurationNode connectionNode, INotificationConnection connection) + { + ConfigurationNode child; + int j; + + child = new ConfigurationNode(CONNECTIONNODE_ISNEW); + child.setValue(connection.getIsNew()?"true":"false"); + connectionNode.addChild(connectionNode.getChildCount(),child); + + child = new ConfigurationNode(CONNECTIONNODE_NAME); + child.setValue(connection.getName()); + connectionNode.addChild(connectionNode.getChildCount(),child); + + child = new ConfigurationNode(CONNECTIONNODE_CLASSNAME); + child.setValue(connection.getClassName()); + connectionNode.addChild(connectionNode.getChildCount(),child); + + child = new ConfigurationNode(CONNECTIONNODE_MAXCONNECTIONS); + child.setValue(Integer.toString(connection.getMaxConnections())); + connectionNode.addChild(connectionNode.getChildCount(),child); + + if (connection.getDescription() != null) + { + child = new ConfigurationNode(CONNECTIONNODE_DESCRIPTION); + child.setValue(connection.getDescription()); + connectionNode.addChild(connectionNode.getChildCount(),child); + } + + ConfigParams cp = connection.getConfigParams(); + child = new ConfigurationNode(CONNECTIONNODE_CONFIGURATION); + j = 0; + while (j < cp.getChildCount()) + { + ConfigurationNode cn = cp.findChild(j++); + child.addChild(child.getChildCount(),cn); + } + connectionNode.addChild(connectionNode.getChildCount(),child); + + } + // End of connection API code } Modified: manifoldcf/trunk/framework/ui-core/src/main/native2ascii/org/apache/manifoldcf/ui/i18n/common_en_US.properties URL: http://svn.apache.org/viewvc/manifoldcf/trunk/framework/ui-core/src/main/native2ascii/org/apache/manifoldcf/ui/i18n/common_en_US.properties?rev=1647585&r1=1647584&r2=1647585&view=diff ============================================================================== --- manifoldcf/trunk/framework/ui-core/src/main/native2ascii/org/apache/manifoldcf/ui/i18n/common_en_US.properties (original) +++ manifoldcf/trunk/framework/ui-core/src/main/native2ascii/org/apache/manifoldcf/ui/i18n/common_en_US.properties Tue Dec 23 14:46:43 2014 @@ -162,7 +162,7 @@ edittransformation.ApacheManifoldCFEditT edittransformation.Name=Name edittransformation.Type=Type edittransformation.Throttling=Throttling -edittransformation.EditATransformationConnection=Edit a Transformation Connection +edittransformation.EditATransformationConnection=Edit a transformation connection edittransformation.EditTransformationConnection2=Edit Transformation Connection edittransformation.ConnectionTypeColon=Connection type: edittransformation.Continue=Continue @@ -992,3 +992,78 @@ viewmapper.DeleteThisMappingConnection=D viewmapper.qmark=? viewmapper.PrerequisiteUserMappingColon=Prerequisite user mapping: viewmapper.NoPrerequisites=No prerequisites + +edittransformation.NoTransformationConnectorsRegistered=No transformation connectors registered +editoutput.NoOutputConnectorsRegistered=No output connectors registered +editnotification.NoNotificationConnectorsRegistered=No notification connectors registered +editnotification.Name=Name +editnotification.Type=Type +editnotification.Throttling=Throttling +editnotification.ApacheManifoldCFEditNotificationConnection=Apache ManifoldCF: Edit Notification Connection +editnotification.ConnectionMustHaveAName=Connection must have a name +editnotification.TheMaximumNumberOfConnectionsMustBeAValidInteger=The maximum number of connections must be a valid integer +editnotification.EditNotificationConnection2=Edit Notification Connection +editnotification.EditNotificationConnection=Edit notification connection +editnotification.EditANotificationConnection=Edit a notification connection +editnotification.tab=tab +editnotification.NameColon=Name: +editnotification.DescriptionColon=Description: +editnotification.TypeColon=Type: +editnotification.UNREGISTERED=UNREGISTERED +editnotification.ConnectionTypeColon=Connection type: +editnotification.MaxConnectionsColon=Max connections: +editnotification.Save=Save +editnotification.Continue=Continue +editnotification.SaveThisNotificationConnection=Save this notification connection +editnotification.ContinueToNextPage=Continue to next page +editnotification.Cancel=Cancel +editnotification.CancelNotificationConnectionEditing=Cancel notification connection editing + +listnotifications.ApacheManifoldCFListNotificationConnections=Apache ManifoldCF: List Notification Connections +listnotifications.DeleteNotificationConnection=Delete notification connection +listnotifications.ListOfNotificationConnections=List of Notification Connections +listnotifications.Name=Name +listnotifications.Description=Description +listnotifications.ConnectionType=Connection Type +listnotifications.Max=Max +listnotifications.uninstalled=(uninstalled) +listnotifications.View=View +listnotifications.Edit=Edit +listnotifications.Delete=Delete +listnotifications.AddANotificationConnection=Add a notification connection +listnotifications.AddaNewNotificationConnection=Add a new notification connection +listnotifications.DeleteNotificationConnection=Delete notification connection + +viewnotification.ApacheManifoldCFViewNotificationConnectionStatus=Apache ManifoldCF: View Notification Connection Status +viewnotification.Deletenotificationconnection=Delete notification connection +viewnotification.qmark=? +viewnotification.ViewNotificationConnectionStatus=View Notification Connection Status +viewnotification.uninstalled=(uninstalled) +viewnotification.Connectorisnotinstalled=Connector is not installed +viewnotification.Threwexception=Threw exception: +viewnotification.NameColon=Name: +viewnotification.DescriptionColon=Description: +viewnotification.ConnectionTypeColon=Connection type: +viewnotification.MaxConnectionsColon=Max connections: +viewnotification.ConnectionStatusColon=Connection status: +viewnotification.Refresh=Refresh +viewnotification.EditThisNotificationConnection=Edit this notification connection +viewnotification.Edit=Edit +viewnotification.DeleteThisNotificationConnection=Delete this notification connection +viewnotification.Delete=Delete + +navigation.Listnotificationconnections=List notification connections +navigation.ListNotificationConnections=List Notification Connections + +editjob.SelectANotificationConnectionName=Select a notification connection name +editjob.NotificationsColon=Notifications: +editjob.NotificationDescription=Description +editjob.NotificationConnectionName=Connection name +editjob.Deletenotification=Delete notification +editjob.AddNotification=Add notification +editjob.AddANotification=Add a notification + +viewjob.NotificationsColon=Notifications: +viewjob.NotificationDescription=Description +viewjob.NotificationConnectionName=Connection name +viewjob.NoNotificationConnections=No notification connections \ No newline at end of file Modified: manifoldcf/trunk/framework/ui-core/src/main/native2ascii/org/apache/manifoldcf/ui/i18n/common_ja_JP.properties URL: http://svn.apache.org/viewvc/manifoldcf/trunk/framework/ui-core/src/main/native2ascii/org/apache/manifoldcf/ui/i18n/common_ja_JP.properties?rev=1647585&r1=1647584&r2=1647585&view=diff ============================================================================== --- manifoldcf/trunk/framework/ui-core/src/main/native2ascii/org/apache/manifoldcf/ui/i18n/common_ja_JP.properties (original) +++ manifoldcf/trunk/framework/ui-core/src/main/native2ascii/org/apache/manifoldcf/ui/i18n/common_ja_JP.properties Tue Dec 23 14:46:43 2014 @@ -993,3 +993,78 @@ viewmapper.DeleteThisMappingConnection=� viewmapper.qmark=ï¼ viewmapper.PrerequisiteUserMappingColon=åæã¦ã¼ã¶ã¼ãããã³ã°ï¼ viewmapper.NoPrerequisites=æ¡ä»¶ç¡ã + +edittransformation.NoTransformationConnectorsRegistered=No transformation connectors registered +editoutput.NoOutputConnectorsRegistered=No output connectors registered +editnotification.NoNotificationConnectorsRegistered=No notification connectors registered +editnotification.Name=Name +editnotification.Type=Type +editnotification.Throttling=Throttling +editnotification.ApacheManifoldCFEditNotificationConnection=Apache ManifoldCF: Edit Notification Connection +editnotification.ConnectionMustHaveAName=Connection must have a name +editnotification.TheMaximumNumberOfConnectionsMustBeAValidInteger=The maximum number of connections must be a valid integer +editnotification.EditNotificationConnection2=Edit Notification Connection +editnotification.EditNotificationConnection=Edit notification connection +editnotification.EditANotificationConnection=Edit a notification connection +editnotification.tab=tab +editnotification.NameColon=Name: +editnotification.DescriptionColon=Description: +editnotification.TypeColon=Type: +editnotification.UNREGISTERED=UNREGISTERED +editnotification.ConnectionTypeColon=Connection type: +editnotification.MaxConnectionsColon=Max connections: +editnotification.Save=Save +editnotification.Continue=Continue +editnotification.SaveThisNotificationConnection=Save this notification connection +editnotification.ContinueToNextPage=Continue to next page +editnotification.Cancel=Cancel +editnotification.CancelNotificationConnectionEditing=Cancel notification connection editing + +listnotifications.ApacheManifoldCFListNotificationConnections=Apache ManifoldCF: List Notification Connections +listnotifications.DeleteNotificationConnection=Delete notification connection +listnotifications.ListOfNotificationConnections=List of Notification Connections +listnotifications.Name=Name +listnotifications.Description=Description +listnotifications.ConnectionType=Connection Type +listnotifications.Max=Max +listnotifications.uninstalled=(uninstalled) +listnotifications.View=View +listnotifications.Edit=Edit +listnotifications.Delete=Delete +listnotifications.AddANotificationConnection=Add a notification connection +listnotifications.AddaNewNotificationConnection=Add a new notification connection +listnotifications.DeleteNotificationConnection=Delete notification connection + +viewnotification.ApacheManifoldCFViewNotificationConnectionStatus=Apache ManifoldCF: View Notification Connection Status +viewnotification.Deletenotificationconnection=Delete notification connection +viewnotification.qmark=? +viewnotification.ViewNotificationConnectionStatus=View Notification Connection Status +viewnotification.uninstalled=(uninstalled) +viewnotification.Connectorisnotinstalled=Connector is not installed +viewnotification.Threwexception=Threw exception: +viewnotification.NameColon=Name: +viewnotification.DescriptionColon=Description: +viewnotification.ConnectionTypeColon=Connection type: +viewnotification.MaxConnectionsColon=Max connections: +viewnotification.ConnectionStatusColon=Connection status: +viewnotification.Refresh=Refresh +viewnotification.EditThisNotificationConnection=Edit this notification connection +viewnotification.Edit=Edit +viewnotification.DeleteThisNotificationConnection=Delete this notification connection +viewnotification.Delete=Delete + +navigation.Listnotificationconnections=List notification connections +navigation.ListNotificationConnections=List Notification Connections + +editjob.SelectANotificationConnectionName=Select a notification connection name +editjob.NotificationsColon=Notifications: +editjob.NotificationDescription=Description +editjob.NotificationConnectionName=Connection name +editjob.Deletenotification=Delete notification +editjob.AddNotification=Add notification +editjob.AddANotification=Add a notification + +viewjob.NotificationsColon=Notifications: +viewjob.NotificationDescription=Description +viewjob.NotificationConnectionName=Connection name +viewjob.NoNotificationConnections=No notification connections Modified: manifoldcf/trunk/framework/ui-core/src/main/native2ascii/org/apache/manifoldcf/ui/i18n/common_zh_CN.properties URL: http://svn.apache.org/viewvc/manifoldcf/trunk/framework/ui-core/src/main/native2ascii/org/apache/manifoldcf/ui/i18n/common_zh_CN.properties?rev=1647585&r1=1647584&r2=1647585&view=diff ============================================================================== --- manifoldcf/trunk/framework/ui-core/src/main/native2ascii/org/apache/manifoldcf/ui/i18n/common_zh_CN.properties (original) +++ manifoldcf/trunk/framework/ui-core/src/main/native2ascii/org/apache/manifoldcf/ui/i18n/common_zh_CN.properties Tue Dec 23 14:46:43 2014 @@ -993,3 +993,78 @@ viewmapper.DeleteThisMappingConnection=� viewmapper.qmark=? viewmapper.PrerequisiteUserMappingColon=ç¨æ·æ å°åææ¡ä»¶: viewmapper.NoPrerequisites=æ åææ¡ä»¶ + +edittransformation.NoTransformationConnectorsRegistered=No transformation connectors registered +editoutput.NoOutputConnectorsRegistered=No output connectors registered +editnotification.NoNotificationConnectorsRegistered=No notification connectors registered +editnotification.Name=Name +editnotification.Type=Type +editnotification.Throttling=Throttling +editnotification.ApacheManifoldCFEditNotificationConnection=Apache ManifoldCF: Edit Notification Connection +editnotification.ConnectionMustHaveAName=Connection must have a name +editnotification.TheMaximumNumberOfConnectionsMustBeAValidInteger=The maximum number of connections must be a valid integer +editnotification.EditNotificationConnection2=Edit Notification Connection +editnotification.EditNotificationConnection=Edit notification connection +editnotification.EditANotificationConnection=Edit a notification connection +editnotification.tab=tab +editnotification.NameColon=Name: +editnotification.DescriptionColon=Description: +editnotification.TypeColon=Type: +editnotification.UNREGISTERED=UNREGISTERED +editnotification.ConnectionTypeColon=Connection type: +editnotification.MaxConnectionsColon=Max connections: +editnotification.Save=Save +editnotification.Continue=Continue +editnotification.SaveThisNotificationConnection=Save this notification connection +editnotification.ContinueToNextPage=Continue to next page +editnotification.Cancel=Cancel +editnotification.CancelNotificationConnectionEditing=Cancel notification connection editing + +listnotifications.ApacheManifoldCFListNotificationConnections=Apache ManifoldCF: List Notification Connections +listnotifications.DeleteNotificationConnection=Delete notification connection +listnotifications.ListOfNotificationConnections=List of Notification Connections +listnotifications.Name=Name +listnotifications.Description=Description +listnotifications.ConnectionType=Connection Type +listnotifications.Max=Max +listnotifications.uninstalled=(uninstalled) +listnotifications.View=View +listnotifications.Edit=Edit +listnotifications.Delete=Delete +listnotifications.AddANotificationConnection=Add a notification connection +listnotifications.AddaNewNotificationConnection=Add a new notification connection +listnotifications.DeleteNotificationConnection=Delete notification connection + +viewnotification.ApacheManifoldCFViewNotificationConnectionStatus=Apache ManifoldCF: View Notification Connection Status +viewnotification.Deletenotificationconnection=Delete notification connection +viewnotification.qmark=? +viewnotification.ViewNotificationConnectionStatus=View Notification Connection Status +viewnotification.uninstalled=(uninstalled) +viewnotification.Connectorisnotinstalled=Connector is not installed +viewnotification.Threwexception=Threw exception: +viewnotification.NameColon=Name: +viewnotification.DescriptionColon=Description: +viewnotification.ConnectionTypeColon=Connection type: +viewnotification.MaxConnectionsColon=Max connections: +viewnotification.ConnectionStatusColon=Connection status: +viewnotification.Refresh=Refresh +viewnotification.EditThisNotificationConnection=Edit this notification connection +viewnotification.Edit=Edit +viewnotification.DeleteThisNotificationConnection=Delete this notification connection +viewnotification.Delete=Delete + +navigation.Listnotificationconnections=List notification connections +navigation.ListNotificationConnections=List Notification Connections + +editjob.SelectANotificationConnectionName=Select a notification connection name +editjob.NotificationsColon=Notifications: +editjob.NotificationDescription=Description +editjob.NotificationConnectionName=Connection name +editjob.Deletenotification=Delete notification +editjob.AddNotification=Add notification +editjob.AddANotification=Add a notification + +viewjob.NotificationsColon=Notifications: +viewjob.NotificationDescription=Description +viewjob.NotificationConnectionName=Connection name +viewjob.NoNotificationConnections=No notification connections
