/* * Copyright (c) 2015 Huawei, Inc and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ package org.opendaylight.nic.nemo.renderer; import java.math.BigDecimal; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.annotation.concurrent.Immutable; import org.joda.time.LocalTime; import org.joda.time.Period; import org.joda.time.format.ISODateTimeFormat; import org.joda.time.format.ISOPeriodFormat; import org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.Actions; import org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.Conditions; import org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.Constraints; import org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.Subjects; import org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.actions.Action; import org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.actions.action.Allow; import org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.conditions.condition.Daily; import org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.constraints.constraints.BandwidthConstraint; import org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intent.subjects.subject.EndPointGroup; import org.opendaylight.yang.gen.v1.urn.opendaylight.intent.rev150122.intents.Intent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.base.Function; import com.google.common.collect.Ordering; /** * * @author gwu * */ public class NEMOIntentParser { private static final Logger LOG = LoggerFactory.getLogger(NEMOIntentParser.class); private NEMOIntentParser() { } @Immutable public static class BandwidthOnDemandParameters { public final String from; public final String to; public final long bandwidth; public final LocalTime startTime; public final Period duration; public BandwidthOnDemandParameters(String from, String to, long bandwidth, LocalTime startTime, Period duration) { super(); this.from = from; this.to = to; this.bandwidth = bandwidth; this.startTime = startTime; this.duration = duration; } } private static final Pattern BANDWIDTH_PATTERN = Pattern.compile("(\\d+)([kmgt]?)", Pattern.CASE_INSENSITIVE); /** * Simple parsing of strings like "10G" bps into a long value in number of kbps. * * @param bandwidthStr * @return number of kbps */ public static long parseBandwidthString(String bandwidthStr) { Matcher matcher = BANDWIDTH_PATTERN.matcher(bandwidthStr); if (matcher.matches()) { BigDecimal num = new BigDecimal(matcher.group(1)); String unit = matcher.group(2).toLowerCase(); final BigDecimal KILO = new BigDecimal(1024L); if (unit.equals("k")) { num = num.multiply(KILO); } else if (unit.equals("m")) { num = num.multiply(KILO.pow(2)); } else if (unit.equals("g")) { num = num.multiply(KILO.pow(3)); } else if (unit.equals("t")) { num = num.multiply(KILO.pow(4)); } // divide to get kbps return num.divide(KILO, BigDecimal.ROUND_CEILING).longValueExact(); } else { NumberFormatException exception = new NumberFormatException("Invalid bandwidth string " + bandwidthStr + "; must be of pattern " + BANDWIDTH_PATTERN.pattern()); LOG.warn(exception.getMessage(), exception); throw exception; } } public static BandwidthOnDemandParameters parseBandwidthOnDemand(Intent intent) { List<Actions> actions = intent.getActions(); Action action = !actions.isEmpty() ? actions.get(0).getAction() : null; // subjects in sorted order List<Subjects> subjects = Ordering.natural().onResultOf(new Function<Subjects, Short>() { @Override public Short apply(Subjects input) { return input.getOrder(); } }).immutableSortedCopy(intent.getSubjects()); BandwidthConstraint constraint = null; for (Constraints c : intent.getConstraints()) { if (c.getConstraints() instanceof BandwidthConstraint) { constraint = (BandwidthConstraint) c.getConstraints(); } } List<Conditions> conditions = intent.getConditions(); Daily condition = null; for (Conditions c : conditions) { if (c.getCondition() instanceof Daily) { condition = (Daily) c.getCondition(); } } if (action instanceof Allow && constraint instanceof BandwidthConstraint && condition instanceof Daily && subjects.size() == 2) { if (subjects.get(0).getSubject() instanceof EndPointGroup && subjects.get(1).getSubject() instanceof EndPointGroup) { String from = ((EndPointGroup) subjects.get(0).getSubject()).getEndPointGroup().getName(); String to = ((EndPointGroup) subjects.get(1).getSubject()).getEndPointGroup().getName(); String bandwidthStr = constraint.getBandwidthConstraint().getBandwidth(); long bandwidth = parseBandwidthString(bandwidthStr); String startTimeStr = condition.getDaily().getStartTime().getValue(); LocalTime startTime = parseTime(startTimeStr); String durationStr = condition.getDaily().getDuration().getValue(); Period duration = parsePeriod(durationStr); // return new BandwidthOnDemandParameters(from, to, bandwidth, startTime, duration); return new BandwidthOnDemandParameters(from, to, bandwidth, startTime, duration); } } return null; } /** * parse start time as ISO8601 time string * * @param startTimeStr * @return */ public static LocalTime parseTime(String startTimeStr) { return ISODateTimeFormat.timeNoMillis().parseLocalTime(startTimeStr); } /** * parse duration as ISO8601 duration string * * @param durationStr * @return */ public static Period parsePeriod(String durationStr) { return ISOPeriodFormat.standard().parsePeriod("PT" + durationStr); } }