--- /dev/null
+/*
+ * Copyright (c) 2017 Red Hat, 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.genius.infra;
+
+import static org.immutables.value.Value.Style.ImplementationVisibility.PRIVATE;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import org.immutables.value.Value;
+
+/**
+ * <a href="http://immutables.org">Immutables.org</a> style meta annotation.
+ *
+ * @author Michael Vorburger.ch
+ */
+@Target({ElementType.PACKAGE, ElementType.TYPE})
+@Retention(RetentionPolicy.CLASS) // Make it class retention for incremental compilation
+@Value.Style(
+ // generate *Builder as public top level type and the *Immutable impl. as private inner class
+ visibility = PRIVATE,
+ // we use setter-like convention instead of Immutables.org default (no set* prefix)
+ // because this is makes it look closer to the YANG binding gen. code, and also
+ // because the Xtend literals can use the nicer to read = instead of set*(..);
+ // the down-side is that in Java chained Builder initialization it's more ugly.
+ init = "set*",
+ // It would be neat to able to use strictBuilder = true, BUT:
+ // a) that prevents generation of from() copy methods, which are quite handy
+ // (unless https://github.com/immutables/immutables/issues/595 gets implemented)
+ // b) that prevents generation of init/setters for collections, which (as above)
+ // makes it look closer to the YANG binding gen. code which has this (but not addAll),
+ // because the Xtend literals can use the nicer to read = instead of addAll*(..)
+ // (unless https://github.com/immutables/immutables/issues/596 gets implemented)
+ strictBuilder = false)
+public @interface OpenDaylightImmutableStyle { }
+// Beware: Changes made here are not active without a restart in Eclipse (would need separate project)
package org.opendaylight.genius.mdsalutil;
import java.math.BigInteger;
-import java.util.ArrayList;
import java.util.List;
-import java.util.Objects;
+import org.eclipse.jdt.annotation.Nullable;
+import org.immutables.value.Value.Default;
+import org.immutables.value.Value.Immutable;
+import org.opendaylight.genius.infra.OpenDaylightImmutableStyle;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowCookie;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowModFlags;
-import org.opendaylight.yangtools.util.EvenMoreObjects;
-public class FlowEntity extends AbstractSwitchEntity {
- private static final long serialVersionUID = 1L;
+@Immutable
+@OpenDaylightImmutableStyle
+public abstract class FlowEntity extends AbstractSwitchEntity {
- private short tableId;
- private String flowId;
- private int priority;
- private String flowName;
- private int idleTimeOut;
- private int hardTimeOut;
- private BigInteger biCookie;
- private List<MatchInfoBase> listMatchInfo = new ArrayList<>();
- private List<InstructionInfo> listInstructionInfo = new ArrayList<>();
-
- private boolean strictFlag;
- private boolean sendFlowRemFlag;
-
- private transient FlowBuilder flowBuilder;
-
- public FlowEntity(BigInteger dpnId) {
- super(dpnId);
- }
-
- public FlowEntity(long dpnId) {
- this(BigInteger.valueOf(dpnId));
- }
-
- @Override
- public String toString() {
- return "FlowEntity [dpnId=" + getDpnId() + ", tableId=" + tableId + ", flowId=" + flowId + ", priority="
- + priority + ", flowName=" + flowName + ", idleTimeOut=" + idleTimeOut + ", hardTimeOut="
- + hardTimeOut + ", cookie=" + biCookie + ", matchInfo=" + listMatchInfo
- + ", instructionInfo=" + listInstructionInfo + ", strictFlag=" + strictFlag
- + ", sendFlowRemFlag=" + sendFlowRemFlag + "]";
- }
+ // This is required as it will cause the code generation by @Immutable.org to implement Builder,
+ // which is required Xtend sources can use the XtendBuilderExtensions.operator_doubleGreaterThan
+ public abstract static class Builder implements org.opendaylight.yangtools.concepts.Builder<FlowEntity> {}
+ // This was done because MDSALManager has this hard-coded like this, upon MDSALManager.installFlow()
+ @Default
public BigInteger getCookie() {
- return biCookie;
+ return new BigInteger("0110000", 16);
}
- public String getFlowId() {
- return flowId;
- }
+ public abstract String getFlowId();
- public String getFlowName() {
- return flowName;
- }
+ public abstract @Nullable String getFlowName();
+ @Default
public int getHardTimeOut() {
- return hardTimeOut;
+ return 0;
}
+ @Default
public int getIdleTimeOut() {
- return idleTimeOut;
+ return 0;
}
- public List<InstructionInfo> getInstructionInfoList() {
- return listInstructionInfo;
- }
+ public abstract List<InstructionInfo> getInstructionInfoList();
- public List<MatchInfoBase> getMatchInfoList() {
- return listMatchInfo;
- }
+ public abstract List<MatchInfoBase> getMatchInfoList();
+ @Default
public int getPriority() {
- return priority;
+ return 0;
}
+ @Default
public boolean getSendFlowRemFlag() {
- return sendFlowRemFlag;
+ return false;
}
+ @Default
public boolean getStrictFlag() {
- return strictFlag;
- }
-
- public short getTableId() {
- return tableId;
+ return false;
}
- public void setCookie(BigInteger biCookie) {
- this.biCookie = biCookie;
- this.flowBuilder = null;
- }
+ public abstract short getTableId();
public FlowBuilder getFlowBuilder() {
- if (flowBuilder == null) {
- flowBuilder = new FlowBuilder();
-
- flowBuilder.setKey(new FlowKey(new FlowId(getFlowId())));
-
- flowBuilder.setTableId(getTableId());
- flowBuilder.setPriority(getPriority());
- flowBuilder.setFlowName(getFlowName());
- flowBuilder.setIdleTimeout(getIdleTimeOut());
- flowBuilder.setHardTimeout(getHardTimeOut());
- flowBuilder.setCookie(new FlowCookie(getCookie()));
- flowBuilder.setMatch(MDSALUtil.buildMatches(getMatchInfoList()));
- flowBuilder.setInstructions(MDSALUtil.buildInstructions(getInstructionInfoList()));
-
- flowBuilder.setStrict(getStrictFlag());
- // TODO Fix Me
- //m_flowBuilder.setResyncFlag(getResyncFlag());
- if (getSendFlowRemFlag()) {
- flowBuilder.setFlags(new FlowModFlags(false, false, false, false, true));
- }
-
- flowBuilder.setBarrier(false);
- flowBuilder.setInstallHw(true);
- }
-
- return flowBuilder;
- }
-
- public void setFlowId(String flowId) {
- this.flowId = flowId;
- if (this.flowBuilder != null) {
- this.flowBuilder.setKey(new FlowKey(new FlowId(flowId)));
- }
- }
-
- public void setFlowName(String flowName) {
- this.flowName = flowName;
- this.flowBuilder = null;
- }
-
- public void setHardTimeOut(int hardTimeOut) {
- this.hardTimeOut = hardTimeOut;
- this.flowBuilder = null;
- }
-
- public void setIdleTimeOut(int idleTimeOut) {
- this.idleTimeOut = idleTimeOut;
- this.flowBuilder = null;
- }
-
- public void setInstructionInfoList(List<InstructionInfo> listInstructionInfo) {
- this.listInstructionInfo = listInstructionInfo;
- this.flowBuilder = null;
- }
-
- @SuppressWarnings("unchecked")
- public void setMatchInfoList(List<? extends MatchInfoBase> listMatchInfo) {
- this.listMatchInfo = (List<MatchInfoBase>) listMatchInfo;
- this.flowBuilder = null;
- }
-
- public void setPriority(int priority) {
- this.priority = priority;
- this.flowBuilder = null;
- }
-
- public void setSendFlowRemFlag(boolean sendFlowRemFlag) {
- this.sendFlowRemFlag = sendFlowRemFlag;
- this.flowBuilder = null;
- }
-
- public void setStrictFlag(boolean strictFlag) {
- this.strictFlag = strictFlag;
- this.flowBuilder = null;
- }
-
- public void setTableId(short tableId) {
- this.tableId = tableId;
- this.flowBuilder = null;
- }
-
- // int variant is a convenience, because Java is dumb: setTableId(123) does
- // not work without this, and there is no short literal like 123l for long.
- public void setTableId(int shTableId) {
- if (shTableId > Short.MAX_VALUE || shTableId < Short.MIN_VALUE) {
- throw new IllegalArgumentException("tableId not a short: " + shTableId);
+ FlowBuilder flowBuilder = new FlowBuilder();
+
+ flowBuilder.setKey(new FlowKey(new FlowId(getFlowId())));
+
+ flowBuilder.setTableId(getTableId());
+ flowBuilder.setPriority(getPriority());
+ flowBuilder.setFlowName(getFlowName());
+ flowBuilder.setIdleTimeout(getIdleTimeOut());
+ flowBuilder.setHardTimeout(getHardTimeOut());
+ flowBuilder.setCookie(new FlowCookie(getCookie()));
+ flowBuilder.setMatch(MDSALUtil.buildMatches(getMatchInfoList()));
+ flowBuilder.setInstructions(MDSALUtil.buildInstructions(getInstructionInfoList()));
+
+ flowBuilder.setStrict(getStrictFlag());
+ // TODO flowBuilder.setResyncFlag(getResyncFlag());
+ if (getSendFlowRemFlag()) {
+ flowBuilder.setFlags(new FlowModFlags(false, false, false, false, true));
}
- setTableId((short) shTableId);
- }
- @Override
- public int hashCode() {
- return Objects.hash(getDpnId(), tableId, flowId, priority, flowName, idleTimeOut,
- hardTimeOut, biCookie, listMatchInfo, listInstructionInfo, strictFlag, sendFlowRemFlag);
- }
+ flowBuilder.setBarrier(false);
+ flowBuilder.setInstallHw(true);
- @Override
- public boolean equals(Object obj) {
- return EvenMoreObjects.equalsHelper(this, obj,
- (self, other) -> Objects.equals(self.getDpnId(), other.getDpnId())
- && Objects.equals(self.tableId, other.tableId)
- && Objects.equals(self.flowId, other.flowId)
- && Objects.equals(self.priority, other.priority)
- && Objects.equals(self.flowName, other.flowName)
- && Objects.equals(self.idleTimeOut, other.idleTimeOut)
- && Objects.equals(self.hardTimeOut, other.hardTimeOut)
- && Objects.equals(self.biCookie, other.biCookie)
- && Objects.equals(self.listMatchInfo, other.listMatchInfo)
- && Objects.equals(self.listInstructionInfo, other.listInstructionInfo)
- && Objects.equals(self.strictFlag, other.strictFlag)
- && Objects.equals(self.sendFlowRemFlag, other.sendFlowRemFlag)
- );
+ return flowBuilder;
}
}
import com.google.common.collect.ImmutableList;
import com.google.common.testing.EqualsTester;
import java.math.BigInteger;
-import java.util.List;
import org.junit.Test;
import org.opendaylight.genius.mdsalutil.FlowEntity;
-import org.opendaylight.genius.mdsalutil.InstructionInfo;
-import org.opendaylight.genius.mdsalutil.MatchInfoBase;
+import org.opendaylight.genius.mdsalutil.FlowEntityBuilder;
import org.opendaylight.genius.mdsalutil.instructions.InstructionClearActions;
import org.opendaylight.genius.mdsalutil.instructions.InstructionGotoTable;
import org.opendaylight.genius.mdsalutil.interfaces.testutils.TestIMdsalApiManager;
}
private FlowEntity getNewFlow1() {
- FlowEntity flow1 = new FlowEntity(123);
- flow1.setTableId(1);
- flow1.setCookie(BigInteger.valueOf(456789));
- flow1.setFlowId("ThisIsFlow1");
- flow1.setHardTimeOut(456);
- flow1.setIdleTimeOut(789);
- flow1.setPriority(1);
- flow1.setSendFlowRemFlag(true);
- flow1.setStrictFlag(true);
- List<InstructionInfo> instructionInfos = ImmutableList.of(
- new InstructionClearActions(), new InstructionGotoTable((short) 2));
- flow1.setInstructionInfoList(instructionInfos);
- List<MatchInfoBase> matchInfos = ImmutableList.of(
- new MatchArpSpa("192.168.1.1", "24"));
- flow1.setMatchInfoList(matchInfos);
- return flow1;
+ return new FlowEntityBuilder()
+ .setDpnId(BigInteger.valueOf(123))
+ .setTableId((short) 1)
+ .setCookie(BigInteger.valueOf(456789))
+ .setFlowId("ThisIsFlow1")
+ .setHardTimeOut(456)
+ .setIdleTimeOut(789)
+ .setPriority(1)
+ .setSendFlowRemFlag(true)
+ .setStrictFlag(true)
+ .addInstructionInfoList(
+ new InstructionClearActions(), new InstructionGotoTable((short) 2))
+ .addMatchInfoList(new MatchArpSpa("192.168.1.1", "24"))
+ .build();
}
private FlowEntity getNewFlow2() {
- FlowEntity flow2 = new FlowEntity(321);
- flow2.setTableId(2);
- flow2.setCookie(BigInteger.valueOf(987654));
- flow2.setFlowId("ThisIsflow2");
- flow2.setHardTimeOut(654);
- flow2.setIdleTimeOut(987);
- flow2.setPriority(2);
- flow2.setSendFlowRemFlag(false);
- flow2.setStrictFlag(false);
- List<InstructionInfo> instructionInfos = ImmutableList.of(
- new InstructionGotoTable((short) 1), new InstructionClearActions());
- flow2.setInstructionInfoList(instructionInfos);
- List<MatchInfoBase> matchInfos = ImmutableList.of(
- new MatchArpSpa("10.11.12.30", "24"));
- flow2.setMatchInfoList(matchInfos);
- return flow2;
+ return new FlowEntityBuilder()
+ .setDpnId(BigInteger.valueOf(321))
+ .setTableId((short) 2)
+ .setCookie(BigInteger.valueOf(987654))
+ .setFlowId("ThisIsFlow2")
+ .setHardTimeOut(654)
+ .setIdleTimeOut(987)
+ .setPriority(2)
+ .setSendFlowRemFlag(false)
+ .setStrictFlag(false)
+ .addInstructionInfoList(
+ new InstructionGotoTable((short) 1), new InstructionClearActions())
+ .addMatchInfoList(new MatchArpSpa("10.11.12.30", "24"))
+ .build();
}
}