1313
1414package io .dapr .testcontainers ;
1515
16+ import io .dapr .testcontainers .converter .ComponentYamlConverter ;
17+ import io .dapr .testcontainers .converter .ConfigurationYamlConverter ;
18+ import io .dapr .testcontainers .converter .SubscriptionYamlConverter ;
19+ import io .dapr .testcontainers .converter .YamlConverter ;
20+ import io .dapr .testcontainers .converter .YamlMapperFactory ;
1621import org .testcontainers .containers .GenericContainer ;
1722import org .testcontainers .containers .Network ;
1823import org .testcontainers .containers .wait .strategy .Wait ;
1924import org .testcontainers .containers .wait .strategy .WaitStrategy ;
2025import org .testcontainers .images .builder .Transferable ;
2126import org .testcontainers .utility .DockerImageName ;
22- import org .yaml .snakeyaml .DumperOptions ;
2327import org .yaml .snakeyaml .Yaml ;
24- import org .yaml .snakeyaml .nodes .Tag ;
25- import org .yaml .snakeyaml .representer .Representer ;
2628
2729import java .io .IOException ;
2830import java .nio .file .Files ;
2931import java .nio .file .Path ;
3032import java .util .ArrayList ;
3133import java .util .Collections ;
32- import java .util .HashMap ;
3334import java .util .HashSet ;
34- import java .util .LinkedHashMap ;
3535import java .util .List ;
3636import java .util .Map ;
3737import java .util .Set ;
3838
3939public class DaprContainer extends GenericContainer <DaprContainer > {
40-
4140 private static final int DAPRD_DEFAULT_HTTP_PORT = 3500 ;
4241 private static final int DAPRD_DEFAULT_GRPC_PORT = 50001 ;
42+ private static final DaprProtocol DAPR_PROTOCOL = DaprProtocol .HTTP ;
43+ private static final DockerImageName DEFAULT_IMAGE_NAME = DockerImageName .parse ("daprio/daprd" );
44+ private static final Yaml YAML_MAPPER = YamlMapperFactory .create ();
45+ private static final YamlConverter <Component > COMPONENT_CONVERTER = new ComponentYamlConverter (YAML_MAPPER );
46+ private static final YamlConverter <Subscription > SUBSCRIPTION_CONVERTER = new SubscriptionYamlConverter (YAML_MAPPER );
47+ private static final YamlConverter <Configuration > CONFIGURATION_CONVERTER = new ConfigurationYamlConverter (
48+ YAML_MAPPER );
4349 private static final WaitStrategy WAIT_STRATEGY = Wait .forHttp ("/v1.0/healthz/outbound" )
4450 .forPort (DAPRD_DEFAULT_HTTP_PORT )
4551 .forStatusCodeMatching (statusCode -> statusCode >= 200 && statusCode <= 399 );
4652
4753 private final Set <Component > components = new HashSet <>();
4854 private final Set <Subscription > subscriptions = new HashSet <>();
49- private DaprProtocol protocol = DaprProtocol .HTTP ;
50- private String appName ;
51- private Integer appPort = null ;
5255 private DaprLogLevel daprLogLevel = DaprLogLevel .INFO ;
5356 private String appChannelAddress = "localhost" ;
5457 private String placementService = "placement" ;
55- private static final DockerImageName DEFAULT_IMAGE_NAME = DockerImageName .parse ("daprio/daprd" );
56- private static final Yaml yaml = getYamlMapper ();
57- private DaprPlacementContainer placementContainer ;
5858 private String placementDockerImageName = "daprio/placement" ;
59+
60+ private Configuration configuration ;
61+ private DaprPlacementContainer placementContainer ;
62+ private String appName ;
63+ private Integer appPort ;
5964 private boolean shouldReusePlacement ;
6065
6166 /**
@@ -78,6 +83,10 @@ public DaprContainer(String image) {
7883 this (DockerImageName .parse (image ));
7984 }
8085
86+ public Configuration getConfiguration () {
87+ return configuration ;
88+ }
89+
8190 public Set <Component > getComponents () {
8291 return components ;
8392 }
@@ -91,6 +100,16 @@ public DaprContainer withAppPort(Integer port) {
91100 return this ;
92101 }
93102
103+ public DaprContainer withAppChannelAddress (String appChannelAddress ) {
104+ this .appChannelAddress = appChannelAddress ;
105+ return this ;
106+ }
107+
108+ public DaprContainer withConfiguration (Configuration configuration ) {
109+ this .configuration = configuration ;
110+ return this ;
111+ }
112+
94113 public DaprContainer withPlacementService (String placementService ) {
95114 this .placementService = placementService ;
96115 return this ;
@@ -111,6 +130,21 @@ public DaprContainer withSubscription(Subscription subscription) {
111130 return this ;
112131 }
113132
133+ public DaprContainer withPlacementImage (String placementDockerImageName ) {
134+ this .placementDockerImageName = placementDockerImageName ;
135+ return this ;
136+ }
137+
138+ public DaprContainer withReusablePlacement (boolean reuse ) {
139+ this .shouldReusePlacement = reuse ;
140+ return this ;
141+ }
142+
143+ public DaprContainer withPlacementContainer (DaprPlacementContainer placementContainer ) {
144+ this .placementContainer = placementContainer ;
145+ return this ;
146+ }
147+
114148 public DaprContainer withComponent (Component component ) {
115149 components .add (component );
116150 return this ;
@@ -123,7 +157,7 @@ public DaprContainer withComponent(Component component) {
123157 */
124158 public DaprContainer withComponent (Path path ) {
125159 try {
126- Map <String , Object > component = this .yaml .loadAs (Files .newInputStream (path ), Map .class );
160+ Map <String , Object > component = this .YAML_MAPPER .loadAs (Files .newInputStream (path ), Map .class );
127161
128162 String type = (String ) component .get ("type" );
129163 Map <String , Object > metadata = (Map <String , Object >) component .get ("metadata" );
@@ -165,60 +199,6 @@ public String getGrpcEndpoint() {
165199 return ":" + getMappedPort (DAPRD_DEFAULT_GRPC_PORT );
166200 }
167201
168- public DaprContainer withAppChannelAddress (String appChannelAddress ) {
169- this .appChannelAddress = appChannelAddress ;
170- return this ;
171- }
172-
173- /**
174- * Get a map of Dapr component details.
175- * @param component A Dapr Component.
176- * @return Map of component details.
177- */
178- public Map <String , Object > componentToMap (Component component ) {
179- Map <String , Object > componentProps = new HashMap <>();
180- componentProps .put ("apiVersion" , "dapr.io/v1alpha1" );
181- componentProps .put ("kind" , "Component" );
182-
183- Map <String , String > componentMetadata = new LinkedHashMap <>();
184- componentMetadata .put ("name" , component .getName ());
185- componentProps .put ("metadata" , componentMetadata );
186-
187- Map <String , Object > componentSpec = new HashMap <>();
188- componentSpec .put ("type" , component .getType ());
189- componentSpec .put ("version" , component .getVersion ());
190-
191- if (!component .getMetadata ().isEmpty ()) {
192- componentSpec .put ("metadata" , component .getMetadata ());
193- }
194-
195- componentProps .put ("spec" , componentSpec );
196- return Collections .unmodifiableMap (componentProps );
197- }
198-
199- /**
200- * Get a map of Dapr subscription details.
201- * @param subscription A Dapr Subscription.
202- * @return Map of subscription details.
203- */
204- public Map <String , Object > subscriptionToMap (Subscription subscription ) {
205- Map <String , Object > subscriptionProps = new HashMap <>();
206- subscriptionProps .put ("apiVersion" , "dapr.io/v1alpha1" );
207- subscriptionProps .put ("kind" , "Subscription" );
208-
209- Map <String , String > subscriptionMetadata = new LinkedHashMap <>();
210- subscriptionMetadata .put ("name" , subscription .getName ());
211- subscriptionProps .put ("metadata" , subscriptionMetadata );
212-
213- Map <String , Object > subscriptionSpec = new HashMap <>();
214- subscriptionSpec .put ("pubsubname" , subscription .getPubsubName ());
215- subscriptionSpec .put ("topic" , subscription .getTopic ());
216- subscriptionSpec .put ("route" , subscription .getRoute ());
217-
218- subscriptionProps .put ("spec" , subscriptionSpec );
219- return Collections .unmodifiableMap (subscriptionProps );
220- }
221-
222202 @ Override
223203 protected void configure () {
224204 super .configure ();
@@ -241,7 +221,7 @@ protected void configure() {
241221 cmds .add (appName );
242222 cmds .add ("--dapr-listen-addresses=0.0.0.0" );
243223 cmds .add ("--app-protocol" );
244- cmds .add (protocol .getName ());
224+ cmds .add (DAPR_PROTOCOL .getName ());
245225 cmds .add ("-placement-host-address" );
246226 cmds .add (placementService + ":50005" );
247227
@@ -257,10 +237,15 @@ protected void configure() {
257237
258238 cmds .add ("--log-level" );
259239 cmds .add (daprLogLevel .toString ());
260- cmds .add ("-components -path" );
240+ cmds .add ("--resources -path" );
261241 cmds .add ("/dapr-resources" );
262242 withCommand (cmds .toArray (new String []{}));
263243
244+ if (configuration != null ) {
245+ String configurationYaml = CONFIGURATION_CONVERTER .convert (configuration );
246+ withCopyToContainer (Transferable .of (configurationYaml ), "/dapr-resources/" + configuration .getName () + ".yaml" );
247+ }
248+
264249 if (components .isEmpty ()) {
265250 components .add (new Component ("kvstore" , "state.in-memory" , "v1" , Collections .emptyMap ()));
266251 components .add (new Component ("pubsub" , "pubsub.in-memory" , "v1" , Collections .emptyMap ()));
@@ -271,28 +256,18 @@ protected void configure() {
271256 }
272257
273258 for (Component component : components ) {
274- String componentYaml = componentToYaml (component );
259+ String componentYaml = COMPONENT_CONVERTER . convert (component );
275260 withCopyToContainer (Transferable .of (componentYaml ), "/dapr-resources/" + component .getName () + ".yaml" );
276261 }
277262
278263 for (Subscription subscription : subscriptions ) {
279- String subscriptionYaml = subscriptionToYaml (subscription );
264+ String subscriptionYaml = SUBSCRIPTION_CONVERTER . convert (subscription );
280265 withCopyToContainer (Transferable .of (subscriptionYaml ), "/dapr-resources/" + subscription .getName () + ".yaml" );
281266 }
282267
283268 dependsOn (placementContainer );
284269 }
285270
286- public String subscriptionToYaml (Subscription subscription ) {
287- Map <String , Object > subscriptionMap = subscriptionToMap (subscription );
288- return yaml .dumpAsMap (subscriptionMap );
289- }
290-
291- public String componentToYaml (Component component ) {
292- Map <String , Object > componentMap = componentToMap (component );
293- return yaml .dumpAsMap (componentMap );
294- }
295-
296271 public String getAppName () {
297272 return appName ;
298273 }
@@ -313,21 +288,6 @@ public static DockerImageName getDefaultImageName() {
313288 return DEFAULT_IMAGE_NAME ;
314289 }
315290
316- public DaprContainer withPlacementImage (String placementDockerImageName ) {
317- this .placementDockerImageName = placementDockerImageName ;
318- return this ;
319- }
320-
321- public DaprContainer withReusablePlacement (boolean reuse ) {
322- this .shouldReusePlacement = reuse ;
323- return this ;
324- }
325-
326- public DaprContainer withPlacementContainer (DaprPlacementContainer placementContainer ) {
327- this .placementContainer = placementContainer ;
328- return this ;
329- }
330-
331291 // Required by spotbugs plugin
332292 @ Override
333293 public boolean equals (Object o ) {
@@ -338,13 +298,4 @@ public boolean equals(Object o) {
338298 public int hashCode () {
339299 return super .hashCode ();
340300 }
341-
342- private static Yaml getYamlMapper () {
343- DumperOptions options = new DumperOptions ();
344- options .setDefaultFlowStyle (DumperOptions .FlowStyle .BLOCK );
345- options .setPrettyFlow (true );
346- Representer representer = new Representer (options );
347- representer .addClassTag (MetadataEntry .class , Tag .MAP );
348- return new Yaml (representer );
349- }
350301}
0 commit comments