Skip to content

Commit 22ebcbf

Browse files
Yannic92GitHub Enterprise
authored and
GitHub Enterprise
committed
Merge pull request eclipse-ditto#8 from bosch-iot-things/feature/move-live-signals
Move live signals into ditto-java-client
2 parents 67d06a7 + 62414df commit 22ebcbf

File tree

242 files changed

+21301
-86
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

242 files changed

+21301
-86
lines changed

java/pom.xml

-12
Original file line numberDiff line numberDiff line change
@@ -847,11 +847,6 @@
847847
<artifactId>ditto-signals-commands-things</artifactId>
848848
<version>${ditto.version}</version>
849849
</dependency>
850-
<dependency>
851-
<groupId>org.eclipse.ditto</groupId>
852-
<artifactId>ditto-signals-commands-live</artifactId>
853-
<version>${ditto.version}</version>
854-
</dependency>
855850
<dependency>
856851
<groupId>org.eclipse.ditto</groupId>
857852
<artifactId>ditto-signals-commands-messages</artifactId>
@@ -1045,13 +1040,6 @@
10451040
<version>${ditto.version}</version>
10461041
<scope>test</scope>
10471042
</dependency>
1048-
<dependency>
1049-
<groupId>org.eclipse.ditto</groupId>
1050-
<artifactId>ditto-signals-commands-live</artifactId>
1051-
<type>test-jar</type>
1052-
<version>${ditto.version}</version>
1053-
<scope>test</scope>
1054-
</dependency>
10551043
<dependency>
10561044
<groupId>org.eclipse.ditto</groupId>
10571045
<artifactId>ditto-signals-events-base</artifactId>

java/src/main/assembly/assembly.xml

-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@
4848
<include>org.eclipse.ditto:ditto-signals-commands-things</include>
4949
<include>org.eclipse.ditto:ditto-signals-commands-policies</include>
5050
<include>org.eclipse.ditto:ditto-signals-commands-messages</include>
51-
<include>org.eclipse.ditto:ditto-signals-commands-live</include>
5251
<include>org.eclipse.ditto:ditto-signals-events-base</include>
5352
<include>org.eclipse.ditto:ditto-signals-events-things</include>
5453
<include>org.eclipse.ditto:ditto-signals-events-thingsearch</include>

java/src/main/java/org/eclipse/ditto/client/live/LiveCommandProcessor.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@
1717
import java.util.stream.Stream;
1818

1919
import org.eclipse.ditto.client.live.commands.LiveCommandHandler;
20+
import org.eclipse.ditto.client.live.commands.base.LiveCommand;
21+
import org.eclipse.ditto.client.live.commands.base.LiveCommandAnswer;
22+
import org.eclipse.ditto.client.live.commands.base.LiveCommandAnswerBuilder;
2023
import org.eclipse.ditto.signals.base.Signal;
21-
import org.eclipse.ditto.signals.commands.live.base.LiveCommand;
22-
import org.eclipse.ditto.signals.commands.live.base.LiveCommandAnswer;
23-
import org.eclipse.ditto.signals.commands.live.base.LiveCommandAnswerBuilder;
2424
import org.slf4j.Logger;
2525

