package com.thinkbiganalytics.feedmgr.rest.controller;
/*-
* #%L
* thinkbig-feed-manager-controller
* %%
* Copyright (C) 2017 ThinkBig Analytics
* %%
* Licensed 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.
* #L%
*/
import com.thinkbiganalytics.feedmgr.rest.FeedLineageBuilder;
import com.thinkbiganalytics.feedmgr.rest.Model;
import com.thinkbiganalytics.feedmgr.security.FeedServicesAccessControl;
import com.thinkbiganalytics.feedmgr.service.datasource.DatasourceModelTransform;
import com.thinkbiganalytics.feedmgr.service.datasource.DatasourceService;
import com.thinkbiganalytics.feedmgr.service.security.SecurityService;
import com.thinkbiganalytics.feedmgr.sla.ServiceLevelAgreementModelTransform;
import com.thinkbiganalytics.metadata.api.MetadataAccess;
import com.thinkbiganalytics.metadata.api.datasource.Datasource;
import com.thinkbiganalytics.metadata.api.datasource.DatasourceProvider;
import com.thinkbiganalytics.metadata.api.feed.FeedProvider;
import com.thinkbiganalytics.metadata.api.op.FeedDependencyDeltaResults;
import com.thinkbiganalytics.metadata.api.op.FeedOperationsProvider;
import com.thinkbiganalytics.metadata.core.feed.FeedPreconditionService;
import com.thinkbiganalytics.metadata.rest.MetadataModelTransform;
import com.thinkbiganalytics.metadata.rest.model.feed.Feed;
import com.thinkbiganalytics.metadata.rest.model.feed.FeedCriteria;
import com.thinkbiganalytics.metadata.rest.model.feed.FeedDependencyGraph;
import com.thinkbiganalytics.metadata.rest.model.feed.FeedDestination;
import com.thinkbiganalytics.metadata.rest.model.feed.FeedLineage;
import com.thinkbiganalytics.metadata.rest.model.feed.FeedPrecondition;
import com.thinkbiganalytics.metadata.rest.model.feed.FeedSource;
import com.thinkbiganalytics.metadata.rest.model.feed.InitializationStatus;
import com.thinkbiganalytics.metadata.rest.model.sla.ServiceLevelAssessment;
import com.thinkbiganalytics.rest.model.RestResponseStatus;
import com.thinkbiganalytics.security.AccessController;
import com.thinkbiganalytics.security.action.AllowedEntityActionsProvider;
import com.thinkbiganalytics.security.rest.controller.SecurityModelTransform;
import com.thinkbiganalytics.security.rest.model.ActionGroup;
import com.thinkbiganalytics.security.rest.model.PermissionsChange;
import com.thinkbiganalytics.security.rest.model.PermissionsChange.ChangeType;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.security.Principal;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.inject.Inject;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response.Status;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
/**
* Manages Feed Metadata and allows feeds to be updated with various Metadata Properties.
*/
@Component
@Api(tags = "Feed Manager - Feeds", produces = "application/json")
@Path("/v1/metadata/feed")
public class FeedsController {
private static final Logger LOG = LoggerFactory.getLogger(FeedsController.class);
@Inject
private FeedProvider feedProvider;
@Inject
private FeedOperationsProvider feedOpsProvider;
@Inject
private DatasourceProvider datasetProvider;
@Inject
private DatasourceService datasourceService;
@Inject
private AllowedEntityActionsProvider actionsProvider;
@Inject
private FeedPreconditionService preconditionService;
@Inject
private SecurityService securityService;
@Inject
private MetadataAccess metadata;
@Inject
private MetadataModelTransform metadataTransform;
@Inject
private SecurityModelTransform actionsTransform;
@Inject
private AccessController accessController;
@Inject
private Model model;
@Inject
private DatasourceModelTransform datasourceTransform;
@GET
@Path("{id}/actions/available")
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation("Gets the list of available actions that may be permitted or revoked on a feed.")
@ApiResponses({
@ApiResponse(code = 200, message = "Returns the actions.", response = ActionGroup.class),
@ApiResponse(code = 404, message = "A feed with the given ID does not exist.", response = RestResponseStatus.class)
})
public ActionGroup getAvailableActions(@PathParam("id") String feedIdStr) {
LOG.debug("Get available actions for feed: {}", feedIdStr);
return this.securityService.getAvailableFeedActions(feedIdStr)
.orElseThrow(() -> new WebApplicationException("A feed with the given ID does not exist: " + feedIdStr, Status.NOT_FOUND));
}
@GET
@Path("{id}/actions/allowed")
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation("Gets the list of actions permitted for the given username and/or groups.")
@ApiResponses({
@ApiResponse(code = 200, message = "Returns the actions.", response = ActionGroup.class),
@ApiResponse(code = 404, message = "A feed with the given ID does not exist.", response = RestResponseStatus.class)
})
public ActionGroup getAllowedActions(@PathParam("id") String feedIdStr,
@QueryParam("user") Set<String> userNames,
@QueryParam("group") Set<String> groupNames) {
LOG.debug("Get allowed actions for feed: {}", feedIdStr);
Set<? extends Principal> users = Arrays.stream(this.actionsTransform.asUserPrincipals(userNames)).collect(Collectors.toSet());
Set<? extends Principal> groups = Arrays.stream(this.actionsTransform.asGroupPrincipals(groupNames)).collect(Collectors.toSet());
return this.securityService.getAllowedFeedActions(feedIdStr, Stream.concat(users.stream(), groups.stream()).collect(Collectors.toSet()))
.orElseThrow(() -> new WebApplicationException("A feed with the given ID does not exist: " + feedIdStr, Status.NOT_FOUND));
}
@POST
@Path("{id}/actions/allowed")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation("Updates the permissions for a feed using the supplied permission change request.")
@ApiResponses({
@ApiResponse(code = 200, message = "The permissions were changed successfully.", response = ActionGroup.class),
@ApiResponse(code = 400, message = "The type is not valid.", response = RestResponseStatus.class),
@ApiResponse(code = 404, message = "No feed exists with the specified ID.", response = RestResponseStatus.class)
})
public ActionGroup postPermissionsChange(@PathParam("id") String feedIdStr,
PermissionsChange changes) {
return this.securityService.changeFeedPermissions(feedIdStr, changes)
.orElseThrow(() -> new WebApplicationException("A feed with the given ID does not exist: " + feedIdStr, Status.NOT_FOUND));
}
@GET
@Path("{id}/actions/change/allowed")
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation("Constructs and returns a permission change request for a set of users/groups containing the actions that the requester may permit or revoke.")
@ApiResponses({
@ApiResponse(code = 200, message = "Returns the change request that may be modified by the client and re-posted.", response = PermissionsChange.class),
@ApiResponse(code = 400, message = "The type is not valid.", response = RestResponseStatus.class),
@ApiResponse(code = 404, message = "No feed exists with the specified ID.", response = RestResponseStatus.class)
})
public PermissionsChange getAllowedPermissionsChange(@PathParam("id") String feedIdStr,
@QueryParam("type") String changeType,
@QueryParam("user") Set<String> userNames,
@QueryParam("group") Set<String> groupNames) {
if (StringUtils.isBlank(changeType)) {
throw new WebApplicationException("The query parameter \"type\" is required", Status.BAD_REQUEST);
}
Set<? extends Principal> users = Arrays.stream(this.actionsTransform.asUserPrincipals(userNames)).collect(Collectors.toSet());
Set<? extends Principal> groups = Arrays.stream(this.actionsTransform.asGroupPrincipals(groupNames)).collect(Collectors.toSet());
return this.securityService.createFeedPermissionChange(feedIdStr,
ChangeType.valueOf(changeType.toUpperCase()),
Stream.concat(users.stream(), groups.stream()).collect(Collectors.toSet()))
.orElseThrow(() -> new WebApplicationException("A feed with the given ID does not exist: " + feedIdStr, Status.NOT_FOUND));
}
@GET
@Path("{id}/initstatus")
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation("Gets the registration status for the specified feed.")
@ApiResponses({
@ApiResponse(code = 200, message = "Returns the registration status.", response = InitializationStatus.class),
@ApiResponse(code = 404, message = "The feed could not be found.", response = RestResponseStatus.class)
})
public InitializationStatus getInitializationStatus(@PathParam("id") String feedIdStr) {
LOG.debug("Get feed initialization status {}", feedIdStr);
return this.metadata.read(() -> {
this.accessController.checkPermission(AccessController.SERVICES, FeedServicesAccessControl.ACCESS_FEEDS);
com.thinkbiganalytics.metadata.api.feed.Feed.ID feedId = feedProvider.resolveFeed(feedIdStr);
com.thinkbiganalytics.metadata.api.feed.Feed feed = feedProvider.getFeed(feedId);
if (feed != null) {
return metadataTransform.domainToInitStatus().apply(feed.getCurrentInitStatus());
} else {
throw new WebApplicationException("A feed with the given ID does not exist: " + feedId, Status.NOT_FOUND);
}
});
}
@GET
@Path("{id}/initstatus/history")
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation("Gets the registration history for the specified feed.")
@ApiResponses({
@ApiResponse(code = 200, message = "Returns the registration history.", response = InitializationStatus.class, responseContainer = "List"),
@ApiResponse(code = 404, message = "The feed could not be found.", response = RestResponseStatus.class)
})
public List<InitializationStatus> getInitializationStatusHistory(@PathParam("id") String feedIdStr) {
LOG.debug("Get feed initialization history {}", feedIdStr);
return this.metadata.read(() -> {
this.accessController.checkPermission(AccessController.SERVICES, FeedServicesAccessControl.ACCESS_FEEDS);
com.thinkbiganalytics.metadata.api.feed.Feed.ID feedId = feedProvider.resolveFeed(feedIdStr);
com.thinkbiganalytics.metadata.api.feed.Feed feed = feedProvider.getFeed(feedId);
if (feed != null) {
return feed.getInitHistory().stream().map(metadataTransform.domainToInitStatus()).collect(Collectors.toList());
} else {
throw new WebApplicationException("A feed with the given ID does not exist: " + feedId, Status.NOT_FOUND);
}
});
}
@PUT
@Path("{id}/initstatus")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@ApiOperation("Sets the registration status for the specified feed.")
@ApiResponses({
@ApiResponse(code = 204, message = "The registration status was updated."),
@ApiResponse(code = 404, message = "The feed could not be found.", response = RestResponseStatus.class),
@ApiResponse(code = 500, message = "The registration status could not be updated.", response = RestResponseStatus.class)
})
public void putInitializationStatus(@PathParam("id") String feedIdStr,
InitializationStatus status) {
LOG.debug("Get feed initialization status {}", feedIdStr);
this.metadata.commit(() -> {
this.accessController.checkPermission(AccessController.SERVICES, FeedServicesAccessControl.ACCESS_FEEDS);
com.thinkbiganalytics.metadata.api.feed.Feed.ID feedId = feedProvider.resolveFeed(feedIdStr);
com.thinkbiganalytics.metadata.api.feed.Feed feed = feedProvider.getFeed(feedId);
if (feed != null) {
com.thinkbiganalytics.metadata.api.feed.InitializationStatus.State newState
= com.thinkbiganalytics.metadata.api.feed.InitializationStatus.State.valueOf(status.getState().name());
feed.updateInitStatus(new com.thinkbiganalytics.metadata.api.feed.InitializationStatus(newState));
} else {
throw new WebApplicationException("A feed with the given ID does not exist: " + feedId, Status.NOT_FOUND);
}
});
}
@GET
@Path("{id}/watermark")
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation("Gets the HighWaterMarks used by the specified feed.")
@ApiResponses({
@ApiResponse(code = 200, message = "Returns the HighWaterMark names.", response = String.class, responseContainer = "List"),
@ApiResponse(code = 404, message = "The feed could not be found.", response = RestResponseStatus.class)
})
public List<String> getHighWaterMarks(@PathParam("id") String feedIdStr) {
LOG.debug("Get feed watermarks {}", feedIdStr);
return this.metadata.read(() -> {
this.accessController.checkPermission(AccessController.SERVICES, FeedServicesAccessControl.ACCESS_FEEDS);
com.thinkbiganalytics.metadata.api.feed.Feed.ID feedId = feedProvider.resolveFeed(feedIdStr);
com.thinkbiganalytics.metadata.api.feed.Feed feed = feedProvider.getFeed(feedId);
if (feed != null) {
List<String> list = feed.getWaterMarkNames().stream().collect(Collectors.toList());
Collections.sort(list);
return list;
} else {
throw new WebApplicationException("A feed with the given ID does not exist: " + feedId, Status.NOT_FOUND);
}
});
}
@GET
@Path("{id}/watermark/{name}")
@Produces({MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON})
@ApiOperation("Gets the value for a specific HighWaterMark.")
@ApiResponses({
@ApiResponse(code = 200, message = "Returns the HighWaterMark value.", response = String.class),
@ApiResponse(code = 404, message = "The HighWaterMark could not be found.", response = RestResponseStatus.class)
})
public String getHighWaterMark(@PathParam("id") String feedIdStr,
@PathParam("name") String waterMarkName) {
LOG.debug("Get feed watermark {}: {}", feedIdStr, waterMarkName);
return this.metadata.read(() -> {
this.accessController.checkPermission(AccessController.SERVICES, FeedServicesAccessControl.ACCESS_FEEDS);
com.thinkbiganalytics.metadata.api.feed.Feed.ID feedId = feedProvider.resolveFeed(feedIdStr);
com.thinkbiganalytics.metadata.api.feed.Feed feed = feedProvider.getFeed(feedId);
if (feed != null) {
return feed.getWaterMarkValue(waterMarkName)
.orElseThrow(() -> new WebApplicationException("A feed high-water mark with the given name does not exist: " + waterMarkName, Status.NOT_FOUND));
} else {
throw new WebApplicationException("A feed with the given ID does not exist: " + feedId, Status.NOT_FOUND);
}
});
}
@PUT
@Path("{id}/watermark/{name}")
@Consumes(MediaType.TEXT_PLAIN)
@ApiOperation("Sets the value for a specific HighWaterMark.")
@ApiResponses({
@ApiResponse(code = 204, message = "The HighWaterMark value has been changed."),
@ApiResponse(code = 404, message = "The feed could not be found.", response = RestResponseStatus.class),
@ApiResponse(code = 500, message = "The HighWaterMark value could not be changed.", response = RestResponseStatus.class)
})
public void putHighWaterMark(@PathParam("id") String feedIdStr,
@PathParam("name") String waterMarkName,
String value) {
LOG.debug("Get feed watermark {}: {}", feedIdStr, waterMarkName);
this.metadata.commit(() -> {
this.accessController.checkPermission(AccessController.SERVICES, FeedServicesAccessControl.ACCESS_FEEDS);
com.thinkbiganalytics.metadata.api.feed.Feed.ID feedId = feedProvider.resolveFeed(feedIdStr);
com.thinkbiganalytics.metadata.api.feed.Feed feed = feedProvider.getFeed(feedId);
if (feed != null) {
feed.setWaterMarkValue(waterMarkName, value);
} else {
throw new WebApplicationException("A feed with the given ID does not exist: " + feedId, Status.NOT_FOUND);
}
});
}
@DELETE
@Path("{id}/watermark/{name}")
@Consumes(MediaType.TEXT_PLAIN)
@ApiOperation("Deletes the specified HighWaterMark.")
@ApiResponses({
@ApiResponse(code = 204, message = "The HighWaterMark has been deleted."),
@ApiResponse(code = 404, message = "The feed could not be found.", response = RestResponseStatus.class),
@ApiResponse(code = 500, message = "The HighWaterMark could not be deleted.", response = RestResponseStatus.class)
})
public void deleteHighWaterMark(@PathParam("id") String feedIdStr,
@PathParam("name") String waterMarkName) {
LOG.debug("Get feed watermark {}: {}", feedIdStr, waterMarkName);
this.metadata.commit(() -> {
this.accessController.checkPermission(AccessController.SERVICES, FeedServicesAccessControl.ACCESS_FEEDS);
com.thinkbiganalytics.metadata.api.feed.Feed.ID feedId = feedProvider.resolveFeed(feedIdStr);
com.thinkbiganalytics.metadata.api.feed.Feed feed = feedProvider.getFeed(feedId);
if (feed != null) {
feed.setWaterMarkValue(waterMarkName, null);
} else {
throw new WebApplicationException("A feed with the given ID does not exist: " + feedId, Status.NOT_FOUND);
}
});
}
@GET
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation("Gets a list of feeds.")
@ApiResponses(
@ApiResponse(code = 200, message = "Returns the matching feeds.", response = Feed.class, responseContainer = "List")
)
public List<Feed> getFeeds(@QueryParam(FeedCriteria.CATEGORY) final String category,
@QueryParam(FeedCriteria.NAME) final String name,
@QueryParam(FeedCriteria.SRC_ID) final String srcId,
@QueryParam(FeedCriteria.DEST_ID) final String destId) {
LOG.debug("Get feeds {}/{}/{}", name, srcId, destId);
return this.metadata.read(() -> {
this.accessController.checkPermission(AccessController.SERVICES, FeedServicesAccessControl.ACCESS_FEEDS);
com.thinkbiganalytics.metadata.api.feed.FeedCriteria criteria = createFeedCriteria(category, name, srcId, destId);
Collection<com.thinkbiganalytics.metadata.api.feed.Feed> domainFeeds = feedProvider.getFeeds(criteria);
return domainFeeds.stream().map(metadataTransform.domainToFeed()).collect(Collectors.toList());
});
}
@GET
@Path("{id}")
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation("Gets the specified feed.")
@ApiResponses({
@ApiResponse(code = 200, message = "Returns the feed.", response = Feed.class),
@ApiResponse(code = 400, message = "The id is not a valid UUID.", response = RestResponseStatus.class),
@ApiResponse(code = 500, message = "The feed could not be found.", response = RestResponseStatus.class)
})
public Feed getFeed(@PathParam("id") final String feedId) {
LOG.debug("Get feed {}", feedId);
return this.metadata.read(() -> {
this.accessController.checkPermission(AccessController.SERVICES, FeedServicesAccessControl.ACCESS_FEEDS);
com.thinkbiganalytics.metadata.api.feed.Feed.ID domainId = feedProvider.resolveFeed(feedId);
com.thinkbiganalytics.metadata.api.feed.Feed domain = feedProvider.getFeed(domainId);
return this.metadataTransform.domainToFeed().apply(domain);
});
}
/*
@GET
@Path("{id}/op")
@Produces(MediaType.APPLICATION_JSON)
public List<FeedOperation> getFeedOperations(@PathParam("id") final String feedId,
@QueryParam("since") @DefaultValue("1970-01-01T00:00:00Z") String sinceStr,
@QueryParam("limit") @DefaultValue("-1") int limit) {
final DateTime since = Formatters.parseDateTime(sinceStr);
return this.metadata.read(() -> {
this.accessController.checkPermission(AccessController.SERVICES, FeedServicesAccessControl.ACCESS_FEEDS);
com.thinkbiganalytics.metadata.api.feed.Feed.ID domainId = feedProvider.resolveFeed(feedId);
FeedOperationCriteria criteria = feedOpsProvider.criteria()
.feed(domainId)
.stoppedSince(since)
.state(State.SUCCESS);
List<com.thinkbiganalytics.metadata.api.op.FeedOperation> list = feedOpsProvider.find(criteria);
return list.stream().map(op -> Model.DOMAIN_TO_FEED_OP.apply(op)).collect(Collectors.toList());
});
}
@GET
@Path("{id}/op/results")
@Produces(MediaType.APPLICATION_JSON)
public Map<DateTime, Map<String, Object>> collectFeedOperationsResults(@PathParam("id") final String feedId,
@QueryParam("since") @DefaultValue("1970-01-01T00:00:00Z") String sinceStr) {
final DateTime since = Formatters.TIME_FORMATTER.parseDateTime(sinceStr);
return this.metadata.read(() -> {
this.accessController.checkPermission(AccessController.SERVICES, FeedServicesAccessControl.ACCESS_FEEDS);
com.thinkbiganalytics.metadata.api.feed.Feed.ID domainId = feedProvider.resolveFeed(feedId);
FeedOperationCriteria criteria = feedOpsProvider.criteria()
.feed(domainId)
.stoppedSince(since)
.state(State.SUCCESS);
Map<DateTime, Map<String, Object>> results = feedOpsProvider.getAllResults(criteria, null);
return results.entrySet().stream()
.collect(Collectors.toMap(te -> te.getKey(),
te -> (Map<String, Object>) te.getValue().entrySet().stream()
.collect(Collectors.toMap(ve -> ve.getKey(),
ve -> (Object) ve.getValue().toString()))));
});
}
*/
@GET
@Path("{id}/depfeeds")
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation("Gets the dependencies of the specified feed.")
@ApiResponses({
@ApiResponse(code = 200, message = "Returns the dependency graph.", response = FeedDependencyGraph.class),
@ApiResponse(code = 404, message = "The feed could not be found.", response = RestResponseStatus.class)
})
public FeedDependencyGraph getDependencyGraph(@PathParam("id") final String feedId,
@QueryParam("preconds") @DefaultValue("false") final boolean assessPrecond) {
LOG.debug("Get feed dependencies {}", feedId);
return this.metadata.read(() -> {
this.accessController.checkPermission(AccessController.SERVICES, FeedServicesAccessControl.ACCESS_FEEDS);
com.thinkbiganalytics.metadata.api.feed.Feed.ID domainId = feedProvider.resolveFeed(feedId);
com.thinkbiganalytics.metadata.api.feed.Feed startDomain = feedProvider.getFeed(domainId);
if (startDomain != null) {
return collectFeedDependencies(startDomain, assessPrecond);
} else {
throw new WebApplicationException("A feed with the given ID does not exist: " + feedId, Status.NOT_FOUND);
}
});
}
@POST
@Path("{feedId}/depfeeds")
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation("Adds a dependency to the specified feed.")
@ApiResponses({
@ApiResponse(code = 200, message = "Returns the new dependency graph.", response = FeedDependencyGraph.class),
@ApiResponse(code = 500, message = "The dependency could not be added.", response = RestResponseStatus.class)
})
public FeedDependencyGraph addDependent(@PathParam("feedId") final String feedIdStr,
@QueryParam("dependentId") final String depIdStr) {
com.thinkbiganalytics.metadata.api.feed.Feed.ID feedId = this.feedProvider.resolveFeed(feedIdStr);
com.thinkbiganalytics.metadata.api.feed.Feed.ID depId = this.feedProvider.resolveFeed(depIdStr);
this.metadata.commit(() -> {
this.accessController.checkPermission(AccessController.SERVICES, FeedServicesAccessControl.EDIT_FEEDS);
this.feedProvider.addDependent(feedId, depId);
return null;
});
return getDependencyGraph(feedId.toString(), false);
}
@DELETE
@Path("{feedId}/depfeeds")
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation("Removes a dependency from the specified feed.")
@ApiResponses({
@ApiResponse(code = 200, message = "Returns the new dependency graph.", response = FeedDependencyGraph.class),
@ApiResponse(code = 500, message = "The dependency could not be removed.", response = RestResponseStatus.class)
})
public FeedDependencyGraph removeDependent(@PathParam("feedId") final String feedIdStr,
@QueryParam("dependentId") final String depIdStr) {
com.thinkbiganalytics.metadata.api.feed.Feed.ID feedId = this.feedProvider.resolveFeed(feedIdStr);
com.thinkbiganalytics.metadata.api.feed.Feed.ID depId = this.feedProvider.resolveFeed(depIdStr);
this.metadata.commit(() -> {
this.accessController.checkPermission(AccessController.SERVICES, FeedServicesAccessControl.EDIT_FEEDS);
this.feedProvider.removeDependent(feedId, depId);
return null;
});
return getDependencyGraph(feedId.toString(), false);
}
@GET
@Path("{feedId}/depfeeds/delta")
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation("Gets the dependencies delta for the specified feed.")
@ApiResponses({
@ApiResponse(code = 200, message = "Returns the dependencies deltas.", response = FeedDependencyDeltaResults.class),
@ApiResponse(code = 500, message = "The feed could not be found.", response = RestResponseStatus.class)
})
public FeedDependencyDeltaResults getDependentResultDeltas(@PathParam("feedId") final String feedIdStr) {
LOG.info("Get feed dependencies delta for {}", feedIdStr);
com.thinkbiganalytics.metadata.api.feed.Feed.ID feedId = this.feedProvider.resolveFeed(feedIdStr);
return this.metadata.read(() -> {
this.accessController.checkPermission(AccessController.SERVICES, FeedServicesAccessControl.ACCESS_FEEDS);
FeedDependencyDeltaResults results = this.feedOpsProvider.getDependentDeltaResults(feedId, null);
return results;
});
}
@GET
@Path("{id}/source")
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation("Gets the sources of the specified feed.")
@ApiResponses({
@ApiResponse(code = 200, message = "Returns the feed sources.", response = FeedSource.class, responseContainer = "List"),
@ApiResponse(code = 400, message = "The id is not a valid UUID.", response = RestResponseStatus.class),
@ApiResponse(code = 404, message = "The feed could not be found.", response = RestResponseStatus.class)
})
public List<FeedSource> getFeedSources(@PathParam("id") final String feedId) {
LOG.debug("Get feed {} sources", feedId);
return this.metadata.read(() -> {
this.accessController.checkPermission(AccessController.SERVICES, FeedServicesAccessControl.ACCESS_FEEDS);
com.thinkbiganalytics.metadata.api.feed.Feed.ID domainId = feedProvider.resolveFeed(feedId);
com.thinkbiganalytics.metadata.api.feed.Feed domain = feedProvider.getFeed(domainId);
if (domain != null) {
return domain.getSources().stream().map(this.metadataTransform.domainToFeedSource()).collect(Collectors.toList());
} else {
throw new WebApplicationException("A feed with the given ID does not exist: " + feedId, Status.NOT_FOUND);
}
});
}
//
// @GET
// @Path("{fid}/source/{sid}")
// @Produces(MediaType.APPLICATION_JSON)
// public FeedSource getFeedSource(@PathParam("fid") final String feedId, @PathParam("sid") final String srcId) {
// LOG.debug("Get feed {} source {}", feedId, srcId);
//
// return this.metadata.read(() -> {
// com.thinkbiganalytics.metadata.api.feed.Feed.ID domainId = feedProvider.resolveFeed(feedId);
// com.thinkbiganalytics.metadata.api.feed.FeedSource.ID domainSrcId = feedProvider.resolveSource(srcId);
// com.thinkbiganalytics.metadata.api.feed.Feed domain = feedProvider.getFeed(domainId);
//
// if (domain != null) {
// com.thinkbiganalytics.metadata.api.feed.FeedSource domainSrc = domain.getSource(domainSrcId);
//
// if (domainSrc != null) {
// return Model.domainToFeedSource.apply(domainSrc);
// } else {
// throw new WebApplicationException("A feed source with the given ID does not exist: " + srcId, Status.NOT_FOUND);
// }
// } else {
// throw new WebApplicationException("A feed with the given ID does not exist: " + feedId, Status.NOT_FOUND);
// }
// });
// }
@GET
@Path("{id}/destination")
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation("Gets the destinations of the specified feed.")
@ApiResponses({
@ApiResponse(code = 200, message = "Returns the feed destinations.", response = FeedDestination.class, responseContainer = "List"),
@ApiResponse(code = 400, message = "The id is not a valid UUID.", response = RestResponseStatus.class),
@ApiResponse(code = 404, message = "The feed could not be found.", response = RestResponseStatus.class)
})
public List<FeedDestination> getFeedDestinations(@PathParam("id") final String feedId) {
LOG.debug("Get feed {} destinations", feedId);
return this.metadata.read(() -> {
this.accessController.checkPermission(AccessController.SERVICES, FeedServicesAccessControl.ACCESS_FEEDS);
com.thinkbiganalytics.metadata.api.feed.Feed.ID domainId = feedProvider.resolveFeed(feedId);
com.thinkbiganalytics.metadata.api.feed.Feed domain = feedProvider.getFeed(domainId);
if (domain != null) {
return domain.getDestinations().stream().map(this.metadataTransform.domainToFeedDestination()).collect(Collectors.toList());
} else {
throw new WebApplicationException("A feed with the given ID does not exist: " + feedId, Status.NOT_FOUND);
}
});
}
//
// @GET
// @Path("{fid}/destination/{sid}")
// @Produces(MediaType.APPLICATION_JSON)
// public FeedDestination getFeedDestination(@PathParam("fid") final String feedId, @PathParam("sid") final String destId) {
// LOG.debug("Get feed {} destination {}", feedId, destId);
//
// return this.metadata.read(() -> {
// com.thinkbiganalytics.metadata.api.feed.Feed.ID domainId = feedProvider.resolveFeed(feedId);
// com.thinkbiganalytics.metadata.api.feed.FeedDestination.ID domainDestId = feedProvider.resolveDestination(destId);
// com.thinkbiganalytics.metadata.api.feed.Feed domain = feedProvider.getFeed(domainId);
//
// if (domain != null) {
// com.thinkbiganalytics.metadata.api.feed.FeedDestination domainDest = domain.getDestination(domainDestId);
//
// if (domainDest != null) {
// return Model.domainToFeedDestination.apply(domainDest);
// } else {
// throw new WebApplicationException("A feed destination with the given ID does not exist: " + destId, Status.NOT_FOUND);
// }
// } else {
// throw new WebApplicationException("A feed with the given ID does not exist: " + feedId, Status.NOT_FOUND);
// }
// });
// }
@GET
@Path("{id}/precondition")
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation("Gets the precondition for the specified feed.")
@ApiResponses({
@ApiResponse(code = 200, message = "Returns the feed precondition.", response = FeedPrecondition.class),
@ApiResponse(code = 400, message = "The id is not a valid UUID.", response = RestResponseStatus.class),
@ApiResponse(code = 404, message = "The feed could not be found.", response = RestResponseStatus.class)
})
public FeedPrecondition getFeedPrecondition(@PathParam("id") final String feedId) {
LOG.debug("Get feed {} precondition", feedId);
return this.metadata.read(() -> {
this.accessController.checkPermission(AccessController.SERVICES, FeedServicesAccessControl.ACCESS_FEEDS);
com.thinkbiganalytics.metadata.api.feed.Feed.ID domainId = feedProvider.resolveFeed(feedId);
com.thinkbiganalytics.metadata.api.feed.Feed domain = feedProvider.getFeed(domainId);
if (domain != null) {
return this.metadataTransform.domainToFeedPrecond().apply(domain.getPrecondition());
} else {
throw new WebApplicationException("A feed with the given ID does not exist: " + feedId, Status.NOT_FOUND);
}
});
}
@GET
@Path("{id}/precondition/assessment")
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation("Assess the precondition of the specified feed.")
@ApiResponses({
@ApiResponse(code = 200, message = "Returns the assessment.", response = ServiceLevelAssessment.class),
@ApiResponse(code = 400, message = "The id is not a valid UUID or the feed does not have a precondition.", response = RestResponseStatus.class),
@ApiResponse(code = 404, message = "The feed could not be found.", response = RestResponseStatus.class)
})
public ServiceLevelAssessment assessPrecondition(@PathParam("id") final String feedId) {
LOG.debug("Assess feed {} precondition", feedId);
return this.metadata.read(() -> {
this.accessController.checkPermission(AccessController.SERVICES, FeedServicesAccessControl.ACCESS_FEEDS);
com.thinkbiganalytics.metadata.api.feed.Feed.ID domainId = feedProvider.resolveFeed(feedId);
com.thinkbiganalytics.metadata.api.feed.Feed domain = feedProvider.getFeed(domainId);
if (domain != null) {
com.thinkbiganalytics.metadata.api.feed.FeedPrecondition precond = domain.getPrecondition();
if (precond != null) {
return generateModelAssessment(precond);
} else {
throw new WebApplicationException("The feed with the given ID does not have a precondition: " + feedId, Status.BAD_REQUEST);
}
} else {
throw new WebApplicationException("A feed with the given ID does not exist: " + feedId, Status.NOT_FOUND);
}
});
}
@GET
@Path("{id}/precondition/assessment/result")
@Produces(MediaType.TEXT_PLAIN)
@ApiOperation("Assess the precondition of the specified feed.")
@ApiResponses({
@ApiResponse(code = 200, message = "Returns the assessment result.", response = ServiceLevelAssessment.class),
@ApiResponse(code = 400, message = "The id is not a valid UUID or the feed does not have a precondition.", response = RestResponseStatus.class),
@ApiResponse(code = 404, message = "The feed could not be found.", response = RestResponseStatus.class)
})
public String assessPreconditionResult(@PathParam("id") final String feedId) {
return assessPrecondition(feedId).getResult().toString();
}
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation("Creates a new feed.")
@ApiResponses({
@ApiResponse(code = 200, message = "The feed was created.", response = Feed.class),
@ApiResponse(code = 400, message = "The name is already in use.", response = RestResponseStatus.class),
@ApiResponse(code = 500, message = "The feed could not be created.", response = RestResponseStatus.class)
})
public Feed createFeed(final Feed feed, @QueryParam("ensure") @DefaultValue("true") final boolean ensure) {
LOG.debug("Create feed (ensure={}) {}", ensure, feed);
this.metadataTransform.validateCreate(feed);
return this.metadata.commit(() -> {
this.accessController.checkPermission(AccessController.SERVICES, FeedServicesAccessControl.EDIT_FEEDS);
com.thinkbiganalytics.metadata.api.feed.FeedCriteria crit = feedProvider.feedCriteria().name(feed.getSystemName()).category(feed.getCategory().getSystemName());
Collection<com.thinkbiganalytics.metadata.api.feed.Feed> existing = feedProvider.getFeeds(crit);
if (existing.isEmpty()) {
com.thinkbiganalytics.metadata.api.feed.Feed domainFeed = feedProvider.ensureFeed(feed.getCategory().getSystemName(), feed.getSystemName(), feed.getDescription());
ensureDependentDatasources(feed, domainFeed);
ensurePrecondition(feed, domainFeed);
ensureProperties(feed, domainFeed);
return this.metadataTransform.domainToFeed().apply(feedProvider.getFeed(domainFeed.getId()));
} else if (ensure) {
return this.metadataTransform.domainToFeed().apply(existing.iterator().next());
} else {
throw new WebApplicationException("A feed with the given name already exists: " + feed.getSystemName(), Status.BAD_REQUEST);
}
});
}
/**
* Updates an existing feed. Note that POST is used here rather than PUT since it behaves more like a PATCH; which isn't supported in Jersey.
*/
@POST
@Path("{id}")
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation("Updates the specified feed.")
@ApiResponses({
@ApiResponse(code = 200, message = "The feed was updated.", response = Feed.class),
@ApiResponse(code = 404, message = "The feed was not found.", response = RestResponseStatus.class),
@ApiResponse(code = 500, message = "The feed could not be updated.", response = RestResponseStatus.class)
})
public Feed updateFeed(@PathParam("id") final String feedId, final Feed feed) {
LOG.debug("Update feed: {}", feed);
this.metadataTransform.validateCreate(feed);
return this.metadata.commit(() -> {
this.accessController.checkPermission(AccessController.SERVICES, FeedServicesAccessControl.EDIT_FEEDS);
com.thinkbiganalytics.metadata.api.feed.Feed.ID domainId = feedProvider.resolveFeed(feedId);
com.thinkbiganalytics.metadata.api.feed.Feed domain = feedProvider.getFeed(domainId);
if (domain != null) {
domain = this.metadataTransform.updateDomain(feed, domain);
return this.metadataTransform.domainToFeed().apply(domain);
} else {
throw new WebApplicationException("No feed exist with the ID: " + feed.getId(), Status.NOT_FOUND);
}
});
}
/**
* Gets the properties for the specified feed.
*
* @param feedId the feed id or the feed category and name
* @return the metadata properties
*/
@GET
@Path("{id}/props")
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation("Gets the properties of the specified feed.")
@ApiResponses({
@ApiResponse(code = 200, message = "Returns the feed properties.", response = Map.class),
@ApiResponse(code = 400, message = "The id is not a valid UUID.", response = RestResponseStatus.class),
@ApiResponse(code = 404, message = "The feed was not found.", response = RestResponseStatus.class)
})
public Map<String, Object> getFeedProperties(@PathParam("id") final String feedId) {
LOG.debug("Get feed properties ID: {}", feedId);
return this.metadata.read(() -> {
this.accessController.checkPermission(AccessController.SERVICES, FeedServicesAccessControl.ACCESS_FEEDS);
String[] parts = feedId.split("\\.", 2);
com.thinkbiganalytics.metadata.api.feed.Feed domain = (parts.length == 2) ? feedProvider.findBySystemName(parts[0], parts[1]) : feedProvider.getFeed(feedProvider.resolveFeed(feedId));
if (domain != null) {
return domain.getProperties();
} else {
throw new WebApplicationException("No feed exist with the ID: " + feedId, Status.NOT_FOUND);
}
});
}
/**
* Merges the properties for the specified feeds. New properties will be added and existing properties will be overwritten.
*
* @param feedId the feed id or the feed category and name
* @param props the properties to be merged
* @return the merged metadata properties
*/
@POST
@Path("{id}/props")
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation("Merges the properties for the specified feed.")
@ApiResponses({
@ApiResponse(code = 200, message = "Returns the updated properties.", response = Map.class),
@ApiResponse(code = 400, message = "The id is not a valid UUID.", response = RestResponseStatus.class),
@ApiResponse(code = 404, message = "The feed could not be found.", response = RestResponseStatus.class),
@ApiResponse(code = 500, message = "The properties could not be updated.", response = RestResponseStatus.class)
})
public Map<String, Object> mergeFeedProperties(@PathParam("id") final String feedId, final Properties props) {
LOG.debug("Merge feed properties ID: {}, properties: {}", feedId, props);
return this.metadata.commit(() -> {
String[] parts = feedId.split("\\.", 2);
com.thinkbiganalytics.metadata.api.feed.Feed domain = (parts.length == 2) ? feedProvider.findBySystemName(parts[0], parts[1]) : feedProvider.getFeed(feedProvider.resolveFeed(feedId));
if (domain != null) {
return updateProperties(props, domain, false);
} else {
throw new WebApplicationException("No feed exist with the ID: " + feedId, Status.NOT_FOUND);
}
});
}
@PUT
@Path("{id}/props")
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation("Sets the properties for the specified feed.")
@ApiResponses({
@ApiResponse(code = 200, message = "Returns the updated properties.", response = Properties.class),
@ApiResponse(code = 400, message = "The id is not a valid UUID.", response = RestResponseStatus.class),
@ApiResponse(code = 404, message = "The feed could not be found.", response = RestResponseStatus.class),
@ApiResponse(code = 500, message = "The properties could not be updated.", response = RestResponseStatus.class)
})
public Properties replaceFeedProperties(@PathParam("id") final String feedId,
final Properties props) {
LOG.debug("Replace feed properties ID: {}, properties: {}", feedId, props);
return this.metadata.commit(() -> {
this.accessController.checkPermission(AccessController.SERVICES, FeedServicesAccessControl.EDIT_FEEDS);
com.thinkbiganalytics.metadata.api.feed.Feed.ID domainId = feedProvider.resolveFeed(feedId);
com.thinkbiganalytics.metadata.api.feed.Feed domain = feedProvider.getFeed(domainId);
if (domain != null) {
Map<String, Object> domainProps = updateProperties(props, domain, true);
Properties newProps = new Properties();
newProps.putAll(domainProps);
return newProps;
} else {
throw new WebApplicationException("No feed exist with the ID: " + feedId, Status.NOT_FOUND);
}
});
}
@GET
@Path("{feedId}/lineage")
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation("Gets the lineage of the specified feed.")
@ApiResponses({
@ApiResponse(code = 200, message = "Returns the feed lineage.", response = FeedLineage.class),
@ApiResponse(code = 400, message = "The id is not a valid UUID.", response = RestResponseStatus.class)
})
public FeedLineage getFeedLineage(@PathParam("feedId") final String feedId) {
return this.metadata.read(() -> {
com.thinkbiganalytics.metadata.api.feed.Feed domainFeed = feedProvider.getFeed(feedProvider.resolveFeed(feedId));
if (domainFeed != null) {
FeedLineageBuilder builder = new FeedLineageBuilder(domainFeed, model, datasourceTransform);
Feed feed = builder.build();//Model.DOMAIN_TO_FEED_WITH_DEPENDENCIES.apply(domainFeed);
return new FeedLineage(feed, datasourceService.getFeedLineageStyleMap());
}
return null;
});
}
/*
@GET
@Path("remove-sources")
@Produces(MediaType.APPLICATION_JSON)
public RestResponseStatus removeSources(){
try {
this.metadata.commit(() -> {
List<? extends com.thinkbiganalytics.metadata.api.feed.Feed> feeds = feedProvider.getFeeds();
feeds.stream().forEach(feed -> {
feedProvider.removeFeedSources(feed.getId());
});
}, MetadataAccess.SERVICE);
}catch (Exception e){
e.printStackTrace();
}
this.metadata.commit(() -> {
List<? extends com.thinkbiganalytics.metadata.api.feed.Feed> feeds = feedProvider.getFeeds();
feeds.stream().forEach(feed -> {
feedProvider.removeFeedDestinations(feed.getId());
});
}, MetadataAccess.SERVICE);
this.metadata.commit(() -> {
List<Datasource> datasources = datasetProvider.getDatasources();
datasources.stream().forEach(datasource -> {
datasetProvider.removeDatasource(datasource.getId());
});
}, MetadataAccess.SERVICE);
return new RestResponseStatus.ResponseStatusBuilder().buildSuccess();
}
*/
@POST
@Path("{feedId}/source")
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation("Adds a source to the specified feed.")
@ApiResponses({
@ApiResponse(code = 200, message = "Returns the updated feed.", response = Feed.class),
@ApiResponse(code = 400, message = "The feed could not be found.", response = RestResponseStatus.class),
@ApiResponse(code = 500, message = "The feed could not be updated.", response = RestResponseStatus.class)
})
public Feed addFeedSource(@PathParam("feedId") final String feedId,
@FormParam("datasourceId") final String datasourceId) {
LOG.debug("Add feed source, feed ID: {}, datasource ID: {}", feedId, datasourceId);
return this.metadata.commit(() -> {
com.thinkbiganalytics.metadata.api.feed.Feed.ID domainFeedId = feedProvider.resolveFeed(feedId);
Datasource.ID domainDsId = datasetProvider.resolve(datasourceId);
com.thinkbiganalytics.metadata.api.feed.FeedSource domainDest = feedProvider.ensureFeedSource(domainFeedId, domainDsId);
return this.metadataTransform.domainToFeed().apply(domainDest.getFeed());
});
}
@POST
@Path("{feedId}/destination")
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation("Adds a destination to the specified feed.")
@ApiResponses({
@ApiResponse(code = 200, message = "Returns the updated feed.", response = Feed.class),
@ApiResponse(code = 400, message = "The feed could not be found.", response = RestResponseStatus.class),
@ApiResponse(code = 500, message = "The feed could not be updated.", response = RestResponseStatus.class)
})
public Feed addFeedDestination(@PathParam("feedId") final String feedId,
@FormParam("datasourceId") final String datasourceId) {
LOG.debug("Add feed destination, feed ID: {}, datasource ID: {}", feedId, datasourceId);
return this.metadata.commit(() -> {
this.accessController.checkPermission(AccessController.SERVICES, FeedServicesAccessControl.EDIT_FEEDS);
com.thinkbiganalytics.metadata.api.feed.Feed.ID domainFeedId = feedProvider.resolveFeed(feedId);
Datasource.ID domainDsId = datasetProvider.resolve(datasourceId);
com.thinkbiganalytics.metadata.api.feed.FeedDestination domainDest = feedProvider.ensureFeedDestination(domainFeedId, domainDsId);
return this.metadataTransform.domainToFeed().apply(domainDest.getFeed());
});
}
@POST
@Path("{feedId}/precondition")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@ApiOperation("Adds a precondition to the specified feed.")
@ApiResponses({
@ApiResponse(code = 200, message = "Returns the updated feed.", response = Feed.class),
@ApiResponse(code = 400, message = "The feed could not be found.", response = RestResponseStatus.class),
@ApiResponse(code = 500, message = "The feed could not be updated.", response = RestResponseStatus.class)
})
public Feed setPrecondition(@PathParam("feedId") final String feedId, final FeedPrecondition precond) {
LOG.debug("Add feed precondition, feed ID: {}, precondition: {}", feedId, precond);
return this.metadata.commit(() -> {
this.accessController.checkPermission(AccessController.SERVICES, FeedServicesAccessControl.EDIT_FEEDS);
com.thinkbiganalytics.metadata.api.feed.Feed.ID domainFeedId = feedProvider.resolveFeed(feedId);
List<com.thinkbiganalytics.metadata.sla.api.Metric> domainMetrics
= precond.getSla().getObligations().stream()
.flatMap((grp) -> grp.getMetrics().stream())
.map((metric) -> metric)
.collect(Collectors.toList());
com.thinkbiganalytics.metadata.api.feed.Feed domainFeed
= feedProvider.createPrecondition(domainFeedId, "", domainMetrics);
return this.metadataTransform.domainToFeed().apply(domainFeed);
});
}
private Map<String, Object> updateProperties(final Properties props,
com.thinkbiganalytics.metadata.api.feed.Feed domain,
boolean replace) {
return metadata.commit(() -> {
Map<String, Object> newProperties = new HashMap<String, Object>();
for (String name : props.stringPropertyNames()) {
newProperties.put(name, props.getProperty(name));
}
if (replace) {
feedProvider.replaceProperties(domain.getId(), newProperties);
} else {
feedProvider.mergeFeedProperties(domain.getId(), newProperties);
}
return domain.getProperties();
});
}
private ServiceLevelAssessment generateModelAssessment(com.thinkbiganalytics.metadata.api.feed.FeedPrecondition precond) {
com.thinkbiganalytics.metadata.sla.api.ServiceLevelAssessment assmt = this.preconditionService.assess(precond);
return ServiceLevelAgreementModelTransform.DOMAIN_TO_SLA_ASSMT.apply(assmt);
}
private void ensurePrecondition(Feed feed, com.thinkbiganalytics.metadata.api.feed.Feed domainFeed) {
FeedPrecondition precond = feed.getPrecondition();
if (precond != null) {
List<com.thinkbiganalytics.metadata.sla.api.Metric> domainMetrics
= precond.getSla().getObligations().stream()
.flatMap((grp) -> grp.getMetrics().stream())
.map((metric) -> metric)
.collect(Collectors.toList());
feedProvider.createPrecondition(domainFeed.getId(), "", domainMetrics);
}
}
private void ensureDependentDatasources(Feed feed, com.thinkbiganalytics.metadata.api.feed.Feed domainFeed) {
for (FeedSource src : feed.getSources()) {
Datasource.ID dsId = this.datasetProvider.resolve(src.getId());
feedProvider.ensureFeedSource(domainFeed.getId(), dsId);
}
for (FeedDestination src : feed.getDestinations()) {
Datasource.ID dsId = this.datasetProvider.resolve(src.getId());
feedProvider.ensureFeedDestination(domainFeed.getId(), dsId);
}
}
private void ensureProperties(Feed feed, com.thinkbiganalytics.metadata.api.feed.Feed domainFeed) {
Map<String, Object> domainProps = domainFeed.getProperties();
Properties props = feed.getProperties();
for (String key : feed.getProperties().stringPropertyNames()) {
domainProps.put(key, props.getProperty(key));
}
}
private com.thinkbiganalytics.metadata.api.feed.FeedCriteria createFeedCriteria(String category,
String name,
String srcId,
String destId) {
com.thinkbiganalytics.metadata.api.feed.FeedCriteria criteria = feedProvider.feedCriteria();
if (StringUtils.isNotEmpty(category)) {
criteria.category(category);
}
if (StringUtils.isNotEmpty(name)) {
criteria.name(name);
}
if (StringUtils.isNotEmpty(srcId)) {
Datasource.ID dsId = this.datasetProvider.resolve(srcId);
criteria.sourceDatasource(dsId);
}
if (StringUtils.isNotEmpty(destId)) {
Datasource.ID dsId = this.datasetProvider.resolve(destId);
criteria.destinationDatasource(dsId);
}
return criteria;
}
private FeedDependencyGraph collectFeedDependencies(com.thinkbiganalytics.metadata.api.feed.Feed currentFeed, boolean assessPrecond) {
List<com.thinkbiganalytics.metadata.api.feed.Feed> domainDeps = currentFeed.getDependentFeeds();
FeedDependencyGraph feedDep = new FeedDependencyGraph(this.metadataTransform.domainToFeed().apply(currentFeed), null);
if (!domainDeps.isEmpty()) {
for (com.thinkbiganalytics.metadata.api.feed.Feed depFeed : domainDeps) {
FeedDependencyGraph childDep = collectFeedDependencies(depFeed, assessPrecond);
feedDep.addDependecy(childDep);
}
}
if (assessPrecond && currentFeed.getPrecondition() != null) {
feedDep.setPreconditonResult(generateModelAssessment(currentFeed.getPrecondition()));
}
return feedDep;
}
}