/** * Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.web.analytics.rest; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.regex.Pattern; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import org.apache.commons.lang.StringUtils; import org.json.JSONArray; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.collect.ImmutableMap; import com.google.common.collect.LinkedListMultimap; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Multimap; import com.opengamma.core.marketdatasnapshot.impl.ManageableMarketDataSnapshot; import com.opengamma.id.ObjectId; import com.opengamma.master.marketdatasnapshot.MarketDataSnapshotDocument; import com.opengamma.master.marketdatasnapshot.MarketDataSnapshotHistoryRequest; import com.opengamma.master.marketdatasnapshot.MarketDataSnapshotHistoryResult; import com.opengamma.master.marketdatasnapshot.MarketDataSnapshotMaster; import com.opengamma.master.marketdatasnapshot.MarketDataSnapshotSearchRequest; import com.opengamma.master.marketdatasnapshot.impl.MarketDataSnapshotSearchIterator; import com.opengamma.util.ArgumentChecker; /** * REST resource that produces a JSON list of market data snapshots and their IDs. This isn't a full REST * interface for market data snapshots, it's intended for populating data in the web client. */ @Path("marketdatasnapshots") public class MarketDataSnapshotListResource { private static final Logger s_logger = LoggerFactory.getLogger(MarketDataSnapshotListResource.class); static final String BASIS_VIEW_NAME = "basisViewName"; static final String SNAPSHOTS = "snapshots"; static final String ID = "id"; static final String NAME = "name"; private static final Pattern s_guidPattern = Pattern.compile("(\\{?([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}\\}?)"); private final MarketDataSnapshotMaster _snapshotMaster; public MarketDataSnapshotListResource(MarketDataSnapshotMaster snapshotMaster) { ArgumentChecker.notNull(snapshotMaster, "snapshotMaster"); _snapshotMaster = snapshotMaster; } /** * @return JSON {@code [{basisViewName: basisViewName1, snapshots: [{id: snapshot1Id, name: snapshot1Name}, ...]}, ...]} */ @GET @Produces(MediaType.APPLICATION_JSON) public String getMarketDataSnapshotList() { MarketDataSnapshotSearchRequest snapshotSearchRequest = new MarketDataSnapshotSearchRequest(); snapshotSearchRequest.setIncludeData(false); Multimap<String, ManageableMarketDataSnapshot> snapshotsByBasisView = LinkedListMultimap.create(); for (MarketDataSnapshotDocument doc : MarketDataSnapshotSearchIterator.iterable(_snapshotMaster, snapshotSearchRequest)) { ManageableMarketDataSnapshot snapshot = doc.getSnapshot(); if (snapshot.getUniqueId() == null) { s_logger.warn("Ignoring snapshot with null unique identifier {}", snapshot.getName()); continue; } if (StringUtils.isBlank(snapshot.getName())) { s_logger.warn("Ignoring snapshot {} with no name", snapshot.getUniqueId()); continue; } if (s_guidPattern.matcher(snapshot.getName()).find()) { s_logger.debug("Ignoring snapshot which appears to have an auto-generated name: {}", snapshot.getName()); continue; } String basisViewName = snapshot.getBasisViewName() != null ? snapshot.getBasisViewName() : "unknown"; snapshotsByBasisView.put(basisViewName, snapshot); } // list of maps for each basis view: {"basisViewName": basisViewName, "snapshots", [...]} List<Map<String, Object>> basisViewSnapshotList = new ArrayList<Map<String, Object>>(); for (String basisViewName : snapshotsByBasisView.keySet()) { Collection<ManageableMarketDataSnapshot> viewSnapshots = snapshotsByBasisView.get(basisViewName); // list of maps containing snapshot IDs and names: {"id", snapshotId, "name", snapshotName} List<Map<String, Object>> snapshotsList = new ArrayList<Map<String, Object>>(viewSnapshots.size()); for (ManageableMarketDataSnapshot viewSnapshot : viewSnapshots) { // map for a single snapshot: {"id", snapshotId, "name", snapshotName} Map<String, Object> snapshotMap = ImmutableMap.<String, Object>of(ID, viewSnapshot.getUniqueId(), NAME, viewSnapshot.getName()); snapshotsList.add(snapshotMap); } basisViewSnapshotList.add(ImmutableMap.of(BASIS_VIEW_NAME, basisViewName, SNAPSHOTS, snapshotsList)); } return new JSONArray(basisViewSnapshotList).toString(); } /** * Returns the version history of a market data snapshot. * @param snapshotId An snapshot {@link ObjectId} * @return JSON array of the snapshot's history * <pre> * [{"uniqueId": "DbSnp~12345~2", * "correctionFrom": "2012-05-23T10:54:10.124293Z", * "correctionTo": null, * "versionFrom": "2012-05-23T10:54:10.124293Z", * "versionTo": null}] * </pre> */ @GET @Produces(MediaType.APPLICATION_JSON) @Path("{snapshotId}") public String getMarketDataSnapshotHistory(@PathParam("snapshotId") String snapshotId) { ObjectId id = ObjectId.parse(snapshotId); MarketDataSnapshotHistoryResult result = _snapshotMaster.history(new MarketDataSnapshotHistoryRequest(id)); List<MarketDataSnapshotDocument> documents = result.getDocuments(); List<Map<String, Object>> json = Lists.newArrayListWithCapacity(documents.size()); for (MarketDataSnapshotDocument document : documents) { Map<String, Object> map = Maps.newHashMapWithExpectedSize(5); map.put("uniqueId", document.getUniqueId()); map.put("versionFrom", document.getVersionFromInstant()); map.put("versionTo", document.getVersionToInstant()); map.put("correctionFrom", document.getCorrectionFromInstant()); map.put("correctionTo", document.getCorrectionToInstant()); json.add(map); } return new JSONArray(json).toString(); } }