Package com.esri.gpt.control.webharvest.engine

Source Code of com.esri.gpt.control.webharvest.engine.AutoSelector

/* See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* Esri Inc. licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License.  You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.esri.gpt.control.webharvest.engine;

import com.esri.gpt.catalog.harvest.repository.HrRecord;
import com.esri.gpt.catalog.harvest.repository.HrRecords;
import com.esri.gpt.catalog.harvest.repository.HrSelectRequest;
import com.esri.gpt.framework.collection.StringAttributeMap;
import com.esri.gpt.framework.context.ApplicationConfiguration;
import com.esri.gpt.framework.context.ApplicationContext;
import com.esri.gpt.framework.context.RequestContext;
import com.esri.gpt.framework.util.TimePeriod;
import com.esri.gpt.framework.util.Val;
import java.sql.SQLException;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
* Schedules new harvesting task according to the repository harvest frequency.
*/
abstract class AutoSelector implements Runnable {
private static final int DEFAULT_MAX_ATTEMPTS = 1

/** logger */
private static final Logger LOGGER = Logger.getLogger(AutoSelector.class.getCanonicalName());
/** current thread */
private Thread workerThread;
/** shutdown flag */
private volatile boolean shutdown;
/** autoselect frequency */
private long autoSelectFrequency;
/** suspended */
private volatile boolean suspended;

/**
* Creates instance of auto selector.
* @param autoSelectFrequency auto select frequency (milliseconds)
*/
public AutoSelector(long autoSelectFrequency) {
  this.autoSelectFrequency = autoSelectFrequency;
}

@Override
public void run() {
  workerThread = Thread.currentThread();
  LOGGER.info("[SYNCHRONIZER] AutoSelector activated.");
  int attempt = 0;
 
  do {
    long duration = autoSelectFrequency;
    if (!suspended) {
      LOGGER.finer("[SYNCHRONIZER] AutoSelector entered run mode.");

      try {
        HrRecords records = selectRecords();

        // selecting all records with harvest date due now
        HrRecords recordsDueNow = records.findHarvestDue();
        LOGGER.log(Level.FINER, "[SYNCHRONIZER] AutoSelector selected {0} records with harvest date due now.", recordsDueNow.size());

        // process all with harvest date due now
        for (HrRecord r : recordsDueNow) {
          if (shutdown || suspended) break;
          // this is it; do something in overriden method
          onSelect(r);
        }

        // get the one record with the closes due date but not due yet
        HrRecord nextDue = records.findNextDue();
       
        // caluclate duration in milliseconds
        if (nextDue!=null) {
          Date nextHarvestDate = nextDue.getNextHarvestDate();
          duration = nextHarvestDate.getTime() - (new Date()).getTime() ;
          LOGGER.log(Level.INFO,"[SYNCHRONIZER] Next synchronization time : "+nextHarvestDate.toString()+" has been determined based on scheduling of "+nextDue.getUuid()+"/\""+nextDue.getName()+"\" harvesting site.");
        } else {
          duration = autoSelectFrequency;
          LOGGER.log(Level.INFO,"[SYNCHRONIZER] Next synchronization time couldn't been determined at this time.");
        }
       
        // clear attempt counter
        attempt = 0;
      } catch (SQLException ex) {
        LOGGER.log(Level.SEVERE, "[SYNCHRONIZER] Error selecting harvesting sites for harvest.", ex);
        attempt++;
        if (attempt<=getMaxAttempts()) {
          LOGGER.log(Level.SEVERE, "[SYNCHRONIZER] Error selecting harvesting sites for harvest.", ex);
        }
      }
    }

    if (shutdown) break;
   
    // wait for calculated duration or until interrupted
    synchronized (this) {
      try {
        if (isSuspendedWithAck()) {
          LOGGER.finer("[SYNCHRONIZER] AutoSelector suspended mode");
          wait();
        } else {
          TimePeriod period = new TimePeriod();
          period.setValue(duration);
          LOGGER.log(Level.FINER, "[SYNCHRONIZER] AutoSelector enters wait mode for {0}", period);
          wait(duration);
        }
      } catch (InterruptedException ex) {
        if (shutdown)
          break;
      }
    }
  } while (true);
}

/**
* Shuts down selector.
*/
public synchronized void shutdown() {
  LOGGER.info("[SYNCHRONIZER] Shutting down AutoSelector.");
  this.shutdown = true;
  if (workerThread != null) {
    workerThread.interrupt();
  }
}

/**
* Forces to reselect harvesting sites.
*/
public void reselect() {
  if (workerThread != null) {
    workerThread.interrupt();
  }
}

/**
* Called on every repository selected for harvest.
* @param context request context
* @param repository harvest repository
*/
protected abstract void onSelect(HrRecord repository);

/**
* Selects records.
* @return records
* @throws SQLException if accessing database failed
*/
private HrRecords selectRecords() throws SQLException {
  RequestContext context = RequestContext.extract(null);
  try {
    // get all harveting records
    HrSelectRequest selectRequest = new HrSelectRequest(context);
    selectRequest.execute();
    return selectRequest.getQueryResult().getRecords();
  } finally {
    context.onExecutionPhaseCompleted();
  }
}

public synchronized void safeSuspend() {
  if (!suspended) {
    LOGGER.info("[SYNCHRONIZER] Suspending AutoSelector");
    suspended = true;
    notify();
  } else {
    LOGGER.info("[SYNCHRONIZER] AutoSelector already suspended");
  }
}

public synchronized void safeResume() {
  if (suspended) {
    LOGGER.info("[SYNCHRONIZER] Resuming AutoSelector");
    suspended = false;
    notify();
  } else {
    LOGGER.info("[SYNCHRONIZER] AutoSelector already resumed");
  }
}

private boolean isSuspendedWithAck() {
  if (suspended) {
    LOGGER.info("[SYNCHRONIZER] AutoSelector acknowledged suspension");
  }
  return suspended;
}
 
private int getMaxAttempts() {
  ApplicationContext appCtx = ApplicationContext.getInstance();
  ApplicationConfiguration appCfg = appCtx.getConfiguration();
  StringAttributeMap parameters = appCfg.getCatalogConfiguration().getParameters();
  return Val.chkInt(parameters.getValue("webharvester.maxAttempts"),DEFAULT_MAX_ATTEMPTS);
}
}
TOP

Related Classes of com.esri.gpt.control.webharvest.engine.AutoSelector

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.