use of com.gitblit.models.TicketModel.Change in project gitblit by gitblit.
the class BranchTicketService method getJournal.
/**
* Returns the journal for the specified ticket.
*
* @param db
* @param ticketId
* @return a list of changes
*/
private List<Change> getJournal(Repository db, long ticketId) {
RefModel ticketsBranch = getTicketsBranch(db);
if (ticketsBranch == null) {
return new ArrayList<Change>();
}
if (ticketId <= 0L) {
return new ArrayList<Change>();
}
String journalPath = toTicketPath(ticketId) + "/" + JOURNAL;
String json = readTicketsFile(db, journalPath);
if (StringUtils.isEmpty(json)) {
return new ArrayList<Change>();
}
List<Change> list = TicketSerializer.deserializeJournal(json);
return list;
}
use of com.gitblit.models.TicketModel.Change in project gitblit by gitblit.
the class BranchTicketService method getTickets.
/**
* Returns all the tickets in the repository. Querying tickets from the
* repository requires deserializing all tickets. This is an expensive
* process and not recommended. Tickets are indexed by Lucene and queries
* should be executed against that index.
*
* @param repository
* @param filter
* optional filter to only return matching results
* @return a list of tickets
*/
@Override
public List<TicketModel> getTickets(RepositoryModel repository, TicketFilter filter) {
List<TicketModel> list = new ArrayList<TicketModel>();
Repository db = repositoryManager.getRepository(repository.name);
try {
RefModel ticketsBranch = getTicketsBranch(db);
if (ticketsBranch == null) {
return list;
}
// Collect the set of all json files
List<PathModel> paths = JGitUtils.getDocuments(db, Arrays.asList("json"), BRANCH);
// Deserialize each ticket and optionally filter out unwanted tickets
for (PathModel path : paths) {
String name = path.name.substring(path.name.lastIndexOf('/') + 1);
if (!JOURNAL.equals(name)) {
continue;
}
String json = readTicketsFile(db, path.path);
if (StringUtils.isEmpty(json)) {
// journal was touched but no changes were written
continue;
}
try {
// Reconstruct ticketId from the path
// id/26/326/journal.json
String tid = path.path.split("/")[2];
long ticketId = Long.parseLong(tid);
List<Change> changes = TicketSerializer.deserializeJournal(json);
if (ArrayUtils.isEmpty(changes)) {
log.warn("Empty journal for {}:{}", repository, path.path);
continue;
}
TicketModel ticket = TicketModel.buildTicket(changes);
ticket.project = repository.projectPath;
ticket.repository = repository.name;
ticket.number = ticketId;
// add the ticket, conditionally, to the list
if (filter == null) {
list.add(ticket);
} else {
if (filter.accept(ticket)) {
list.add(ticket);
}
}
} catch (Exception e) {
log.error("failed to deserialize {}/{}\n{}", new Object[] { repository, path.path, e.getMessage() });
log.error(null, e);
}
}
// sort the tickets by creation
Collections.sort(list);
return list;
} finally {
db.close();
}
}
use of com.gitblit.models.TicketModel.Change in project gitblit by gitblit.
the class RedisTicketService method commitChangeImpl.
/**
* Commit a ticket change to the repository.
*
* @param repository
* @param ticketId
* @param change
* @return true, if the change was committed
*/
@Override
protected boolean commitChangeImpl(RepositoryModel repository, long ticketId, Change change) {
Jedis jedis = pool.getResource();
if (jedis == null) {
return false;
}
try {
List<Change> changes = getJournal(jedis, repository, ticketId);
changes.add(change);
// build a new effective ticket from the changes
TicketModel ticket = TicketModel.buildTicket(changes);
String object = TicketSerializer.serialize(ticket);
String journal = TicketSerializer.serialize(change);
// atomically store ticket
Transaction t = jedis.multi();
t.set(key(repository, KeyType.ticket, ticketId), object);
t.rpush(key(repository, KeyType.journal, ticketId), journal);
t.exec();
log.debug("updated ticket {} in Redis @ {}", "" + ticketId, getUrl());
return true;
} catch (JedisException e) {
log.error("failed to update ticket cache in Redis @ " + getUrl(), e);
pool.returnBrokenResource(jedis);
jedis = null;
} finally {
if (jedis != null) {
pool.returnResource(jedis);
}
}
return false;
}
use of com.gitblit.models.TicketModel.Change in project gitblit by gitblit.
the class RedisTicketService method getTickets.
/**
* Returns all the tickets in the repository. Querying tickets from the
* repository requires deserializing all tickets. This is an expensive
* process and not recommended. Tickets should be indexed by Lucene and
* queries should be executed against that index.
*
* @param repository
* @param filter
* optional filter to only return matching results
* @return a list of tickets
*/
@Override
public List<TicketModel> getTickets(RepositoryModel repository, TicketFilter filter) {
Jedis jedis = pool.getResource();
List<TicketModel> list = new ArrayList<TicketModel>();
if (jedis == null) {
return list;
}
try {
// Deserialize each journal, build the ticket, and optionally filter
Set<String> keys = jedis.keys(key(repository, KeyType.journal, "*"));
for (String key : keys) {
// {repo}:journal:{id}
String id = key.split(":")[2];
long ticketId = Long.parseLong(id);
List<Change> changes = getJournal(jedis, repository, ticketId);
if (ArrayUtils.isEmpty(changes)) {
log.warn("Empty journal for {}:{}", repository, ticketId);
continue;
}
TicketModel ticket = TicketModel.buildTicket(changes);
ticket.project = repository.projectPath;
ticket.repository = repository.name;
ticket.number = ticketId;
// add the ticket, conditionally, to the list
if (filter == null) {
list.add(ticket);
} else {
if (filter.accept(ticket)) {
list.add(ticket);
}
}
}
// sort the tickets by creation
Collections.sort(list);
} catch (JedisException e) {
log.error("failed to retrieve tickets from Redis @ " + getUrl(), e);
pool.returnBrokenResource(jedis);
jedis = null;
} finally {
if (jedis != null) {
pool.returnResource(jedis);
}
}
return list;
}
use of com.gitblit.models.TicketModel.Change in project gitblit by gitblit.
the class BranchTicketService method createIndex.
/**
* Creates an in-memory index of the ticket change.
*
* @param changeId
* @param change
* @return an in-memory index
* @throws IOException
*/
private DirCache createIndex(Repository db, long ticketId, Change change) throws IOException, ClassNotFoundException, NoSuchFieldException {
String ticketPath = toTicketPath(ticketId);
DirCache newIndex = DirCache.newInCore();
DirCacheBuilder builder = newIndex.builder();
ObjectInserter inserter = db.newObjectInserter();
Set<String> ignorePaths = new TreeSet<String>();
try {
// create/update the journal
// exclude the attachment content
List<Change> changes = getJournal(db, ticketId);
changes.add(change);
String journal = TicketSerializer.serializeJournal(changes).trim();
byte[] journalBytes = journal.getBytes(Constants.ENCODING);
String journalPath = ticketPath + "/" + JOURNAL;
final DirCacheEntry journalEntry = new DirCacheEntry(journalPath);
journalEntry.setLength(journalBytes.length);
journalEntry.setLastModified(change.date.getTime());
journalEntry.setFileMode(FileMode.REGULAR_FILE);
journalEntry.setObjectId(inserter.insert(org.eclipse.jgit.lib.Constants.OBJ_BLOB, journalBytes));
// add journal to index
builder.add(journalEntry);
ignorePaths.add(journalEntry.getPathString());
// Add any attachments to the index
if (change.hasAttachments()) {
for (Attachment attachment : change.attachments) {
// build a path name for the attachment and mark as ignored
String path = toAttachmentPath(ticketId, attachment.name);
ignorePaths.add(path);
// create an index entry for this attachment
final DirCacheEntry entry = new DirCacheEntry(path);
entry.setLength(attachment.content.length);
entry.setLastModified(change.date.getTime());
entry.setFileMode(FileMode.REGULAR_FILE);
// insert object
entry.setObjectId(inserter.insert(org.eclipse.jgit.lib.Constants.OBJ_BLOB, attachment.content));
// add to temporary in-core index
builder.add(entry);
}
}
for (DirCacheEntry entry : JGitUtils.getTreeEntries(db, BRANCH, ignorePaths)) {
builder.add(entry);
}
// finish the index
builder.finish();
} finally {
inserter.close();
}
return newIndex;
}
Aggregations