/** * */ package com.thinkbiganalytics.metadata.modeshape.feed; /*- * #%L * kylo-metadata-modeshape * %% * 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 java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; import javax.jcr.Node; import javax.jcr.NodeIterator; import javax.jcr.RepositoryException; import org.joda.time.DateTime; import com.thinkbiganalytics.metadata.api.feed.Feed; import com.thinkbiganalytics.metadata.api.feed.Feed.State; import com.thinkbiganalytics.metadata.api.security.HadoopSecurityGroup; import com.thinkbiganalytics.metadata.api.feed.InitializationStatus; import com.thinkbiganalytics.metadata.modeshape.MetadataRepositoryException; import com.thinkbiganalytics.metadata.modeshape.common.JcrPropertiesEntity; import com.thinkbiganalytics.metadata.modeshape.security.JcrHadoopSecurityGroup; import com.thinkbiganalytics.metadata.modeshape.support.JcrPropertyUtil; import com.thinkbiganalytics.metadata.modeshape.support.JcrUtil; import com.thinkbiganalytics.metadata.sla.api.ServiceLevelAgreement; /** * */ public class FeedData extends JcrPropertiesEntity { public static final String NODE_TYPE = "tba:feedData"; public static final String HIGH_WATER_MARKS = "tba:highWaterMarks"; public static final String WATER_MARKS_TYPE = "tba:waterMarks"; public static final String INITIALIZATION_TYPE = "tba:initialization"; public static final String INIT_STATUS_TYPE = "tba:initStatus"; public static final String INITIALIZATION = "tba:initialization"; public static final String INIT_HISTORY = "tba:history"; public static final int MAX_INIT_HISTORY = 10; public static final String INIT_STATE = "tba:state"; public static final String CURRENT_INIT_STATUS = "tba:currentStatus"; public static final String STATE = INIT_STATE; public static final String SCHEDULE_PERIOD = "tba:schedulingPeriod"; // Cron expression, or Timer Expression public static final String SCHEDULE_STRATEGY = "tba:schedulingStrategy"; //CRON_DRIVEN, TIMER_DRIVEN public static final String HADOOP_SECURITY_GROUPS = "tba:securityGroups"; public static final String USR_PREFIX = "usr:"; public FeedData(Node node) { super(node); } public State getState() { return getProperty(STATE, Feed.State.ENABLED); } public void setState(State state) { setProperty(STATE, state); } public boolean isInitialized() { // TODO this smells like a bug return false; } public InitializationStatus getCurrentInitStatus() { if (JcrUtil.hasNode(getNode(), INITIALIZATION)) { Node initNode = JcrUtil.getNode(getNode(), INITIALIZATION); Node statusNode = JcrPropertyUtil.getProperty(initNode, CURRENT_INIT_STATUS); return createInitializationStatus(statusNode); } else { return new InitializationStatus(InitializationStatus.State.PENDING); } } public void updateInitStatus(InitializationStatus status) { try { Node initNode = JcrUtil.getOrCreateNode(getNode(), INITIALIZATION, INITIALIZATION, true); Node statusNode = initNode.addNode(INIT_HISTORY, INIT_STATUS_TYPE); statusNode.setProperty(INIT_STATE, status.getState().toString()); initNode.setProperty(CURRENT_INIT_STATUS, statusNode); // Trim the history if necessary NodeIterator itr = initNode.getNodes(INIT_HISTORY); if (itr.getSize() > MAX_INIT_HISTORY) { long excess = itr.getSize() - MAX_INIT_HISTORY; for (int cnt = 0; cnt < excess; cnt++) { Node node = itr.nextNode(); node.remove(); } } } catch (RepositoryException e) { throw new MetadataRepositoryException("Failed to access initializations statuses", e); } } public List<InitializationStatus> getInitHistory() { Node initNode = JcrUtil.getNode(getNode(), INITIALIZATION); if (initNode != null) { return JcrUtil.getNodeList(initNode, INIT_HISTORY).stream() .map(n -> createInitializationStatus(n)) .sorted(Comparator.comparing(InitializationStatus::getTimestamp).reversed()) .limit(MAX_INIT_HISTORY) .collect(Collectors.toList()); } else { return Collections.emptyList(); } } public Set<String> getWaterMarkNames() { if (JcrUtil.hasNode(getNode(), HIGH_WATER_MARKS)) { Node wmNode = JcrUtil.getNode(getNode(), HIGH_WATER_MARKS); return JcrPropertyUtil.streamProperties(wmNode) .map(JcrPropertyUtil::getName) .filter(name -> name.startsWith(USR_PREFIX)) .map(name -> name.replace(USR_PREFIX, "")) .collect(Collectors.toSet()); } else { return Collections.emptySet(); } } public Optional<String> getWaterMarkValue(String waterMarkName) { if (JcrUtil.hasNode(getNode(), HIGH_WATER_MARKS)) { Node wmNode = JcrUtil.getNode(getNode(), HIGH_WATER_MARKS); return JcrPropertyUtil.findProperty(wmNode, USR_PREFIX + waterMarkName).map(JcrPropertyUtil::toString); } else { return Optional.empty(); } } public void setWaterMarkValue(String waterMarkName, String value) { Node wmNode = JcrUtil.getOrCreateNode(getNode(), HIGH_WATER_MARKS, WATER_MARKS_TYPE); JcrPropertyUtil.setProperty(wmNode, USR_PREFIX + waterMarkName, value); } public String getSchedulePeriod() { return getProperty(SCHEDULE_PERIOD, String.class); } public void setSchedulePeriod(String schedulePeriod) { setProperty(SCHEDULE_PERIOD, schedulePeriod); } public String getScheduleStrategy() { return getProperty(SCHEDULE_STRATEGY, String.class); } public void setScheduleStrategy(String scheduleStrategy) { setProperty(SCHEDULE_STRATEGY, scheduleStrategy); } public List<? extends HadoopSecurityGroup> getSecurityGroups() { Set<Node> list = JcrPropertyUtil.getReferencedNodeSet(this.node, HADOOP_SECURITY_GROUPS); List<HadoopSecurityGroup> hadoopSecurityGroups = new ArrayList<>(); if (list != null) { for (Node n : list) { hadoopSecurityGroups.add(JcrUtil.createJcrObject(n, JcrHadoopSecurityGroup.class)); } } return hadoopSecurityGroups; } public void setSecurityGroups(List<? extends HadoopSecurityGroup> hadoopSecurityGroups) { JcrPropertyUtil.setProperty(this.node, HADOOP_SECURITY_GROUPS, null); for (HadoopSecurityGroup securityGroup : hadoopSecurityGroups) { Node securityGroupNode = ((JcrHadoopSecurityGroup) securityGroup).getNode(); JcrPropertyUtil.addToSetProperty(this.node, HADOOP_SECURITY_GROUPS, securityGroupNode, true); } } private InitializationStatus createInitializationStatus(Node statusNode) { InitializationStatus.State state = InitializationStatus.State.valueOf(JcrPropertyUtil.getString(statusNode, INIT_STATE)); DateTime timestamp = JcrPropertyUtil.getProperty(statusNode, "jcr:created"); return new InitializationStatus(state, timestamp); } }