import java.io.FileOutputStream; | import java.io.FileOutputStream; | ||||
import java.io.IOException; | import java.io.IOException; | ||||
import java.net.InetAddress; | import java.net.InetAddress; | ||||
import java.text.MessageFormat; | |||||
import java.util.ArrayList; | import java.util.ArrayList; | ||||
import java.util.Arrays; | import java.util.Arrays; | ||||
import java.util.Collection; | import java.util.Collection; | ||||
FederationPullStatus is = registration.getLowestStatus(); | FederationPullStatus is = registration.getLowestStatus(); | ||||
if (is.ordinal() < was.ordinal()) { | if (is.ordinal() < was.ordinal()) { | ||||
// the status for this registration has downgraded | // the status for this registration has downgraded | ||||
logger.warn("Federation pull status of {0} is now {1}", registration.name, | |||||
is.name()); | |||||
logger.warn("Federation pull status of {} is now {}", registration.name, is.name()); | |||||
if (registration.notifyOnError) { | if (registration.notifyOnError) { | ||||
String message = "Federation pull of " + registration.name + " @ " | String message = "Federation pull of " + registration.name + " @ " | ||||
+ registration.url + " is now at " + is.name(); | + registration.url + " is now at " + is.name(); | ||||
} | } | ||||
} | } | ||||
} catch (Throwable t) { | } catch (Throwable t) { | ||||
logger.error(MessageFormat.format( | |||||
"Failed to pull from federated gitblit ({0} @ {1})", registration.name, | |||||
registration.url), t); | |||||
logger.error("Failed to pull from federated gitblit ({} @ {})", registration.name, registration.url, t); | |||||
} finally { | } finally { | ||||
reschedule(registration); | reschedule(registration); | ||||
} | } | ||||
// confirm valid characters in server alias | // confirm valid characters in server alias | ||||
Character c = StringUtils.findInvalidCharacter(registrationFolder); | Character c = StringUtils.findInvalidCharacter(registrationFolder); | ||||
if (c != null) { | if (c != null) { | ||||
logger.error(MessageFormat | |||||
.format("Illegal character ''{0}'' in folder name ''{1}'' of federation registration {2}!", | |||||
c, registrationFolder, registration.name)); | |||||
logger.error("Illegal character '{}' in folder name '{}' of federation registration {}!", | |||||
c, registrationFolder, registration.name); | |||||
return; | return; | ||||
} | } | ||||
File repositoriesFolder = gitblit.getRepositoriesFolder(); | File repositoriesFolder = gitblit.getRepositoriesFolder(); | ||||
String cloneUrl = entry.getKey(); | String cloneUrl = entry.getKey(); | ||||
RepositoryModel repository = entry.getValue(); | RepositoryModel repository = entry.getValue(); | ||||
if (!repository.hasCommits) { | if (!repository.hasCommits) { | ||||
logger.warn(MessageFormat.format( | |||||
"Skipping federated repository {0} from {1} @ {2}. Repository is EMPTY.", | |||||
repository.name, registration.name, registration.url)); | |||||
logger.warn("Skipping federated repository {} from {} @ {}. Repository is EMPTY.", | |||||
repository.name, registration.name, registration.url); | |||||
registration.updateStatus(repository, FederationPullStatus.SKIPPED); | registration.updateStatus(repository, FederationPullStatus.SKIPPED); | ||||
continue; | continue; | ||||
} | } | ||||
Repository existingRepository = gitblit.getRepository(repositoryName); | Repository existingRepository = gitblit.getRepository(repositoryName); | ||||
if (existingRepository == null && gitblit.isCollectingGarbage(repositoryName)) { | if (existingRepository == null && gitblit.isCollectingGarbage(repositoryName)) { | ||||
logger.warn(MessageFormat.format("Skipping local repository {0}, busy collecting garbage", repositoryName)); | |||||
logger.warn("Skipping local repository {}, busy collecting garbage", repositoryName); | |||||
continue; | continue; | ||||
} | } | ||||
} | } | ||||
existingRepository.close(); | existingRepository.close(); | ||||
if (!origin.startsWith(registration.url)) { | if (!origin.startsWith(registration.url)) { | ||||
logger.warn(MessageFormat | |||||
.format("Skipping federated repository {0} from {1} @ {2}. Origin does not match, consider EXCLUDING.", | |||||
repository.name, registration.name, registration.url)); | |||||
logger.warn("Skipping federated repository {} from {} @ {}. Origin does not match, consider EXCLUDING.", | |||||
repository.name, registration.name, registration.url); | |||||
registration.updateStatus(repository, FederationPullStatus.SKIPPED); | registration.updateStatus(repository, FederationPullStatus.SKIPPED); | ||||
continue; | continue; | ||||
} | } | ||||
// clone/pull this repository | // clone/pull this repository | ||||
CredentialsProvider credentials = new UsernamePasswordCredentialsProvider( | CredentialsProvider credentials = new UsernamePasswordCredentialsProvider( | ||||
Constants.FEDERATION_USER, registration.token); | Constants.FEDERATION_USER, registration.token); | ||||
logger.info(MessageFormat.format("Pulling federated repository {0} from {1} @ {2}", | |||||
repository.name, registration.name, registration.url)); | |||||
logger.info("Pulling federated repository {} from {} @ {}", repository.name, registration.name, registration.url); | |||||
CloneResult result = JGitUtils.cloneRepository(registrationFolderFile, repository.name, | CloneResult result = JGitUtils.cloneRepository(registrationFolderFile, repository.name, | ||||
cloneUrl, registration.bare, credentials); | cloneUrl, registration.bare, credentials); | ||||
repository.federationStrategy = FederationStrategy.EXCLUDE; | repository.federationStrategy = FederationStrategy.EXCLUDE; | ||||
repository.isFrozen = registration.mirror; | repository.isFrozen = registration.mirror; | ||||
repository.showRemoteBranches = !registration.mirror; | repository.showRemoteBranches = !registration.mirror; | ||||
logger.info(MessageFormat.format(" cloning {0}", repository.name)); | |||||
logger.info(" cloning {}", repository.name); | |||||
registration.updateStatus(repository, FederationPullStatus.MIRRORED); | registration.updateStatus(repository, FederationPullStatus.MIRRORED); | ||||
} else { | } else { | ||||
// fetch and update | // fetch and update | ||||
String hash = ref.getReferencedObjectId().getName(); | String hash = ref.getReferencedObjectId().getName(); | ||||
JGitUtils.setBranchRef(r, branch, hash); | JGitUtils.setBranchRef(r, branch, hash); | ||||
logger.info(MessageFormat.format(" resetting {0} of {1} to {2}", branch, | |||||
repository.name, hash)); | |||||
logger.info(" resetting {} of {} to {}", branch, repository.name, hash); | |||||
} | } | ||||
} | } | ||||
newHead = repository.HEAD; | newHead = repository.HEAD; | ||||
} | } | ||||
JGitUtils.setHEADtoRef(r, newHead); | JGitUtils.setHEADtoRef(r, newHead); | ||||
logger.info(MessageFormat.format(" resetting HEAD of {0} to {1}", | |||||
repository.name, newHead)); | |||||
logger.info(" resetting HEAD of {} to {}", repository.name, newHead); | |||||
registration.updateStatus(repository, FederationPullStatus.MIRRORED); | registration.updateStatus(repository, FederationPullStatus.MIRRORED); | ||||
} else { | } else { | ||||
// indicate no commits pulled | // indicate no commits pulled | ||||
} catch (ForbiddenException e) { | } catch (ForbiddenException e) { | ||||
// ignore forbidden exceptions | // ignore forbidden exceptions | ||||
} catch (IOException e) { | } catch (IOException e) { | ||||
logger.warn(MessageFormat.format( | |||||
"Failed to retrieve USERS from federated gitblit ({0} @ {1})", | |||||
registration.name, registration.url), e); | |||||
logger.warn("Failed to retrieve USERS from federated gitblit ({} @ {})", registration.name, registration.url, e); | |||||
} | } | ||||
try { | try { | ||||
} catch (ForbiddenException e) { | } catch (ForbiddenException e) { | ||||
// ignore forbidden exceptions | // ignore forbidden exceptions | ||||
} catch (IOException e) { | } catch (IOException e) { | ||||
logger.warn(MessageFormat.format( | |||||
"Failed to retrieve TEAMS from federated gitblit ({0} @ {1})", | |||||
registration.name, registration.url), e); | |||||
logger.warn("Failed to retrieve TEAMS from federated gitblit ({} @ {})", registration.name, registration.url, e); | |||||
} | } | ||||
try { | try { | ||||
} catch (ForbiddenException e) { | } catch (ForbiddenException e) { | ||||
// ignore forbidden exceptions | // ignore forbidden exceptions | ||||
} catch (IOException e) { | } catch (IOException e) { | ||||
logger.warn(MessageFormat.format( | |||||
"Failed to retrieve SETTINGS from federated gitblit ({0} @ {1})", | |||||
registration.name, registration.url), e); | |||||
logger.warn("Failed to retrieve SETTINGS from federated gitblit ({} @ {})", registration.name, registration.url, e); | |||||
} | } | ||||
try { | try { | ||||
} catch (ForbiddenException e) { | } catch (ForbiddenException e) { | ||||
// ignore forbidden exceptions | // ignore forbidden exceptions | ||||
} catch (IOException e) { | } catch (IOException e) { | ||||
logger.warn(MessageFormat.format( | |||||
"Failed to retrieve SCRIPTS from federated gitblit ({0} @ {1})", | |||||
registration.name, registration.url), e); | |||||
logger.warn("Failed to retrieve SCRIPTS from federated gitblit ({} @ {})", registration.name, registration.url, e); | |||||
} | } | ||||
} | } | ||||
federationName = addr.getHostName(); | federationName = addr.getHostName(); | ||||
} | } | ||||
FederationUtils.acknowledgeStatus(addr.getHostAddress(), registration); | FederationUtils.acknowledgeStatus(addr.getHostAddress(), registration); | ||||
logger.info(MessageFormat.format("Pull status sent to {0}", registration.url)); | |||||
logger.info("Pull status sent to {}", registration.url); | |||||
} | } | ||||
} | } |
*/ | */ | ||||
package com.gitblit.service; | package com.gitblit.service; | ||||
import java.text.MessageFormat; | |||||
import java.util.Calendar; | import java.util.Calendar; | ||||
import java.util.Date; | import java.util.Date; | ||||
import java.util.Map; | import java.util.Map; | ||||
break; | break; | ||||
} | } | ||||
if (isCollectingGarbage(repositoryName)) { | if (isCollectingGarbage(repositoryName)) { | ||||
logger.warn(MessageFormat.format("Already collecting garbage from {0}?!?", repositoryName)); | |||||
logger.warn("Already collecting garbage from {}?!?", repositoryName); | |||||
continue; | continue; | ||||
} | } | ||||
boolean garbageCollected = false; | boolean garbageCollected = false; | ||||
model = repositoryManager.getRepositoryModel(repositoryName); | model = repositoryManager.getRepositoryModel(repositoryName); | ||||
repository = repositoryManager.getRepository(repositoryName); | repository = repositoryManager.getRepository(repositoryName); | ||||
if (repository == null) { | if (repository == null) { | ||||
logger.warn(MessageFormat.format("GCExecutor is missing repository {0}?!?", repositoryName)); | |||||
logger.warn("GCExecutor is missing repository {}?!?", repositoryName); | |||||
continue; | continue; | ||||
} | } | ||||
if (!repositoryManager.isIdle(repository)) { | if (!repositoryManager.isIdle(repository)) { | ||||
logger.debug(MessageFormat.format("GCExecutor is skipping {0} because it is not idle", repositoryName)); | |||||
logger.debug("GCExecutor is skipping {} because it is not idle", repositoryName); | |||||
continue; | continue; | ||||
} | } | ||||
// disabling *all* access to this repository from Gitblit. | // disabling *all* access to this repository from Gitblit. | ||||
// Think of this as a clutch in a manual transmission vehicle. | // Think of this as a clutch in a manual transmission vehicle. | ||||
if (!setGCStatus(repositoryName, GCStatus.COLLECTING)) { | if (!setGCStatus(repositoryName, GCStatus.COLLECTING)) { | ||||
logger.warn(MessageFormat.format("Can not acquire GC lock for {0}, skipping", repositoryName)); | |||||
logger.warn("Can not acquire GC lock for {}, skipping", repositoryName); | |||||
continue; | continue; | ||||
} | } | ||||
logger.debug(MessageFormat.format("GCExecutor locked idle repository {0}", repositoryName)); | |||||
logger.debug("GCExecutor locked idle repository {}", repositoryName); | |||||
Git git = new Git(repository); | Git git = new Git(repository); | ||||
GarbageCollectCommand gc = git.gc(); | GarbageCollectCommand gc = git.gc(); | ||||
boolean hasGarbage = sizeOfLooseObjects > 0; | boolean hasGarbage = sizeOfLooseObjects > 0; | ||||
if (hasGarbage && (hasEnoughGarbage || shouldCollectGarbage)) { | if (hasGarbage && (hasEnoughGarbage || shouldCollectGarbage)) { | ||||
long looseKB = sizeOfLooseObjects/1024L; | long looseKB = sizeOfLooseObjects/1024L; | ||||
logger.info(MessageFormat.format("Collecting {1} KB of loose objects from {0}", repositoryName, looseKB)); | |||||
logger.info("Collecting {} KB of loose objects from {}", looseKB, repositoryName ); | |||||
// do the deed | // do the deed | ||||
gc.call(); | gc.call(); | ||||
garbageCollected = true; | garbageCollected = true; | ||||
} | } | ||||
} catch (Exception e) { | } catch (Exception e) { | ||||
logger.error("Error collecting garbage in " + repositoryName, e); | |||||
logger.error("Error collecting garbage in {}", repositoryName, e); | |||||
} finally { | } finally { | ||||
// cleanup | // cleanup | ||||
if (repository != null) { | if (repository != null) { | ||||
// reset the GC lock | // reset the GC lock | ||||
releaseLock(repositoryName); | releaseLock(repositoryName); | ||||
logger.debug(MessageFormat.format("GCExecutor released GC lock for {0}", repositoryName)); | |||||
logger.debug("GCExecutor released GC lock for {}", repositoryName); | |||||
} | } | ||||
} | } | ||||
Repository repository = repositoryManager.getRepository(model.name); | Repository repository = repositoryManager.getRepository(model.name); | ||||
if (repository == null) { | if (repository == null) { | ||||
if (repositoryManager.isCollectingGarbage(model.name)) { | if (repositoryManager.isCollectingGarbage(model.name)) { | ||||
logger.info(MessageFormat.format("Skipping Lucene index of {0}, busy garbage collecting", repositoryName)); | |||||
logger.info("Skipping Lucene index of {}, busy garbage collecting", repositoryName); | |||||
} | } | ||||
continue; | continue; | ||||
} | } | ||||
if (result.success) { | if (result.success) { | ||||
if (result.commitCount > 0) { | if (result.commitCount > 0) { | ||||
String msg = "Built {0} Lucene index from {1} commits and {2} files across {3} branches in {4} secs"; | |||||
logger.info(MessageFormat.format(msg, model.name, result.commitCount, | |||||
result.blobCount, result.branchCount, result.duration())); | |||||
logger.info("Built {} Lucene index from {} commits and {} files across {} branches in {} secs", | |||||
model.name, result.commitCount, result.blobCount, result.branchCount, result.duration()); | |||||
} | } | ||||
} else { | } else { | ||||
String msg = "Could not build {0} Lucene index!"; | String msg = "Could not build {0} Lucene index!"; | ||||
IndexResult result = updateIndex(model, repository); | IndexResult result = updateIndex(model, repository); | ||||
if (result.success) { | if (result.success) { | ||||
if (result.commitCount > 0) { | if (result.commitCount > 0) { | ||||
String msg = "Updated {0} Lucene index with {1} commits and {2} files across {3} branches in {4} secs"; | |||||
logger.info(MessageFormat.format(msg, model.name, result.commitCount, | |||||
result.blobCount, result.branchCount, result.duration())); | |||||
logger.info("Updated {} Lucene index with {} commits and {} files across {} branches in {} secs", | |||||
model.name, result.commitCount, result.blobCount, result.branchCount, result.duration()); | |||||
} | } | ||||
} else { | } else { | ||||
String msg = "Could not update {0} Lucene index!"; | |||||
logger.error(MessageFormat.format(msg, model.name)); | |||||
logger.error("Could not update {} Lucene index!", model.name); | |||||
} | } | ||||
} | } | ||||
} catch (Throwable t) { | } catch (Throwable t) { | ||||
logger.error(MessageFormat.format("Lucene indexing failure for {0}", model.name), t); | |||||
logger.error("Lucene indexing failure for {}", model.name, t); | |||||
} | } | ||||
} | } | ||||
searcher.getIndexReader().close(); | searcher.getIndexReader().close(); | ||||
} | } | ||||
} catch (Exception e) { | } catch (Exception e) { | ||||
logger.error("Failed to close index searcher for " + repositoryName, e); | |||||
logger.error("Failed to close index searcher for {}", repositoryName, e); | |||||
} | } | ||||
try { | try { | ||||
writer.close(); | writer.close(); | ||||
} | } | ||||
} catch (Exception e) { | } catch (Exception e) { | ||||
logger.error("Failed to close index writer for " + repositoryName, e); | |||||
logger.error("Failed to close index writer for {}", repositoryName, e); | |||||
} | } | ||||
} | } | ||||
try { | try { | ||||
writers.get(writer).close(); | writers.get(writer).close(); | ||||
} catch (Throwable t) { | } catch (Throwable t) { | ||||
logger.error("Failed to close Lucene writer for " + writer, t); | |||||
logger.error("Failed to close Lucene writer for {}", writer, t); | |||||
} | } | ||||
} | } | ||||
writers.clear(); | writers.clear(); | ||||
try { | try { | ||||
searchers.get(searcher).getIndexReader().close(); | searchers.get(searcher).getIndexReader().close(); | ||||
} catch (Throwable t) { | } catch (Throwable t) { | ||||
logger.error("Failed to close Lucene searcher for " + searcher, t); | |||||
logger.error("Failed to close Lucene searcher for {}", searcher, t); | |||||
} | } | ||||
} | } | ||||
searchers.clear(); | searchers.clear(); | ||||
resetIndexSearcher(model.name); | resetIndexSearcher(model.name); | ||||
result.success(); | result.success(); | ||||
} catch (Exception e) { | } catch (Exception e) { | ||||
logger.error("Exception while reindexing " + model.name, e); | |||||
logger.error("Exception while reindexing {}", model.name, e); | |||||
} | } | ||||
return result; | return result; | ||||
} | } | ||||
result.commitCount++; | result.commitCount++; | ||||
result.success = index(repositoryName, doc); | result.success = index(repositoryName, doc); | ||||
} catch (Exception e) { | } catch (Exception e) { | ||||
logger.error(MessageFormat.format("Exception while indexing commit {0} in {1}", commit.getId().getName(), repositoryName), e); | |||||
logger.error("Exception while indexing commit {} in {}", commit.getId().getName(), repositoryName, e); | |||||
} | } | ||||
return result; | return result; | ||||
} | } | ||||
writer.commit(); | writer.commit(); | ||||
int numDocsAfter = writer.numDocs(); | int numDocsAfter = writer.numDocs(); | ||||
if (numDocsBefore == numDocsAfter) { | if (numDocsBefore == numDocsAfter) { | ||||
logger.debug(MessageFormat.format("no records found to delete {0}", query.toString())); | |||||
logger.debug("no records found to delete {}", query.toString()); | |||||
return false; | return false; | ||||
} else { | } else { | ||||
logger.debug(MessageFormat.format("deleted {0} records with {1}", numDocsBefore - numDocsAfter, query.toString())); | |||||
logger.debug("deleted {} records with {}", numDocsBefore - numDocsAfter, query.toString()); | |||||
return true; | return true; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
result.success = true; | result.success = true; | ||||
} catch (Throwable t) { | } catch (Throwable t) { | ||||
logger.error(MessageFormat.format("Exception while updating {0} Lucene index", model.name), t); | |||||
logger.error("Exception while updating {} Lucene index", model.name, t); | |||||
} | } | ||||
return result; | return result; | ||||
} | } | ||||
resetIndexSearcher(repositoryName); | resetIndexSearcher(repositoryName); | ||||
return true; | return true; | ||||
} catch (Exception e) { | } catch (Exception e) { | ||||
logger.error(MessageFormat.format("Exception while incrementally updating {0} Lucene index", repositoryName), e); | |||||
logger.error("Exception while incrementally updating {} Lucene index", repositoryName, e); | |||||
} | } | ||||
return false; | return false; | ||||
} | } | ||||
results.add(result); | results.add(result); | ||||
} | } | ||||
} catch (Exception e) { | } catch (Exception e) { | ||||
logger.error(MessageFormat.format("Exception while searching for {0}", text), e); | |||||
logger.error("Exception while searching for {}", text, e); | |||||
} | } | ||||
return new ArrayList<SearchResult>(results); | return new ArrayList<SearchResult>(results); | ||||
} | } |
repository = repositoryManager.getRepository(repositoryName); | repository = repositoryManager.getRepository(repositoryName); | ||||
if (repository == null) { | if (repository == null) { | ||||
logger.warn(MessageFormat.format("MirrorExecutor is missing repository {0}?!?", repositoryName)); | |||||
logger.warn("MirrorExecutor is missing repository {}?!?", repositoryName); | |||||
continue; | continue; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
} catch (Exception e) { | } catch (Exception e) { | ||||
logger.error("Error updating mirror " + repositoryName, e); | |||||
logger.error("Error updating mirror {}", repositoryName, e); | |||||
} finally { | } finally { | ||||
// cleanup | // cleanup | ||||
if (repository != null) { | if (repository != null) { |
package com.gitblit.tickets; | package com.gitblit.tickets; | ||||
import java.io.IOException; | import java.io.IOException; | ||||
import java.text.MessageFormat; | |||||
import java.util.ArrayList; | import java.util.ArrayList; | ||||
import java.util.Arrays; | import java.util.Arrays; | ||||
import java.util.Collections; | import java.util.Collections; | ||||
if (!ids.contains(ticketId)) { | if (!ids.contains(ticketId)) { | ||||
ids.add(ticketId); | ids.add(ticketId); | ||||
TicketModel ticket = getTicket(repository, ticketId); | TicketModel ticket = getTicket(repository, ticketId); | ||||
log.info(MessageFormat.format("indexing ticket #{0,number,0}: {1}", | |||||
ticketId, ticket.title)); | |||||
log.info("indexing ticket #{}: {}", ticketId, ticket.title); | |||||
indexer.index(ticket); | indexer.index(ticket); | ||||
} | } | ||||
} | } | ||||
long end = System.nanoTime(); | long end = System.nanoTime(); | ||||
log.info("incremental indexing of {0} ticket(s) completed in {1} msecs", | |||||
log.info("incremental indexing of {} ticket(s) completed in {} msecs", | |||||
ids.size(), TimeUnit.NANOSECONDS.toMillis(end - start)); | ids.size(), TimeUnit.NANOSECONDS.toMillis(end - start)); | ||||
} finally { | } finally { | ||||
db.close(); | db.close(); | ||||
} | } | ||||
break; | break; | ||||
default: | default: | ||||
log.warn("Unexpected receive type {} in BranchTicketService.onRefsChanged" + cmd.getType()); | |||||
log.warn("Unexpected receive type {} in BranchTicketService.onRefsChanged", cmd.getType()); | |||||
break; | break; | ||||
} | } | ||||
} catch (Exception e) { | } catch (Exception e) { | ||||
Result res = cmd.rename(); | Result res = cmd.rename(); | ||||
switch (res) { | switch (res) { | ||||
case RENAMED: | case RENAMED: | ||||
log.info(db.getDirectory() + " " + cmd.getRefLogMessage()); | |||||
log.info("{} {}", db.getDirectory(), cmd.getRefLogMessage()); | |||||
return getTicketsBranch(db); | return getTicketsBranch(db); | ||||
default: | default: | ||||
log.error("failed to rename " + oldRef.getName() + " => " + BRANCH + " (" + res.name() + ")"); | |||||
log.error("failed to rename {} => {} ({})", oldRef.getName(), BRANCH, res.name()); | |||||
} | } | ||||
} catch (IOException e) { | } catch (IOException e) { | ||||
log.error("failed to rename tickets branch", e); | log.error("failed to rename tickets branch", e); | ||||
return JGitUtils.getStringContent(db, tree, file, Constants.ENCODING); | return JGitUtils.getStringContent(db, tree, file, Constants.ENCODING); | ||||
} | } | ||||
} catch (IOException e) { | } catch (IOException e) { | ||||
log.error("failed to read " + file, e); | |||||
log.error("failed to read {}", file, e); | |||||
} finally { | } finally { | ||||
if (rw != null) { | if (rw != null) { | ||||
rw.close(); | rw.close(); | ||||
} | } | ||||
} | } | ||||
} catch (Exception e) { | } catch (Exception e) { | ||||
log.error("failed to deserialize {}/{}\n{}", | |||||
new Object [] { repository, path.path, e.getMessage()}); | |||||
log.error("failed to deserialize {}/{}\n{}", repository, path.path, e.getMessage()); | |||||
log.error(null, e); | log.error(null, e); | ||||
} | } | ||||
} | } | ||||
success = commitIndex(db, index, deletedBy, "- " + ticket.number); | success = commitIndex(db, index, deletedBy, "- " + ticket.number); | ||||
} catch (Throwable t) { | } catch (Throwable t) { | ||||
log.error(MessageFormat.format("Failed to delete ticket {0,number,0} from {1}", | |||||
ticket.number, db.getDirectory()), t); | |||||
log.error("Failed to delete ticket {} from {}", ticket.number, db.getDirectory(), t); | |||||
} finally { | } finally { | ||||
// release the treewalk | // release the treewalk | ||||
if (treeWalk != null) { | if (treeWalk != null) { | ||||
success = commitIndex(db, index, change.author, "#" + ticketId); | success = commitIndex(db, index, change.author, "#" + ticketId); | ||||
} catch (Throwable t) { | } catch (Throwable t) { | ||||
log.error(MessageFormat.format("Failed to commit ticket {0,number,0} to {1}", | |||||
ticketId, db.getDirectory()), t); | |||||
log.error("Failed to commit ticket {} to {}", ticketId, db.getDirectory(), t); | |||||
} finally { | } finally { | ||||
db.close(); | db.close(); | ||||
} | } |
import java.io.File; | import java.io.File; | ||||
import java.io.IOException; | import java.io.IOException; | ||||
import java.text.MessageFormat; | |||||
import java.util.ArrayList; | import java.util.ArrayList; | ||||
import java.util.Collections; | import java.util.Collections; | ||||
import java.util.List; | import java.util.List; | ||||
} | } | ||||
} | } | ||||
} catch (Exception e) { | } catch (Exception e) { | ||||
log.error("failed to deserialize {}/{}\n{}", | |||||
new Object [] { repository, journal, e.getMessage()}); | |||||
log.error("failed to deserialize {}/{}\n{}", repository, journal, e.getMessage()); | |||||
log.error(null, e); | log.error(null, e); | ||||
} | } | ||||
} | } | ||||
FileUtils.writeContent(file, journal); | FileUtils.writeContent(file, journal); | ||||
success = true; | success = true; | ||||
} catch (Throwable t) { | } catch (Throwable t) { | ||||
log.error(MessageFormat.format("Failed to commit ticket {0,number,0} to {1}", | |||||
ticketId, db.getDirectory()), t); | |||||
log.error("Failed to commit ticket {} to {}", ticketId, db.getDirectory(), t); | |||||
} finally { | } finally { | ||||
db.close(); | db.close(); | ||||
} | } |
} | } | ||||
labelsCache.put(key, Collections.unmodifiableList(list)); | labelsCache.put(key, Collections.unmodifiableList(list)); | ||||
} catch (Exception e) { | } catch (Exception e) { | ||||
log.error("invalid tickets settings for " + repository, e); | |||||
log.error("invalid tickets settings for {}", repository, e); | |||||
} finally { | } finally { | ||||
db.close(); | db.close(); | ||||
} | } | ||||
config.setString(LABEL, label, COLOR, lb.color); | config.setString(LABEL, label, COLOR, lb.color); | ||||
config.save(); | config.save(); | ||||
} catch (IOException e) { | } catch (IOException e) { | ||||
log.error("failed to create label " + label + " in " + repository, e); | |||||
log.error("failed to create label {} in {}", label, repository, e); | |||||
} finally { | } finally { | ||||
if (db != null) { | if (db != null) { | ||||
db.close(); | db.close(); | ||||
return true; | return true; | ||||
} catch (IOException e) { | } catch (IOException e) { | ||||
log.error("failed to update label " + label + " in " + repository, e); | |||||
log.error("failed to update label {} in {}", label, repository, e); | |||||
} finally { | } finally { | ||||
if (db != null) { | if (db != null) { | ||||
db.close(); | db.close(); | ||||
return true; | return true; | ||||
} catch (IOException e) { | } catch (IOException e) { | ||||
log.error("failed to rename label " + oldName + " in " + repository, e); | |||||
log.error("failed to rename label {} in {}", oldName, repository, e); | |||||
} finally { | } finally { | ||||
if (db != null) { | if (db != null) { | ||||
db.close(); | db.close(); | ||||
return true; | return true; | ||||
} catch (IOException e) { | } catch (IOException e) { | ||||
log.error("failed to delete label " + label + " in " + repository, e); | |||||
log.error("failed to delete label {} in {}", label, repository, e); | |||||
} finally { | } finally { | ||||
if (db != null) { | if (db != null) { | ||||
db.close(); | db.close(); | ||||
try { | try { | ||||
milestone.due = new SimpleDateFormat(DUE_DATE_PATTERN).parse(due); | milestone.due = new SimpleDateFormat(DUE_DATE_PATTERN).parse(due); | ||||
} catch (ParseException e) { | } catch (ParseException e) { | ||||
log.error("failed to parse {} milestone {} due date \"{}\"", | |||||
new Object [] { repository, name, due }); | |||||
log.error("failed to parse {} milestone {} due date \"{}\"", repository, name, due, e); | |||||
} | } | ||||
} | } | ||||
list.add(milestone); | list.add(milestone); | ||||
} | } | ||||
milestonesCache.put(key, Collections.unmodifiableList(list)); | milestonesCache.put(key, Collections.unmodifiableList(list)); | ||||
} catch (Exception e) { | } catch (Exception e) { | ||||
log.error("invalid tickets settings for " + repository, e); | |||||
log.error("invalid tickets settings for {}", repository, e); | |||||
} finally { | } finally { | ||||
db.close(); | db.close(); | ||||
} | } | ||||
milestonesCache.remove(repository.name); | milestonesCache.remove(repository.name); | ||||
} catch (IOException e) { | } catch (IOException e) { | ||||
log.error("failed to create milestone " + milestone + " in " + repository, e); | |||||
log.error("failed to create milestone {} in {}", milestone, repository, e); | |||||
} finally { | } finally { | ||||
if (db != null) { | if (db != null) { | ||||
db.close(); | db.close(); | ||||
milestonesCache.remove(repository.name); | milestonesCache.remove(repository.name); | ||||
return true; | return true; | ||||
} catch (IOException e) { | } catch (IOException e) { | ||||
log.error("failed to update milestone " + milestone + " in " + repository, e); | |||||
log.error("failed to update milestone {} in {}", milestone, repository, e); | |||||
} finally { | } finally { | ||||
if (db != null) { | if (db != null) { | ||||
db.close(); | db.close(); | ||||
return true; | return true; | ||||
} catch (IOException e) { | } catch (IOException e) { | ||||
log.error("failed to rename milestone " + oldName + " in " + repository, e); | |||||
log.error("failed to rename milestone {} in {}", oldName, repository, e); | |||||
} finally { | } finally { | ||||
if (db != null) { | if (db != null) { | ||||
db.close(); | db.close(); | ||||
} | } | ||||
return true; | return true; | ||||
} catch (IOException e) { | } catch (IOException e) { | ||||
log.error("failed to delete milestone " + milestone + " in " + repository, e); | |||||
log.error("failed to delete milestone {} in {}", milestone, repository, e); | |||||
} finally { | } finally { | ||||
if (db != null) { | if (db != null) { | ||||
db.close(); | db.close(); | ||||
TicketModel ticket = getTicket(repository, ticketId); | TicketModel ticket = getTicket(repository, ticketId); | ||||
boolean success = deleteTicketImpl(repository, ticket, deletedBy); | boolean success = deleteTicketImpl(repository, ticket, deletedBy); | ||||
if (success) { | if (success) { | ||||
log.info(MessageFormat.format("Deleted {0} ticket #{1,number,0}: {2}", | |||||
repository.name, ticketId, ticket.title)); | |||||
log.info("Deleted {} ticket #{}: {}", repository.name, ticketId, ticket.title); | |||||
ticketsCache.invalidate(new TicketKey(repository, ticketId)); | ticketsCache.invalidate(new TicketKey(repository, ticketId)); | ||||
indexer.delete(ticket); | indexer.delete(ticket); | ||||
return true; | return true; |
Boolean exists = jedis.exists(key(repository, KeyType.journal, ticketId)); | Boolean exists = jedis.exists(key(repository, KeyType.journal, ticketId)); | ||||
return exists != null && exists; | return exists != null && exists; | ||||
} catch (JedisException e) { | } catch (JedisException e) { | ||||
log.error("failed to check hasTicket from Redis @ " + getUrl(), e); | |||||
log.error("failed to check hasTicket from Redis @ {}", getUrl(), e); | |||||
pool.returnBrokenResource(jedis); | pool.returnBrokenResource(jedis); | ||||
jedis = null; | jedis = null; | ||||
} finally { | } finally { | ||||
ids.add(ticketId); | ids.add(ticketId); | ||||
} | } | ||||
} catch (JedisException e) { | } catch (JedisException e) { | ||||
log.error("failed to assign new ticket id in Redis @ " + getUrl(), e); | |||||
log.error("failed to assign new ticket id in Redis @ {}", getUrl(), e); | |||||
pool.returnBrokenResource(jedis); | pool.returnBrokenResource(jedis); | ||||
jedis = null; | jedis = null; | ||||
} finally { | } finally { | ||||
long ticketNumber = jedis.incr(key); | long ticketNumber = jedis.incr(key); | ||||
return ticketNumber; | return ticketNumber; | ||||
} catch (JedisException e) { | } catch (JedisException e) { | ||||
log.error("failed to assign new ticket id in Redis @ " + getUrl(), e); | |||||
log.error("failed to assign new ticket id in Redis @ {}", getUrl(), e); | |||||
pool.returnBrokenResource(jedis); | pool.returnBrokenResource(jedis); | ||||
jedis = null; | jedis = null; | ||||
} finally { | } finally { | ||||
// sort the tickets by creation | // sort the tickets by creation | ||||
Collections.sort(list); | Collections.sort(list); | ||||
} catch (JedisException e) { | } catch (JedisException e) { | ||||
log.error("failed to retrieve tickets from Redis @ " + getUrl(), e); | |||||
log.error("failed to retrieve tickets from Redis @ {}", getUrl(), e); | |||||
pool.returnBrokenResource(jedis); | pool.returnBrokenResource(jedis); | ||||
jedis = null; | jedis = null; | ||||
} finally { | } finally { | ||||
log.debug("rebuilt ticket {} from Redis @ {}", ticketId, getUrl()); | log.debug("rebuilt ticket {} from Redis @ {}", ticketId, getUrl()); | ||||
return ticket; | return ticket; | ||||
} catch (JedisException e) { | } catch (JedisException e) { | ||||
log.error("failed to retrieve ticket from Redis @ " + getUrl(), e); | |||||
log.error("failed to retrieve ticket from Redis @ {}", getUrl(), e); | |||||
pool.returnBrokenResource(jedis); | pool.returnBrokenResource(jedis); | ||||
jedis = null; | jedis = null; | ||||
} finally { | } finally { | ||||
} | } | ||||
return changes; | return changes; | ||||
} catch (JedisException e) { | } catch (JedisException e) { | ||||
log.error("failed to retrieve journal from Redis @ " + getUrl(), e); | |||||
log.error("failed to retrieve journal from Redis @ {}", getUrl(), e); | |||||
pool.returnBrokenResource(jedis); | pool.returnBrokenResource(jedis); | ||||
jedis = null; | jedis = null; | ||||
} finally { | } finally { | ||||
t.exec(); | t.exec(); | ||||
success = true; | success = true; | ||||
log.debug("deleted ticket {} from Redis @ {}", "" + ticket.number, getUrl()); | |||||
log.debug("deleted ticket {} from Redis @ {}", ticket.number, getUrl()); | |||||
} catch (JedisException e) { | } catch (JedisException e) { | ||||
log.error("failed to delete ticket from Redis @ " + getUrl(), e); | |||||
log.error("failed to delete ticket from Redis @ {}", getUrl(), e); | |||||
pool.returnBrokenResource(jedis); | pool.returnBrokenResource(jedis); | ||||
jedis = null; | jedis = null; | ||||
} finally { | } finally { | ||||
t.rpush(key(repository, KeyType.journal, ticketId), journal); | t.rpush(key(repository, KeyType.journal, ticketId), journal); | ||||
t.exec(); | t.exec(); | ||||
log.debug("updated ticket {} in Redis @ {}", "" + ticketId, getUrl()); | |||||
log.debug("updated ticket {} in Redis @ {}", ticketId, getUrl()); | |||||
return true; | return true; | ||||
} catch (JedisException e) { | } catch (JedisException e) { | ||||
log.error("failed to update ticket cache in Redis @ " + getUrl(), e); | |||||
log.error("failed to update ticket cache in Redis @ {}", getUrl(), e); | |||||
pool.returnBrokenResource(jedis); | pool.returnBrokenResource(jedis); | ||||
jedis = null; | jedis = null; | ||||
} finally { | } finally { | ||||
} | } | ||||
success = true; | success = true; | ||||
} catch (JedisException e) { | } catch (JedisException e) { | ||||
log.error("failed to delete all tickets in Redis @ " + getUrl(), e); | |||||
log.error("failed to delete all tickets in Redis @ {}", getUrl(), e); | |||||
pool.returnBrokenResource(jedis); | pool.returnBrokenResource(jedis); | ||||
jedis = null; | jedis = null; | ||||
} finally { | } finally { | ||||
t.exec(); | t.exec(); | ||||
success = true; | success = true; | ||||
} catch (JedisException e) { | } catch (JedisException e) { | ||||
log.error("failed to rename tickets in Redis @ " + getUrl(), e); | |||||
log.error("failed to rename tickets in Redis @ {}", getUrl(), e); | |||||
pool.returnBrokenResource(jedis); | pool.returnBrokenResource(jedis); | ||||
jedis = null; | jedis = null; | ||||
} finally { | } finally { |
import java.io.File; | import java.io.File; | ||||
import java.io.IOException; | import java.io.IOException; | ||||
import java.text.MessageFormat; | |||||
import java.text.ParseException; | import java.text.ParseException; | ||||
import java.util.ArrayList; | import java.util.ArrayList; | ||||
import java.util.Collections; | import java.util.Collections; | ||||
closeSearcher(); | closeSearcher(); | ||||
int numDocsAfter = writer.numDocs(); | int numDocsAfter = writer.numDocs(); | ||||
if (numDocsBefore == numDocsAfter) { | if (numDocsBefore == numDocsAfter) { | ||||
log.debug(MessageFormat.format("no records found to delete in {0}", repository)); | |||||
log.debug("no records found to delete in {}", repository); | |||||
return false; | return false; | ||||
} else { | } else { | ||||
log.debug(MessageFormat.format("deleted {0} records in {1}", numDocsBefore - numDocsAfter, repository)); | |||||
log.debug("deleted {} records in {}", numDocsBefore - numDocsAfter, repository); | |||||
return true; | return true; | ||||
} | } | ||||
} catch (Exception e) { | } catch (Exception e) { | ||||
IndexWriter writer = getWriter(); | IndexWriter writer = getWriter(); | ||||
return delete(ticket.repository, ticket.number, writer); | return delete(ticket.repository, ticket.number, writer); | ||||
} catch (Exception e) { | } catch (Exception e) { | ||||
log.error("Failed to delete ticket " + ticket.number, e); | |||||
log.error("Failed to delete ticket {}", ticket.number, e); | |||||
} | } | ||||
return false; | return false; | ||||
} | } | ||||
closeSearcher(); | closeSearcher(); | ||||
int numDocsAfter = writer.numDocs(); | int numDocsAfter = writer.numDocs(); | ||||
if (numDocsBefore == numDocsAfter) { | if (numDocsBefore == numDocsAfter) { | ||||
log.debug(MessageFormat.format("no records found to delete in {0}", repository)); | |||||
log.debug("no records found to delete in {}", repository); | |||||
return false; | return false; | ||||
} else { | } else { | ||||
log.debug(MessageFormat.format("deleted {0} records in {1}", numDocsBefore - numDocsAfter, repository)); | |||||
log.debug("deleted {} records in {}", numDocsBefore - numDocsAfter, repository); | |||||
return true; | return true; | ||||
} | } | ||||
} | } | ||||
results.add(result); | results.add(result); | ||||
} | } | ||||
} catch (Exception e) { | } catch (Exception e) { | ||||
log.error(MessageFormat.format("Exception while searching for {0}", text), e); | |||||
log.error("Exception while searching for {}", text, e); | |||||
} | } | ||||
return new ArrayList<QueryResult>(results); | return new ArrayList<QueryResult>(results); | ||||
} | } | ||||
results.add(result); | results.add(result); | ||||
} | } | ||||
} catch (Exception e) { | } catch (Exception e) { | ||||
log.error(MessageFormat.format("Exception while searching for {0}", queryText), e); | |||||
log.error("Exception while searching for {}", queryText, e); | |||||
} | } | ||||
return new ArrayList<QueryResult>(results); | return new ArrayList<QueryResult>(results); | ||||
} | } |
import java.util.regex.Pattern; | import java.util.regex.Pattern; | ||||
import org.apache.commons.io.IOUtils; | import org.apache.commons.io.IOUtils; | ||||
import org.apache.log4j.Logger; | |||||
import org.eclipse.jgit.diff.DiffEntry.ChangeType; | import org.eclipse.jgit.diff.DiffEntry.ChangeType; | ||||
import org.eclipse.jgit.lib.Repository; | import org.eclipse.jgit.lib.Repository; | ||||
import org.eclipse.jgit.revwalk.RevCommit; | import org.eclipse.jgit.revwalk.RevCommit; | ||||
import org.slf4j.Logger; | |||||
import org.slf4j.LoggerFactory; | import org.slf4j.LoggerFactory; | ||||
import com.gitblit.Constants; | import com.gitblit.Constants; | ||||
private final String addPattern = "<span style=\"color:darkgreen;\">+{0}</span>"; | private final String addPattern = "<span style=\"color:darkgreen;\">+{0}</span>"; | ||||
private final String delPattern = "<span style=\"color:darkred;\">-{0}</span>"; | private final String delPattern = "<span style=\"color:darkred;\">-{0}</span>"; | ||||
private final Logger log = LoggerFactory.getLogger(getClass()); | |||||
public TicketNotifier( | public TicketNotifier( | ||||
IRuntimeManager runtimeManager, | IRuntimeManager runtimeManager, | ||||
INotificationManager notificationManager, | INotificationManager notificationManager, | ||||
return mailing; | return mailing; | ||||
} catch (Exception e) { | } catch (Exception e) { | ||||
Logger.getLogger(getClass()).error("failed to queue mailing for #" + ticket.number, e); | |||||
log.error("failed to queue mailing for #{}", ticket.number, e); | |||||
} | } | ||||
return null; | return null; | ||||
} | } | ||||
diffstat = DiffUtils.getDiffStat(repo, base, patchset.tip); | diffstat = DiffUtils.getDiffStat(repo, base, patchset.tip); | ||||
commits = JGitUtils.getRevLog(repo, base, patchset.tip); | commits = JGitUtils.getRevLog(repo, base, patchset.tip); | ||||
} catch (Exception e) { | } catch (Exception e) { | ||||
Logger.getLogger(getClass()).error("failed to get changed paths", e); | |||||
log.error("failed to get changed paths", e); | |||||
} finally { | } finally { | ||||
if (repo != null) { | if (repo != null) { | ||||
repo.close(); | repo.close(); | ||||
if (user.canView(repository)) { | if (user.canView(repository)) { | ||||
toAddresses.add(user.emailAddress); | toAddresses.add(user.emailAddress); | ||||
} else { | } else { | ||||
LoggerFactory.getLogger(getClass()).warn( | |||||
MessageFormat.format("ticket {0}-{1,number,0}: {2} can not receive notification", | |||||
repository.name, ticket.number, user.username)); | |||||
log.warn("ticket {}-{}: {} can not receive notification", repository.name, ticket.number, user.username); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
if (user.canView(repository)) { | if (user.canView(repository)) { | ||||
ccAddresses.add(user.emailAddress); | ccAddresses.add(user.emailAddress); | ||||
} else { | } else { | ||||
LoggerFactory.getLogger(getClass()).warn( | |||||
MessageFormat.format("ticket {0}-{1,number,0}: {2} can not receive notification", | |||||
repository.name, ticket.number, user.username)); | |||||
log.warn("ticket {}-{}: {} can not receive notification", repository.name, ticket.number, user.username); | |||||
} | } | ||||
} | } | ||||
} | } |