aboutsummaryrefslogtreecommitdiffstats
path: root/models/src
diff options
context:
space:
mode:
authorliamfallon <liam.fallon@est.tech>2021-06-10 11:45:02 +0100
committerliamfallon <liam.fallon@est.tech>2021-06-10 15:54:51 +0100
commit7f89803244315af8dd605380d4a6d6586c3d870b (patch)
treec798f2cd06050493cd282315eb9ae593bac32ece /models/src
parent24619d423c084cb212c97959a93380278b60e414 (diff)
Eliminate two fromAuthorative() calls in providers
The current implementation of the providers makes two calls to the expensive fromAuthorative() method. This change changes the implementation to make a single call. Issue-ID: POLICY-3319 Change-Id: I6b7e016e91b07f567973d9e2af68514de0affddd Signed-off-by: liamfallon <liam.fallon@est.tech>
Diffstat (limited to 'models/src')
-rw-r--r--models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/concepts/ControlLoop.java1
-rw-r--r--models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/provider/ClElementStatisticsProvider.java40
-rw-r--r--models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/provider/ControlLoopProvider.java51
-rw-r--r--models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/provider/ParticipantProvider.java53
-rw-r--r--models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/provider/ParticipantStatisticsProvider.java33
-rw-r--r--models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/provider/ProviderUtils.java56
6 files changed, 95 insertions, 139 deletions
diff --git a/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/concepts/ControlLoop.java b/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/concepts/ControlLoop.java
index d0d79274c..f2397602b 100644
--- a/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/concepts/ControlLoop.java
+++ b/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/concepts/ControlLoop.java
@@ -20,7 +20,6 @@
package org.onap.policy.clamp.controlloop.models.controlloop.concepts;
-import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
diff --git a/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/provider/ClElementStatisticsProvider.java b/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/provider/ClElementStatisticsProvider.java
index 8a06cbf1e..dacde8e79 100644
--- a/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/provider/ClElementStatisticsProvider.java
+++ b/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/provider/ClElementStatisticsProvider.java
@@ -25,13 +25,10 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
-import javax.ws.rs.core.Response;
import lombok.NonNull;
import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ClElementStatistics;
import org.onap.policy.clamp.controlloop.models.controlloop.persistence.concepts.JpaClElementStatistics;
-import org.onap.policy.common.parameters.BeanValidationResult;
import org.onap.policy.models.base.PfModelException;
-import org.onap.policy.models.base.PfModelRuntimeException;
import org.onap.policy.models.base.PfReferenceTimestampKey;
import org.onap.policy.models.provider.PolicyModelsProviderParameters;
import org.onap.policy.models.provider.impl.AbstractModelsProvider;
@@ -64,33 +61,19 @@ public class ClElementStatisticsProvider extends AbstractModelsProvider {
public List<ClElementStatistics> createClElementStatistics(
@NonNull final List<ClElementStatistics> clElementStatisticsList) throws PfModelException {
- BeanValidationResult validationResult =
- new BeanValidationResult("control loop element statistics list", clElementStatisticsList);
- for (ClElementStatistics clElementStatistics : clElementStatisticsList) {
- JpaClElementStatistics jpaClElementStatistics = new JpaClElementStatistics();
- jpaClElementStatistics.fromAuthorative(clElementStatistics);
+ List<JpaClElementStatistics> jpaClElementStatisticsList = ProviderUtils.getJpaAndValidate(
+ clElementStatisticsList, JpaClElementStatistics::new, "control loop element statistics");
- validationResult.addResult(jpaClElementStatistics.validate("control loop element statistics"));
- }
-
- if (!validationResult.isValid()) {
- throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, validationResult.getResult());
- }
-
- for (ClElementStatistics clElementStatistics : clElementStatisticsList) {
- JpaClElementStatistics jpaClElementStatistics = new JpaClElementStatistics();
- jpaClElementStatistics.fromAuthorative(clElementStatistics);
- getPfDao().create(jpaClElementStatistics);
- }
+ jpaClElementStatisticsList.forEach(jpaClElementStatistics -> getPfDao().create(jpaClElementStatistics));
// Return the created control loop element statistics
List<ClElementStatistics> elementStatistics = new ArrayList<>(clElementStatisticsList.size());
for (ClElementStatistics clElementStat : clElementStatisticsList) {
- JpaClElementStatistics jpaClElementStatistics = getPfDao().get(JpaClElementStatistics.class,
- new PfReferenceTimestampKey(clElementStat.getParticipantId().getName(),
- clElementStat.getParticipantId().getVersion(), clElementStat.getId().toString(),
- clElementStat.getTimeStamp()));
+ var jpaClElementStatistics = getPfDao().get(JpaClElementStatistics.class,
+ new PfReferenceTimestampKey(clElementStat.getParticipantId().getName(),
+ clElementStat.getParticipantId().getVersion(), clElementStat.getId().toString(),
+ clElementStat.getTimeStamp()));
elementStatistics.add(jpaClElementStatistics.toAuthorative());
}
@@ -122,16 +105,15 @@ public class ClElementStatisticsProvider extends AbstractModelsProvider {
List<ClElementStatistics> clElementStatistics = new ArrayList<>(1);
if (name != null && version != null && timestamp != null && id != null) {
clElementStatistics.add(getPfDao()
- .get(JpaClElementStatistics.class, new PfReferenceTimestampKey(name, version, id, timestamp))
- .toAuthorative());
+ .get(JpaClElementStatistics.class, new PfReferenceTimestampKey(name, version, id, timestamp))
+ .toAuthorative());
return clElementStatistics;
} else if (name != null) {
- clElementStatistics.addAll(getFilteredClElementStatistics(name, version, null, null, null,
- "DESC", 0));
+ clElementStatistics.addAll(getFilteredClElementStatistics(name, version, null, null, null, "DESC", 0));
} else {
clElementStatistics.addAll(asClElementStatisticsList(getPfDao().getAll(JpaClElementStatistics.class)));
}
- return clElementStatistics;
+ return clElementStatistics;
}
/**
diff --git a/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/provider/ControlLoopProvider.java b/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/provider/ControlLoopProvider.java
index 520e9b864..5317bb31d 100644
--- a/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/provider/ControlLoopProvider.java
+++ b/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/provider/ControlLoopProvider.java
@@ -28,7 +28,6 @@ import javax.ws.rs.core.Response;
import lombok.NonNull;
import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoop;
import org.onap.policy.clamp.controlloop.models.controlloop.persistence.concepts.JpaControlLoop;
-import org.onap.policy.common.parameters.BeanValidationResult;
import org.onap.policy.models.base.PfAuthorative;
import org.onap.policy.models.base.PfConceptKey;
import org.onap.policy.models.base.PfKey;
@@ -66,7 +65,7 @@ public class ControlLoopProvider extends AbstractModelsProvider {
* @throws PfModelException on errors getting the control loop
*/
public ControlLoop getControlLoop(final ToscaConceptIdentifier controlLoopId) throws PfModelException {
- JpaControlLoop jpaControlLoop = getPfDao().get(JpaControlLoop.class, controlLoopId.asConceptKey());
+ var jpaControlLoop = getPfDao().get(JpaControlLoop.class, controlLoopId.asConceptKey());
return jpaControlLoop == null ? null : jpaControlLoop.toAuthorative();
}
@@ -117,31 +116,16 @@ public class ControlLoopProvider extends AbstractModelsProvider {
*/
public List<ControlLoop> createControlLoops(@NonNull final List<ControlLoop> controlLoops) throws PfModelException {
- BeanValidationResult validationResult = new BeanValidationResult("control loops", controlLoops);
+ List<JpaControlLoop> jpaControlLoopList =
+ ProviderUtils.getJpaAndValidate(controlLoops, JpaControlLoop::new, "control loop");
- for (ControlLoop controlLoop : controlLoops) {
- JpaControlLoop jpaControlLoop = new JpaControlLoop();
- jpaControlLoop.fromAuthorative(controlLoop);
-
- validationResult.addResult(jpaControlLoop.validate("control loop"));
- }
-
- if (!validationResult.isValid()) {
- throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, validationResult.getResult());
- }
-
- for (ControlLoop controlLoop : controlLoops) {
- JpaControlLoop jpaControlLoop = new JpaControlLoop();
- jpaControlLoop.fromAuthorative(controlLoop);
-
- getPfDao().create(jpaControlLoop);
- }
+ jpaControlLoopList.forEach(jpaControlLoop -> getPfDao().create(jpaControlLoop));
// Return the created control loops
List<ControlLoop> returnControlLoops = new ArrayList<>(controlLoops.size());
for (ControlLoop controlLoop : controlLoops) {
- JpaControlLoop jpaControlLoop = getPfDao().get(JpaControlLoop.class,
+ var jpaControlLoop = getPfDao().get(JpaControlLoop.class,
new PfConceptKey(controlLoop.getName(), controlLoop.getVersion()));
returnControlLoops.add(jpaControlLoop.toAuthorative());
}
@@ -158,29 +142,16 @@ public class ControlLoopProvider extends AbstractModelsProvider {
*/
public List<ControlLoop> updateControlLoops(@NonNull final List<ControlLoop> controlLoops) throws PfModelException {
- BeanValidationResult validationResult = new BeanValidationResult("control loops", controlLoops);
-
- for (ControlLoop controlLoop : controlLoops) {
- JpaControlLoop jpaControlLoop = new JpaControlLoop();
- jpaControlLoop.fromAuthorative(controlLoop);
-
- validationResult.addResult(jpaControlLoop.validate("control loop"));
- }
-
- if (!validationResult.isValid()) {
- throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, validationResult.getResult());
- }
+ List<JpaControlLoop> jpaControlLoopList =
+ ProviderUtils.getJpaAndValidate(controlLoops, JpaControlLoop::new, "control loop");
// Return the created control loops
List<ControlLoop> returnControlLoops = new ArrayList<>(controlLoops.size());
- for (ControlLoop controlLoop : controlLoops) {
- JpaControlLoop jpaControlLoop = new JpaControlLoop();
- jpaControlLoop.fromAuthorative(controlLoop);
-
- JpaControlLoop returnJpaControlLoop = getPfDao().update(jpaControlLoop);
+ jpaControlLoopList.forEach(jpaControlLoop -> {
+ var returnJpaControlLoop = getPfDao().update(jpaControlLoop);
returnControlLoops.add(returnJpaControlLoop.toAuthorative());
- }
+ });
return returnControlLoops;
}
@@ -195,7 +166,7 @@ public class ControlLoopProvider extends AbstractModelsProvider {
*/
public ControlLoop deleteControlLoop(@NonNull final String name, @NonNull final String version) {
- PfConceptKey controlLoopKey = new PfConceptKey(name, version);
+ var controlLoopKey = new PfConceptKey(name, version);
JpaControlLoop jpaDeleteControlLoop = getPfDao().get(JpaControlLoop.class, controlLoopKey);
diff --git a/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/provider/ParticipantProvider.java b/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/provider/ParticipantProvider.java
index e82956f93..c569cadd8 100644
--- a/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/provider/ParticipantProvider.java
+++ b/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/provider/ParticipantProvider.java
@@ -27,7 +27,6 @@ import javax.ws.rs.core.Response;
import lombok.NonNull;
import org.onap.policy.clamp.controlloop.models.controlloop.concepts.Participant;
import org.onap.policy.clamp.controlloop.models.controlloop.persistence.concepts.JpaParticipant;
-import org.onap.policy.common.parameters.BeanValidationResult;
import org.onap.policy.models.base.PfConceptKey;
import org.onap.policy.models.base.PfModelException;
import org.onap.policy.models.base.PfModelRuntimeException;
@@ -72,8 +71,8 @@ public class ParticipantProvider extends AbstractModelsProvider {
*/
public List<Participant> getFilteredParticipants(@NonNull final ToscaTypedEntityFilter<Participant> filter) {
- return filter.filter(asParticipantList(
- getPfDao().getFiltered(JpaParticipant.class, filter.getName(), filter.getVersion())));
+ return filter.filter(
+ asParticipantList(getPfDao().getFiltered(JpaParticipant.class, filter.getName(), filter.getVersion())));
}
/**
@@ -85,31 +84,16 @@ public class ParticipantProvider extends AbstractModelsProvider {
*/
public List<Participant> createParticipants(@NonNull final List<Participant> participants) throws PfModelException {
- BeanValidationResult validationResult = new BeanValidationResult("participants", participants);
+ List<JpaParticipant> jpaParticipantList =
+ ProviderUtils.getJpaAndValidate(participants, JpaParticipant::new, "participant");
- for (Participant participant : participants) {
- JpaParticipant jpaParticipant = new JpaParticipant();
- jpaParticipant.fromAuthorative(participant);
-
- validationResult.addResult(jpaParticipant.validate("participant"));
- }
-
- if (!validationResult.isValid()) {
- throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, validationResult.getResult());
- }
-
- for (Participant participant : participants) {
- JpaParticipant jpaParticipant = new JpaParticipant();
- jpaParticipant.fromAuthorative(participant);
-
- getPfDao().create(jpaParticipant);
- }
+ jpaParticipantList.forEach(jpaParticipant -> getPfDao().create(jpaParticipant));
// Return the created participants
List<Participant> returnParticipants = new ArrayList<>(participants.size());
for (Participant participant : participants) {
- JpaParticipant jpaParticipant = getPfDao().get(JpaParticipant.class,
+ var jpaParticipant = getPfDao().get(JpaParticipant.class,
new PfConceptKey(participant.getName(), participant.getVersion()));
returnParticipants.add(jpaParticipant.toAuthorative());
}
@@ -126,31 +110,16 @@ public class ParticipantProvider extends AbstractModelsProvider {
*/
public List<Participant> updateParticipants(@NonNull final List<Participant> participants) throws PfModelException {
- BeanValidationResult validationResult = new BeanValidationResult("participants", participants);
+ List<JpaParticipant> jpaParticipantList =
+ ProviderUtils.getJpaAndValidate(participants, JpaParticipant::new, "participant");
- for (Participant participant : participants) {
- JpaParticipant jpaParticipant = new JpaParticipant();
- jpaParticipant.fromAuthorative(participant);
-
- validationResult.addResult(jpaParticipant.validate("participant"));
- }
-
- if (!validationResult.isValid()) {
- throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, validationResult.getResult());
- }
-
- for (Participant participant : participants) {
- JpaParticipant jpaParticipant = new JpaParticipant();
- jpaParticipant.fromAuthorative(participant);
-
- getPfDao().update(jpaParticipant);
- }
+ jpaParticipantList.forEach(jpaParticipant -> getPfDao().update(jpaParticipant));
// Return the created participants
List<Participant> returnParticipants = new ArrayList<>(participants.size());
for (Participant participant : participants) {
- JpaParticipant jpaParticipant = getPfDao().get(JpaParticipant.class,
+ var jpaParticipant = getPfDao().get(JpaParticipant.class,
new PfConceptKey(participant.getName(), participant.getVersion()));
returnParticipants.add(jpaParticipant.toAuthorative());
}
@@ -168,7 +137,7 @@ public class ParticipantProvider extends AbstractModelsProvider {
*/
public Participant deleteParticipant(@NonNull final String name, @NonNull final String version) {
- PfConceptKey participantKey = new PfConceptKey(name, version);
+ var participantKey = new PfConceptKey(name, version);
JpaParticipant jpaDeleteParticipant = getPfDao().get(JpaParticipant.class, participantKey);
diff --git a/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/provider/ParticipantStatisticsProvider.java b/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/provider/ParticipantStatisticsProvider.java
index 6b075278c..4ea76ff4b 100644
--- a/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/provider/ParticipantStatisticsProvider.java
+++ b/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/provider/ParticipantStatisticsProvider.java
@@ -25,21 +25,16 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
-import javax.ws.rs.core.Response;
import lombok.NonNull;
import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantStatistics;
import org.onap.policy.clamp.controlloop.models.controlloop.persistence.concepts.JpaParticipantStatistics;
-import org.onap.policy.common.parameters.BeanValidationResult;
import org.onap.policy.models.base.PfModelException;
-import org.onap.policy.models.base.PfModelRuntimeException;
import org.onap.policy.models.base.PfTimestampKey;
import org.onap.policy.models.provider.PolicyModelsProviderParameters;
import org.onap.policy.models.provider.impl.AbstractModelsProvider;
/**
* This class provides the provision of information on participant statistics in the database to callers.
- *
- * @author Ramesh Murugan Iyer (ramesh.murugan.iyer@est.tech)
*/
public class ParticipantStatisticsProvider extends AbstractModelsProvider {
@@ -70,8 +65,7 @@ public class ParticipantStatisticsProvider extends AbstractModelsProvider {
.get(JpaParticipantStatistics.class, new PfTimestampKey(name, version, timestamp)).toAuthorative());
return participantStatistics;
} else if (name != null) {
- return getFilteredParticipantStatistics(name, version, timestamp, null, null,
- "DESC", 0);
+ return getFilteredParticipantStatistics(name, version, timestamp, null, null, "DESC", 0);
} else {
return asParticipantStatisticsList(getPfDao().getAll(JpaParticipantStatistics.class));
}
@@ -108,32 +102,16 @@ public class ParticipantStatisticsProvider extends AbstractModelsProvider {
public List<ParticipantStatistics> createParticipantStatistics(
@NonNull final List<ParticipantStatistics> participantStatisticsList) throws PfModelException {
- BeanValidationResult validationResult =
- new BeanValidationResult("participant statistics List", participantStatisticsList);
-
- for (ParticipantStatistics participantStatistics : participantStatisticsList) {
- JpaParticipantStatistics jpaParticipantStatistics = new JpaParticipantStatistics();
- jpaParticipantStatistics.fromAuthorative(participantStatistics);
+ List<JpaParticipantStatistics> jpaParticipantStatisticsList = ProviderUtils
+ .getJpaAndValidate(participantStatisticsList, JpaParticipantStatistics::new, "Participant Statistics");
- validationResult.addResult(jpaParticipantStatistics.validate("participant statistics"));
- }
-
- if (!validationResult.isValid()) {
- throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, validationResult.getResult());
- }
-
- for (ParticipantStatistics participantStatistics : participantStatisticsList) {
- JpaParticipantStatistics jpaParticipantStatistics = new JpaParticipantStatistics();
- jpaParticipantStatistics.fromAuthorative(participantStatistics);
-
- getPfDao().create(jpaParticipantStatistics);
- }
+ jpaParticipantStatisticsList.forEach(jpaParticipantStatistics -> getPfDao().update(jpaParticipantStatistics));
// Return the created participant statistics
List<ParticipantStatistics> participantStatistics = new ArrayList<>(participantStatisticsList.size());
for (ParticipantStatistics participantStatisticsItem : participantStatisticsList) {
- JpaParticipantStatistics jpaParticipantStatistics = getPfDao().get(JpaParticipantStatistics.class,
+ var jpaParticipantStatistics = getPfDao().get(JpaParticipantStatistics.class,
new PfTimestampKey(participantStatisticsItem.getParticipantId().getName(),
participantStatisticsItem.getParticipantId().getVersion(),
participantStatisticsItem.getTimeStamp()));
@@ -144,6 +122,7 @@ public class ParticipantStatisticsProvider extends AbstractModelsProvider {
}
+
/**
* Convert JPA participant statistics list to participant statistics list.
*
diff --git a/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/provider/ProviderUtils.java b/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/provider/ProviderUtils.java
new file mode 100644
index 000000000..ff5b132ab
--- /dev/null
+++ b/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/provider/ProviderUtils.java
@@ -0,0 +1,56 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2021 Nordix Foundation.
+ * ================================================================================
+ * 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.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Supplier;
+import javax.ws.rs.core.Response;
+import org.onap.policy.common.parameters.BeanValidationResult;
+import org.onap.policy.models.base.PfAuthorative;
+import org.onap.policy.models.base.PfConcept;
+import org.onap.policy.models.base.PfModelRuntimeException;
+
+public final class ProviderUtils {
+ private ProviderUtils() {
+ // Utility class has no instances
+ }
+
+ protected static <A, J extends PfConcept & PfAuthorative<A>> List<J> getJpaAndValidate(
+ List<A> authorativeConceptList, Supplier<J> jpaSupplier, String conceptDescription) {
+ var validationResult = new BeanValidationResult(conceptDescription + " List", authorativeConceptList);
+
+ List<J> jpaConceptList = new ArrayList<>(authorativeConceptList.size());
+
+ for (A authorativeConcept : authorativeConceptList) {
+ var jpaConcept = jpaSupplier.get();
+ jpaConcept.fromAuthorative(authorativeConcept);
+ jpaConceptList.add(jpaConcept);
+
+ validationResult.addResult(jpaConcept.validate(conceptDescription));
+ }
+
+ if (!validationResult.isValid()) {
+ throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, validationResult.getResult());
+ }
+ return jpaConceptList;
+ }
+}