2626
/**

java/src/main/java/org/eclipse/ditto/client/live/commands/FeaturePropertiesCommandHandling.java

+9-9
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,17 @@
1515
import java.util.function.Function;
1616

1717
import org.eclipse.ditto.client.live.LiveCommandProcessor;
18-
import org.eclipse.ditto.signals.commands.live.base.LiveCommandAnswerBuilder;
19-
import org.eclipse.ditto.signals.commands.live.modify.DeleteFeaturePropertiesLiveCommand;
20-
import org.eclipse.ditto.signals.commands.live.modify.DeleteFeaturePropertyLiveCommand;
21-
import org.eclipse.ditto.signals.commands.live.modify.MergeThingLiveCommand;
22-
import org.eclipse.ditto.signals.commands.live.modify.ModifyFeaturePropertiesLiveCommand;
23-
import org.eclipse.ditto.signals.commands.live.modify.ModifyFeaturePropertyLiveCommand;
24-
import org.eclipse.ditto.signals.commands.live.query.RetrieveFeaturePropertiesLiveCommand;
25-
import org.eclipse.ditto.signals.commands.live.query.RetrieveFeaturePropertyLiveCommand;
18+
import org.eclipse.ditto.client.live.commands.base.LiveCommandAnswerBuilder;
19+
import org.eclipse.ditto.client.live.commands.modify.DeleteFeaturePropertiesLiveCommand;
20+
import org.eclipse.ditto.client.live.commands.modify.DeleteFeaturePropertyLiveCommand;
21+
import org.eclipse.ditto.client.live.commands.modify.MergeThingLiveCommand;
22+
import org.eclipse.ditto.client.live.commands.modify.ModifyFeaturePropertiesLiveCommand;
23+
import org.eclipse.ditto.client.live.commands.modify.ModifyFeaturePropertyLiveCommand;
24+
import org.eclipse.ditto.client.live.commands.query.RetrieveFeaturePropertiesLiveCommand;
25+
import org.eclipse.ditto.client.live.commands.query.RetrieveFeaturePropertyLiveCommand;
2626

2727
/**
28-
* Provides the necessary functionality for registering {@link org.eclipse.ditto.signals.commands.live.base.LiveCommand
28+
* Provides the necessary functionality for registering {@link org.eclipse.ditto.client.live.commands.base.LiveCommand
2929
* LiveCommand} functions to receive commands to manage and retrieve {@link org.eclipse.ditto.model.things.FeatureProperties
3030
* FeatureProperties}.
3131
*

java/src/main/java/org/eclipse/ditto/client/live/commands/FeaturesCommandHandling.java

+9-9
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,17 @@
1414

1515
import java.util.function.Function;
1616

17-
import org.eclipse.ditto.signals.commands.live.base.LiveCommandAnswerBuilder;
18-
import org.eclipse.ditto.signals.commands.live.modify.DeleteFeatureLiveCommand;
19-
import org.eclipse.ditto.signals.commands.live.modify.DeleteFeaturesLiveCommand;
20-
import org.eclipse.ditto.signals.commands.live.modify.MergeThingLiveCommand;
21-
import org.eclipse.ditto.signals.commands.live.modify.ModifyFeatureLiveCommand;
22-
import org.eclipse.ditto.signals.commands.live.modify.ModifyFeaturesLiveCommand;
23-
import org.eclipse.ditto.signals.commands.live.query.RetrieveFeatureLiveCommand;
24-
import org.eclipse.ditto.signals.commands.live.query.RetrieveFeaturesLiveCommand;
17+
import org.eclipse.ditto.client.live.commands.base.LiveCommandAnswerBuilder;
18+
import org.eclipse.ditto.client.live.commands.modify.DeleteFeatureLiveCommand;
19+
import org.eclipse.ditto.client.live.commands.modify.DeleteFeaturesLiveCommand;
20+
import org.eclipse.ditto.client.live.commands.modify.MergeThingLiveCommand;
21+
import org.eclipse.ditto.client.live.commands.modify.ModifyFeatureLiveCommand;
22+
import org.eclipse.ditto.client.live.commands.modify.ModifyFeaturesLiveCommand;
23+
import org.eclipse.ditto.client.live.commands.query.RetrieveFeatureLiveCommand;
24+
import org.eclipse.ditto.client.live.commands.query.RetrieveFeaturesLiveCommand;
2525

2626
/**
27-
* Provides the necessary functionality for registering {@link org.eclipse.ditto.signals.commands.live.base.LiveCommand
27+
* Provides the necessary functionality for registering {@link org.eclipse.ditto.client.live.commands.base.LiveCommand
2828
* LiveCommand} functions to receive commands to manage and retrieve {@link org.eclipse.ditto.model.things.Feature
2929
* Feature}s.
3030
*

java/src/main/java/org/eclipse/ditto/client/live/commands/LiveCommandAcknowledgeable.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,13 @@
1717
import java.util.stream.Collectors;
1818

1919
import org.eclipse.ditto.client.ack.Acknowledgeable;
20-
import org.eclipse.ditto.client.changes.AcknowledgementRequestHandle;
2120
import org.eclipse.ditto.client.ack.internal.ImmutableAcknowledgementRequestHandle;
21+
import org.eclipse.ditto.client.changes.AcknowledgementRequestHandle;
22+
import org.eclipse.ditto.client.live.commands.base.LiveCommand;
23+
import org.eclipse.ditto.client.live.commands.base.LiveCommandAnswerBuilder;
2224
import org.eclipse.ditto.model.base.acks.AcknowledgementLabel;
2325
import org.eclipse.ditto.model.base.acks.AcknowledgementRequest;
2426
import org.eclipse.ditto.signals.base.Signal;
25-
import org.eclipse.ditto.signals.commands.live.base.LiveCommand;
26-
import org.eclipse.ditto.signals.commands.live.base.LiveCommandAnswerBuilder;
2727

2828
/**
2929
* Acknowledgeable of a live command.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
/*
2+
* Copyright (c) 2021 Contributors to the Eclipse Foundation
3+
*
4+
* See the NOTICE file(s) distributed with this work for additional
5+
* information regarding copyright ownership.
6+
*
7+
* This program and the accompanying materials are made available under the
8+
* terms of the Eclipse Public License 2.0 which is available at
9+
* http://www.eclipse.org/legal/epl-2.0
10+
*
11+
* SPDX-License-Identifier: EPL-2.0
12+
*/
13+
package org.eclipse.ditto.client.live.commands;
14+
15+
import static org.eclipse.ditto.model.base.common.ConditionChecker.checkNotNull;
16+
17+
import java.text.MessageFormat;
18+
import java.util.Collections;
19+
import java.util.HashMap;
20+
import java.util.Map;
21+
import java.util.function.Function;
22+
23+
import javax.annotation.Nonnull;
24+
import javax.annotation.concurrent.Immutable;
25+
26+
import org.eclipse.ditto.client.live.commands.base.LiveCommand;
27+
import org.eclipse.ditto.client.live.commands.modify.ModifyLiveCommandFactory;
28+
import org.eclipse.ditto.client.live.commands.query.QueryLiveCommandFactory;
29+
import org.eclipse.ditto.signals.commands.base.Command;
30+
import org.eclipse.ditto.signals.commands.things.modify.CreateThing;
31+
import org.eclipse.ditto.signals.commands.things.modify.DeleteAttribute;
32+
import org.eclipse.ditto.signals.commands.things.modify.DeleteAttributes;
33+
import org.eclipse.ditto.signals.commands.things.modify.DeleteFeature;
34+
import org.eclipse.ditto.signals.commands.things.modify.DeleteFeatureDefinition;
35+
import org.eclipse.ditto.signals.commands.things.modify.DeleteFeatureProperties;
36+
import org.eclipse.ditto.signals.commands.things.modify.DeleteFeatureProperty;
37+
import org.eclipse.ditto.signals.commands.things.modify.DeleteFeatures;
38+
import org.eclipse.ditto.signals.commands.things.modify.DeleteThing;
39+
import org.eclipse.ditto.signals.commands.things.modify.MergeThing;
40+
import org.eclipse.ditto.signals.commands.things.modify.ModifyAttribute;
41+
import org.eclipse.ditto.signals.commands.things.modify.ModifyAttributes;
42+
import org.eclipse.ditto.signals.commands.things.modify.ModifyFeature;
43+
import org.eclipse.ditto.signals.commands.things.modify.ModifyFeatureDefinition;
44+
import org.eclipse.ditto.signals.commands.things.modify.ModifyFeatureProperties;
45+
import org.eclipse.ditto.signals.commands.things.modify.ModifyFeatureProperty;
46+
import org.eclipse.ditto.signals.commands.things.modify.ModifyFeatures;
47+
import org.eclipse.ditto.signals.commands.things.modify.ModifyThing;
48+
import org.eclipse.ditto.signals.commands.things.query.RetrieveAttribute;
49+
import org.eclipse.ditto.signals.commands.things.query.RetrieveAttributes;
50+
import org.eclipse.ditto.signals.commands.things.query.RetrieveFeature;
51+
import org.eclipse.ditto.signals.commands.things.query.RetrieveFeatureDefinition;
52+
import org.eclipse.ditto.signals.commands.things.query.RetrieveFeatureProperties;
53+
import org.eclipse.ditto.signals.commands.things.query.RetrieveFeatureProperty;
54+
import org.eclipse.ditto.signals.commands.things.query.RetrieveFeatures;
55+
import org.eclipse.ditto.signals.commands.things.query.RetrieveThing;
56+
import org.eclipse.ditto.signals.commands.things.query.RetrieveThings;
57+
58+
/**
59+
* A factory for creating immutable instances of {@link LiveCommand} based on existing <em>Twin Commands</em>.
60+
*
61+
* @since 2.0.0
62+
*/
63+
@Immutable
64+
public final class LiveCommandFactory {
65+
66+
private static final int STRATEGIES_NUMBER = 26;
67+
private static final LiveCommandFactory INSTANCE = new LiveCommandFactory();
68+
69+
private final Map<String, Function<Command, LiveCommand>> mappingStrategies;
70+
71+
private LiveCommandFactory() {
72+
mappingStrategies = Collections.unmodifiableMap(initMappingStrategies());
73+
}
74+
75+
private static Map<String, Function<Command, LiveCommand>> initMappingStrategies() {
76+
final Map<String, Function<Command, LiveCommand>> result = new HashMap<>(STRATEGIES_NUMBER);
77+
result.put(CreateThing.TYPE, ModifyLiveCommandFactory::createThing);
78+
result.put(DeleteAttribute.TYPE, ModifyLiveCommandFactory::deleteAttribute);
79+
result.put(DeleteAttributes.TYPE, ModifyLiveCommandFactory::deleteAttributes);
80+
result.put(DeleteFeature.TYPE, ModifyLiveCommandFactory::deleteFeature);
81+
result.put(DeleteFeatureDefinition.TYPE, ModifyLiveCommandFactory::deleteFeatureDefinition);
82+
result.put(DeleteFeatureProperties.TYPE, ModifyLiveCommandFactory::deleteFeatureProperties);
83+
result.put(DeleteFeatureProperty.TYPE, ModifyLiveCommandFactory::deleteFeatureProperty);
84+
result.put(DeleteFeatures.TYPE, ModifyLiveCommandFactory::deleteFeatures);
85+
result.put(DeleteThing.TYPE, ModifyLiveCommandFactory::deleteThing);
86+
result.put(ModifyAttribute.TYPE, ModifyLiveCommandFactory::modifyAttribute);
87+
result.put(ModifyAttributes.TYPE, ModifyLiveCommandFactory::modifyAttributes);
88+
result.put(ModifyFeature.TYPE, ModifyLiveCommandFactory::modifyFeature);
89+
result.put(ModifyFeatureDefinition.TYPE, ModifyLiveCommandFactory::modifyFeatureDefinition);
90+
result.put(ModifyFeatureProperties.TYPE, ModifyLiveCommandFactory::modifyFeatureProperties);
91+
result.put(ModifyFeatureProperty.TYPE, ModifyLiveCommandFactory::modifyFeatureProperty);
92+
result.put(ModifyFeatures.TYPE, ModifyLiveCommandFactory::modifyFeatures);
93+
result.put(ModifyThing.TYPE, ModifyLiveCommandFactory::modifyThing);
94+
result.put(MergeThing.TYPE, ModifyLiveCommandFactory::mergeThing);
95+
96+
result.put(RetrieveAttribute.TYPE, QueryLiveCommandFactory::retrieveAttribute);
97+
result.put(RetrieveAttributes.TYPE, QueryLiveCommandFactory::retrieveAttributes);
98+
result.put(RetrieveFeature.TYPE, QueryLiveCommandFactory::retrieveFeature);
99+
result.put(RetrieveFeatureDefinition.TYPE, QueryLiveCommandFactory::retrieveFeatureDefinition);
100+
result.put(RetrieveFeatureProperties.TYPE, QueryLiveCommandFactory::retrieveFeatureProperties);
101+
result.put(RetrieveFeatureProperty.TYPE, QueryLiveCommandFactory::retrieveFeatureProperty);
102+
result.put(RetrieveFeatures.TYPE, QueryLiveCommandFactory::retrieveFeatures);
103+
result.put(RetrieveThing.TYPE, QueryLiveCommandFactory::retrieveThing);
104+
result.put(RetrieveThings.TYPE, QueryLiveCommandFactory::retrieveThings);
105+
return result;
106+
}
107+
108+
/**
109+
* Returns an instance of {@code LiveCommandFactory}.
110+
*
111+
* @return the instance.
112+
*/
113+
@Nonnull
114+
public static LiveCommandFactory getInstance() {
115+
return INSTANCE;
116+
}
117+
118+
/**
119+
* Returns an immutable {@link LiveCommand} which is associated with the specified Command.
120+
*
121+
* @param command the command to get a LiveCommand for.
122+
* @return the LiveCommand.
123+
* @throws NullPointerException if {@code command} is {@code null}.
124+
* @throws IllegalArgumentException if the given command cannot be mapped to a LiveCommand because there is no
125+
* mapping strategy associated with the command's type.
126+
*/
127+
@Nonnull
128+
public LiveCommand getLiveCommand(@Nonnull final Command<?> command) {
129+
checkNotNull(command, "command");
130+
131+
final String commandType = command.getType();
132+
final Function<Command, LiveCommand> commandToLiveCommand = mappingStrategies.get(commandType);
133+
if (null == commandToLiveCommand) {
134+
final String msgTemplate = "No mapping strategy for command <{0}> available!"
135+
+ " The command type <{1}> is unknown!";
136+
throw new IllegalArgumentException(MessageFormat.format(msgTemplate, command, commandType));
137+
}
138+
return commandToLiveCommand.apply(command);
139+
}
140+
141+
}

