GithubTicketSystem.java 7.08 KB
Newer Older
1
2
package de.hftstuttgart.unifiedticketing.systems.github;

3
4
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
5
import de.hftstuttgart.unifiedticketing.core.*;
6
7
import de.hftstuttgart.unifiedticketing.exceptions.*;
import okhttp3.*;
8

9
import java.io.IOException;
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class GithubTicketSystem extends TicketSystem<GithubTicket, GithubTicketSystem, GithubTicketBuilder, GithubFilter>
{
    private final static Logger logger = Logging.getLogger(GithubTicketSystem.class.getName());

    protected final String acceptHeader;
    protected final String apiKey;
    protected final String username;

    /**
     * creates a new instance of this class from an uri.<br>
     * <br>
     * <b>Attention:</b> This method should not be called from the enduser!<br>
     * Instead call the same method from {@link TicketSystem}.<br>
     * To call this method directly, the uri has to be shortend by the {@code "unifiedticketing:github:"} part.
     * @param uri gitlab specific part of full uri
     * @return new github ticket system instance
     */
    public static GithubTicketSystem fromUri(String uri)
    {
        Matcher matcher = Pattern.compile("^((http|https):\\/\\/)?(.*?(:[0-9]+.*?)?)::(.*?):(.*?)(:(.*?):(.*?))?$").matcher(uri);

        if (!matcher.matches())
        {
            String msg = "uri didn't match regex";
            logger.log(Level.SEVERE, msg);
            throw new AssertionException(msg);
        }

        GithubTicketSystemBuilder builder = new GithubTicketSystemBuilder();

        if (matcher.group(2) != null && matcher.group(2).length() > 0)
        {
            if (matcher.group(2).equalsIgnoreCase("http")) builder.withHttp();
            else builder.withHttps();
        }

        if (matcher.group(3) == null || matcher.group(3).length() == 0)
        {
            String msg = "no base url identified in uri";
            throw new AssertionException(msg);
        }
        builder.withBaseUrl(matcher.group(3));

        if (matcher.group(5) == null || matcher.group(5).length() == 0)
        {
            String msg = "no owner identified in uri";
            throw new AssertionException(msg);
        }
        builder.withOwner(matcher.group(5));

        if (matcher.group(6) == null || matcher.group(6).length() == 0)
        {
            String msg = "no repo identified in uri";
            throw new AssertionException(msg);
        }
        builder.withRepo(matcher.group(6));

        if (matcher.group(8) != null && matcher.group(9) != null)
        {
            builder.withAuthentication(matcher.group(8), matcher.group(9));
        }
        else logger.log(Level.INFO, "no authentication given, creating anonymous instance");

        return builder.build();
    }

    protected GithubTicketSystem(String acceptHeader, String baseUrl)
    {
        this(acceptHeader, baseUrl, null, null);
    }

    protected GithubTicketSystem(String acceptHeader, String baseUrl, String username, String apiKey)
    {
        super();

        this.acceptHeader = acceptHeader;
        this.apiKey = apiKey;
        this.baseUrl = baseUrl;
        this.username = username;
    }

    /**
     * starts builder process for new github ticket
     */
    @Override
    public GithubTicketBuilder createTicket()
    {
        return new GithubTicketBuilder(this);
    }

    @Override
    public GithubFilter find()
    {
        return new GithubFilter(this);
    }

111
112
    protected OkHttpClient getHttpClient() { return new OkHttpClient(); }

113
114
115
    @Override
    public GithubTicket getTicketById(String id)
    {
116
117
118
119
120
121
        ObjectMapper mapper = new ObjectMapper()
            .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

        Request.Builder requestBuilder = new Request.Builder()
            .url(String.format("%s/%s", baseUrl, id))
            .addHeader("accept", acceptHeader)
122
123
            .get();

124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
        if (username != null && apiKey != null)
        {
            requestBuilder.addHeader("Authorization", Credentials.basic(username, apiKey));
            logger.log(Level.FINEST, "added token authentication header");
        }

        HttpUrl.Builder urlBuilder = requestBuilder.build().url().newBuilder();

        requestBuilder.url(urlBuilder.build());

        OkHttpClient client = getHttpClient();
        Response response;

        try
        {
            Request request = requestBuilder.build();
            logger.log(Level.FINEST, String.format(
                "created request:\n%s",
                (apiKey != null)
                    ? request.toString().replace(apiKey, "SECRET")
                    : request.toString()
            ));

            response = client.newCall(request).execute();
        }
        catch (IOException e)
        {
            logger.log(Level.SEVERE, String.format("get request FAILED with: %s", e.getMessage()));

            if (getConfigTrue(TicketSystem.ConfigurationOptions.RETURN_NULL_ON_ERROR)) return null;
            else throw new HttpReqeustException(e);
        }

        if (response.code() >= 400)
158
        {
159
160
161
162
163
164
165
166
167
            logger.log(Level.SEVERE, String.format(
                "request failed with response code %d",
                response.code()
            ));

            if (getConfigTrue(TicketSystem.ConfigurationOptions.RETURN_NULL_ON_ERROR)) return null;
            else throw new HttpResponseException(
                String.format("ticket query failed, error response code: %d", response.code()),
                response.code());
168
        }
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197

        logger.log(Level.FINEST, "response received\n");

        ResponseBody responseBody;
        responseBody = response.body();

        if (responseBody == null)
        {
            logger.log(Level.SEVERE, "query didn't deliver a body in response");

            if (getConfigTrue(TicketSystem.ConfigurationOptions.RETURN_NULL_ON_ERROR)) return null;
            else throw new HttpResponseException("ticket query failed, no response body", response.code());
        }

        GithubTicketResponse tr;
        try
        {
            tr = mapper.readValue(responseBody.bytes(), GithubTicketResponse.class);

            logger.log(Level.FINER, "parsed response body to ticketResponse instance");
        } catch (IOException e)
        {
            logger.log(Level.SEVERE, String.format("parsing query response FAILED with: %s", e.getMessage()));

            if (getConfigTrue(TicketSystem.ConfigurationOptions.RETURN_NULL_ON_ERROR)) return null;
            else throw new DeserializationException(e);
        }

        return GithubTicket.fromTicketResponse(this, tr);
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
    }

    @Override
    public boolean hasAssigneeSupport()
    {
        return true;
    }

    @Override
    public boolean hasDefaultPagination()
    {
        return true;
    }

    @Override
    public boolean hasLabelSupport()
    {
        return true;
    }

    @Override
    public boolean hasPaginationSupport()
    {
        return true;
    }

    @Override
    public boolean hasReturnNullOnErrorSupport()
    {
        return true;
    }
}