blob: 98d7d09533da086fcf21614729e98d00c9814669 [file] [log] [blame]
Jian Li44155b02017-02-15 17:03:38 +09001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2017-present Open Networking Foundation
Jian Li44155b02017-02-15 17:03:38 +09003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.onosproject.mapping;
17
18import com.google.common.base.MoreObjects;
19import com.google.common.collect.ImmutableList;
20import com.google.common.collect.Lists;
21import com.google.common.collect.Maps;
22import org.onosproject.mapping.addresses.MappingAddress;
23import org.onosproject.mapping.instructions.MappingInstruction;
24import org.onosproject.mapping.instructions.MappingInstructions;
25import org.onosproject.mapping.instructions.MulticastMappingInstruction;
26import org.onosproject.mapping.instructions.MulticastMappingInstruction.MulticastType;
27import org.onosproject.mapping.instructions.UnicastMappingInstruction;
28import org.onosproject.mapping.instructions.UnicastMappingInstruction.UnicastType;
29import org.onosproject.net.DeviceId;
30import org.onosproject.net.flow.instructions.ExtensionTreatment;
31
32import java.util.List;
33import java.util.Map;
34import java.util.Objects;
35
36import static com.google.common.base.Preconditions.checkArgument;
37import static com.google.common.base.Preconditions.checkNotNull;
38
39/**
40 * Default implementation of mapping treatment.
41 */
42public final class DefaultMappingTreatment implements MappingTreatment {
43
44 private final List<MappingInstruction> instructions;
45 private final MappingAddress address;
46
47 /**
48 * Create a new mapping treatment from the specified list of mapping instructions.
49 *
50 * @param instructions mapping instructions
51 */
52 private DefaultMappingTreatment(MappingAddress address,
53 List<MappingInstruction> instructions) {
54 this.address = address;
55 this.instructions = ImmutableList.copyOf(checkNotNull(instructions));
56 }
57
58 @Override
59 public MappingAddress address() {
60 return address;
61 }
62
63 @Override
64 public List<MappingInstruction> instructions() {
65 return ImmutableList.copyOf(instructions);
66 }
67
68 @Override
69 public int hashCode() {
70 return Objects.hash(address, instructions);
71 }
72
73 @Override
74 public boolean equals(Object obj) {
75 if (this == obj) {
76 return true;
77 }
78 if (obj instanceof DefaultMappingTreatment) {
79 DefaultMappingTreatment that = (DefaultMappingTreatment) obj;
80 return Objects.equals(address, that.address) &&
81 Objects.equals(instructions, that.instructions);
82 }
83 return false;
84 }
85
86 @Override
87 public String toString() {
88 return MoreObjects.toStringHelper(getClass())
89 .add("address", address)
90 .add("mapping instructions", instructions)
91 .toString();
92 }
93
94 /**
95 * Returns a new mapping treatment builder.
96 *
97 * @return mapping treatment builder
98 */
99 public static Builder builder() {
100 return new Builder();
101 }
102
103 /**
104 * Returns a new mapping treatment builder primed to produce entities
105 * patterned after the supplied mapping treatment.
106 *
107 * @param treatment base mapping treatment
108 * @return mapping treatment builder
109 */
110 public static Builder builder(MappingTreatment treatment) {
111 return new Builder(treatment);
112 }
113
114 /**
115 * Builds a mapping treatment.
116 */
117 public static final class Builder implements MappingTreatment.Builder {
118
119 private List<MappingInstruction> instructions = Lists.newArrayList();
120 private MappingAddress address;
121 private Map<UnicastType, Integer> unicastTypeMap = Maps.newConcurrentMap();
122 private Map<MulticastType, Integer> multicastTypeMap = Maps.newConcurrentMap();
123
124 // creates a new builder
125 private Builder() {
126 initTypeMap();
127 }
128
129 // creates a new builder based off an existing mapping treatment
130 private Builder(MappingTreatment treatment) {
131 treatment.instructions().forEach(i -> instructions.add(i));
132 address = treatment.address();
133 initTypeMap();
134 }
135
136 /**
137 * Initializes type map.
138 */
139 private void initTypeMap() {
140 unicastTypeMap.put(UnicastType.WEIGHT, 0);
141 unicastTypeMap.put(UnicastType.PRIORITY, 0);
142 multicastTypeMap.put(MulticastType.WEIGHT, 0);
143 multicastTypeMap.put(MulticastType.PRIORITY, 0);
144 }
145
146 @Override
147 public Builder withAddress(MappingAddress address) {
148 this.address = address;
149 return this;
150 }
151
152 @Override
153 public Builder add(MappingInstruction instruction) {
154
155 switch (instruction.type()) {
156 case UNICAST:
157 unicastTypeMap.compute(((UnicastMappingInstruction)
158 instruction).subtype(), (k, v) -> v + 1);
159 instructions.add(instruction);
160 break;
161 case MULTICAST:
162 multicastTypeMap.compute(((MulticastMappingInstruction)
163 instruction).subtype(), (k, v) -> v + 1);
164 instructions.add(instruction);
165 break;
166 case EXTENSION:
167 instructions.add(instruction);
168 break;
169 default:
170 throw new IllegalArgumentException("Unknown mapping " +
171 "instruction type: " + instruction.type());
172 }
173
174 return this;
175 }
176
177 @Override
178 public Builder setUnicastWeight(int weight) {
179 return add(MappingInstructions.unicastWeight(weight));
180 }
181
182 @Override
183 public Builder setUnicastPriority(int priority) {
184 return add(MappingInstructions.unicastPriority(priority));
185 }
186
187 @Override
188 public Builder setMulticastWeight(int weight) {
189 return add(MappingInstructions.multicastWeight(weight));
190 }
191
192 @Override
193 public Builder setMulticastPriority(int priority) {
194 return add(MappingInstructions.multicastPriority(priority));
195 }
196
197 @Override
198 public Builder extension(ExtensionTreatment extension, DeviceId deviceId) {
199 return add(MappingInstructions.extension(extension, deviceId));
200 }
201
202 @Override
203 public MappingTreatment build() {
204
205 unicastTypeMap.forEach((k, v) -> checkArgument(v <= 1,
206 "Should not specify more than one " + k.toString()));
207 multicastTypeMap.forEach((k, v) -> checkArgument(v <= 1,
208 "Should not specify more than one " + k.toString()));
209
210 return new DefaultMappingTreatment(address, instructions);
211 }
212 }
213}