java/src/main/java/org/eclipse/ditto/client/live/commands/LiveCommandHandler.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@
1515
import java.util.function.Consumer;
1616
import java.util.function.Function;
1717

18+
import org.eclipse.ditto.client.live.commands.base.LiveCommand;
19+
import org.eclipse.ditto.client.live.commands.base.LiveCommandAnswerBuilder;
1820
import org.eclipse.ditto.signals.base.Signal;
19-
import org.eclipse.ditto.signals.commands.live.base.LiveCommand;
20-
import org.eclipse.ditto.signals.commands.live.base.LiveCommandAnswerBuilder;
2121

2222
/**
2323
* Generic interface for handling a live command.

java/src/main/java/org/eclipse/ditto/client/live/commands/LiveCommandHandlerImpl.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515
import java.util.function.Consumer;
1616
import java.util.function.Function;
1717

18-
import org.eclipse.ditto.signals.commands.live.base.LiveCommand;
19-
import org.eclipse.ditto.signals.commands.live.base.LiveCommandAnswerBuilder;
18+
import org.eclipse.ditto.client.live.commands.base.LiveCommand;
19+
import org.eclipse.ditto.client.live.commands.base.LiveCommandAnswerBuilder;
2020

2121
/**
2222
* Package-private implementation of {@code LiveCommandHandler}.

java/src/main/java/org/eclipse/ditto/client/live/commands/ThingAttributesCommandHandling.java

+9-9
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,17 @@
1515
import java.util.function.Function;
1616

1717
import org.eclipse.ditto.client.live.LiveCommandProcessor;
18-
import org.eclipse.ditto.signals.commands.live.base.LiveCommandAnswerBuilder;
19-
import org.eclipse.ditto.signals.commands.live.modify.DeleteAttributeLiveCommand;
20-
import org.eclipse.ditto.signals.commands.live.modify.DeleteAttributesLiveCommand;
21-
import org.eclipse.ditto.signals.commands.live.modify.MergeThingLiveCommand;
22-
import org.eclipse.ditto.signals.commands.live.modify.ModifyAttributeLiveCommand;
23-
import org.eclipse.ditto.signals.commands.live.modify.ModifyAttributesLiveCommand;
24-
import org.eclipse.ditto.signals.commands.live.query.RetrieveAttributeLiveCommand;
25-
import org.eclipse.ditto.signals.commands.live.query.RetrieveAttributesLiveCommand;
18+
import org.eclipse.ditto.client.live.commands.base.LiveCommandAnswerBuilder;
19+
import org.eclipse.ditto.client.live.commands.modify.DeleteAttributeLiveCommand;
20+
import org.eclipse.ditto.client.live.commands.modify.DeleteAttributesLiveCommand;
21+
import org.eclipse.ditto.client.live.commands.modify.MergeThingLiveCommand;
22+
import org.eclipse.ditto.client.live.commands.modify.ModifyAttributeLiveCommand;
23+
import org.eclipse.ditto.client.live.commands.modify.ModifyAttributesLiveCommand;
24+
import org.eclipse.ditto.client.live.commands.query.RetrieveAttributeLiveCommand;
25+
import org.eclipse.ditto.client.live.commands.query.RetrieveAttributesLiveCommand;
2626

2727
/**
28-
* Provides the necessary functionality for registering {@link org.eclipse.ditto.signals.commands.live.base.LiveCommand
28+
* Provides the necessary functionality for registering {@link org.eclipse.ditto.client.live.commands.base.LiveCommand
2929
* LiveCommand} function to receive commands to manage and retrieve {@link java.util.jar.Attributes Attributes}.
3030
*
3131
* @since 1.0.0

java/src/main/java/org/eclipse/ditto/client/live/commands/ThingCommandHandling.java

+7-7
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,15 @@
1515
import java.util.function.Function;
1616

1717
import org.eclipse.ditto.client.live.LiveCommandProcessor;
18-
import org.eclipse.ditto.signals.commands.live.base.LiveCommandAnswerBuilder;
19-
import org.eclipse.ditto.signals.commands.live.modify.CreateThingLiveCommand;
20-
import org.eclipse.ditto.signals.commands.live.modify.DeleteThingLiveCommand;
21-
import org.eclipse.ditto.signals.commands.live.modify.MergeThingLiveCommand;
22-
import org.eclipse.ditto.signals.commands.live.modify.ModifyThingLiveCommand;
23-
import org.eclipse.ditto.signals.commands.live.query.RetrieveThingLiveCommand;
18+
import org.eclipse.ditto.client.live.commands.base.LiveCommandAnswerBuilder;
19+
import org.eclipse.ditto.client.live.commands.modify.CreateThingLiveCommand;
20+
import org.eclipse.ditto.client.live.commands.modify.DeleteThingLiveCommand;
21+
import org.eclipse.ditto.client.live.commands.modify.MergeThingLiveCommand;
22+
import org.eclipse.ditto.client.live.commands.modify.ModifyThingLiveCommand;
23+
import org.eclipse.ditto.client.live.commands.query.RetrieveThingLiveCommand;
2424

2525
/**
26-
* Provides the necessary functionality for registering {@link org.eclipse.ditto.signals.commands.live.base.LiveCommand
26+
* Provides the necessary functionality for registering {@link org.eclipse.ditto.client.live.commands.base.LiveCommand
2727
* LiveCommand} functions to receive commands to manage and retrieve <em>a particular</em> {@link
2828
* org.eclipse.ditto.model.things.Thing Thing}.
2929
*

java/src/main/java/org/eclipse/ditto/client/live/commands/ThingsCommandHandling.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@
1414

1515
import java.util.function.Function;
1616

17-
import org.eclipse.ditto.signals.commands.live.base.LiveCommandAnswerBuilder;
18-
import org.eclipse.ditto.signals.commands.live.query.RetrieveThingsLiveCommand;
17+
import org.eclipse.ditto.client.live.commands.base.LiveCommandAnswerBuilder;
18+
import org.eclipse.ditto.client.live.commands.query.RetrieveThingsLiveCommand;
1919

2020
/**
21-
* Provides the necessary functionality for registering {@link org.eclipse.ditto.signals.commands.live.base.LiveCommand
21+
* Provides the necessary functionality for registering {@link org.eclipse.ditto.client.live.commands.base.LiveCommand
2222
* LiveCommand} functions to receive commands to <em>generally</em> manage and retrieve {@link
2323
* org.eclipse.ditto.model.things.Thing Thing}s.
2424
*

0 commit comments

Comments
 (0)