1 /*
2  * Copyright 2013-2019 the original author or authors.
3  *
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  *      https://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  */

16
17 package org.springframework.cloud.aws.messaging.support.destination;
18
19 import java.net.URI;
20 import java.net.URISyntaxException;
21
22 import com.amazonaws.services.sqs.AmazonSQS;
23 import com.amazonaws.services.sqs.model.CreateQueueRequest;
24 import com.amazonaws.services.sqs.model.CreateQueueResult;
25 import com.amazonaws.services.sqs.model.GetQueueUrlRequest;
26 import com.amazonaws.services.sqs.model.GetQueueUrlResult;
27 import com.amazonaws.services.sqs.model.QueueDoesNotExistException;
28
29 import org.springframework.cloud.aws.core.env.ResourceIdResolver;
30 import org.springframework.messaging.core.DestinationResolutionException;
31 import org.springframework.messaging.core.DestinationResolver;
32 import org.springframework.util.Assert;
33
34 /**
35  * @author Agim Emruli
36  * @since 1.0
37  */

38 public class DynamicQueueUrlDestinationResolver implements DestinationResolver<String> {
39
40     private final AmazonSQS amazonSqs;
41
42     private final ResourceIdResolver resourceIdResolver;
43
44     private boolean autoCreate;
45
46     public DynamicQueueUrlDestinationResolver(AmazonSQS amazonSqs,
47             ResourceIdResolver resourceIdResolver) {
48         Assert.notNull(amazonSqs, "amazonSqs must not be null");
49
50         this.amazonSqs = amazonSqs;
51         this.resourceIdResolver = resourceIdResolver;
52     }
53
54     public DynamicQueueUrlDestinationResolver(AmazonSQS amazonSqs) {
55         this(amazonSqs, null);
56     }
57
58     private static boolean isValidQueueUrl(String name) {
59         try {
60             URI candidate = new URI(name);
61             return ("http".equals(candidate.getScheme())
62                     || "https".equals(candidate.getScheme()));
63         }
64         catch (URISyntaxException e) {
65             return false;
66         }
67     }
68
69     public void setAutoCreate(boolean autoCreate) {
70         this.autoCreate = autoCreate;
71     }
72
73     @Override
74     public String resolveDestination(String name) throws DestinationResolutionException {
75         String queueName = name;
76
77         if (this.resourceIdResolver != null) {
78             queueName = this.resourceIdResolver.resolveToPhysicalResourceId(name);
79         }
80
81         if (isValidQueueUrl(queueName)) {
82             return queueName;
83         }
84
85         if (this.autoCreate) {
86             // Auto-create is fine to be called even if the queue exists.
87             CreateQueueResult createQueueResult = this.amazonSqs
88                     .createQueue(new CreateQueueRequest(queueName));
89             return createQueueResult.getQueueUrl();
90         }
91         else {
92             try {
93                 GetQueueUrlResult getQueueUrlResult = this.amazonSqs
94                         .getQueueUrl(new GetQueueUrlRequest(queueName));
95                 return getQueueUrlResult.getQueueUrl();
96             }
97             catch (QueueDoesNotExistException e) {
98                 throw toDestinationResolutionException(e);
99             }
100         }
101     }
102
103     private DestinationResolutionException toDestinationResolutionException(
104             QueueDoesNotExistException e) {
105         if (e.getMessage() != null && e.getMessage().contains("access")) {
106             return new DestinationResolutionException(
107                     "The queue does not exist or no access to perform action sqs:GetQueueUrl.",
108                     e);
109         }
110         else {
111             return new DestinationResolutionException("The queue does not exist.", e);
112         }
113     }
114
115 }
116