28 | * Required by JaCoCo starting from v0.83
29 | * https://github.com/jacoco/jacoco/pull/822
30 | * https://www.jacoco.org/jacoco/trunk/doc/changes.html (Release 0.8.3 (2019/01/23))
31 | * https://github.com/jacoco/jacoco/blob/f72c2c865fa7c975debb1b3156120501843f5c74/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/AnnotationGeneratedFilter.java#L51
32 | * By default, annotation retention policy is CLASS, which does not make your annotation available to reflection
33 | */
34 | @Documented
35 | @Retention(RetentionPolicy.CLASS)
36 | @Target({ElementType.TYPE})
37 | public @interface GeneratedCodeClassCoverageExclusion {}
38 |
--------------------------------------------------------------------------------
/src/main/java/io/github/azagniotov/stubby4j/annotations/GeneratedCodeMethodCoverageExclusion.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2012-2024 Alexander Zagniotov
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 | * http://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 io.github.azagniotov.stubby4j.annotations;
18 |
19 | import java.lang.annotation.Documented;
20 | import java.lang.annotation.ElementType;
21 | import java.lang.annotation.Retention;
22 | import java.lang.annotation.RetentionPolicy;
23 | import java.lang.annotation.Target;
24 |
25 | /**
26 | * Marker annotation for exclusion of method from JaCoCo code coverage instrumentation.
27 | *
28 | * Required by JaCoCo starting from v0.83
29 | * https://github.com/jacoco/jacoco/pull/822
30 | * https://www.jacoco.org/jacoco/trunk/doc/changes.html (Release 0.8.3 (2019/01/23))
31 | * https://github.com/jacoco/jacoco/blob/f72c2c865fa7c975debb1b3156120501843f5c74/org.jacoco.core/src/org/jacoco/core/internal/analysis/filter/AnnotationGeneratedFilter.java#L51
32 | * By default, annotation retention policy is RUNTIME, makes your annotation available to reflection
33 | */
34 | @Documented
35 | @Retention(RetentionPolicy.RUNTIME)
36 | @Target({ElementType.CONSTRUCTOR, ElementType.METHOD})
37 | public @interface GeneratedCodeMethodCoverageExclusion {}
38 |
--------------------------------------------------------------------------------
/src/main/java/io/github/azagniotov/stubby4j/annotations/PotentiallyFlaky.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2012-2024 Alexander Zagniotov
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 | * http://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 io.github.azagniotov.stubby4j.annotations;
18 |
19 | import java.lang.annotation.ElementType;
20 | import java.lang.annotation.Retention;
21 | import java.lang.annotation.RetentionPolicy;
22 | import java.lang.annotation.Target;
23 |
24 | @Retention(RetentionPolicy.RUNTIME)
25 | @Target({ElementType.METHOD, ElementType.TYPE})
26 | public @interface PotentiallyFlaky {
27 | /**
28 | * The optional reason why the test is considered flaky.
29 | */
30 | String value() default "";
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/io/github/azagniotov/stubby4j/annotations/VisibleForTesting.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2012-2024 Alexander Zagniotov
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 | * http://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 io.github.azagniotov.stubby4j.annotations;
18 |
19 | import java.lang.annotation.ElementType;
20 | import java.lang.annotation.Retention;
21 | import java.lang.annotation.RetentionPolicy;
22 | import java.lang.annotation.Target;
23 |
24 | /**
25 | * An annotation that indicates that the visibility of a type or member has been relaxed to make the code testable.
26 | * Inspired by @VisibleForTesting from Google's Guava library
27 | */
28 | @Retention(RetentionPolicy.CLASS)
29 | @Target({ElementType.TYPE, ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.FIELD})
30 | public @interface VisibleForTesting {}
31 |
--------------------------------------------------------------------------------
/src/main/java/io/github/azagniotov/stubby4j/caching/Cache.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2012-2024 Alexander Zagniotov
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 | * http://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 io.github.azagniotov.stubby4j.caching;
18 |
19 | import io.github.azagniotov.stubby4j.stubs.StubHttpLifecycle;
20 | import java.util.Optional;
21 | import java.util.concurrent.atomic.AtomicInteger;
22 | import java.util.regex.Pattern;
23 | import org.ehcache.UserManagedCache;
24 |
25 | public interface Cache {
26 |
27 | long CACHE_ENTRY_LIFETIME_SECONDS = 3600L; // 3600 secs => 60 minutes
28 |
29 | static Cache stubHttpLifecycleCache(final boolean buildNoOpCache) {
30 | if (buildNoOpCache) {
31 | return new NoOpStubHttpLifecycleCache();
32 | } else {
33 | return new StubHttpLifecycleCache(CACHE_ENTRY_LIFETIME_SECONDS);
34 | }
35 | }
36 |
37 | static Cache regexPatternCache() {
38 | return new RegexPatternCache(CACHE_ENTRY_LIFETIME_SECONDS);
39 | }
40 |
41 | default Optional get(final K key) {
42 | return Optional.ofNullable(cache().get(key));
43 | }
44 |
45 | default void putIfAbsent(final K key, final V value) {
46 | if (!cache().containsKey(key)) {
47 | cache().put(key, value);
48 | size().incrementAndGet();
49 | }
50 | }
51 |
52 | default boolean clearByKey(final K key) {
53 | if (cache().containsKey(key)) {
54 | cache().remove(key);
55 | size().decrementAndGet();
56 |
57 | return true;
58 | }
59 |
60 | return false;
61 | }
62 |
63 | default void clear() {
64 | cache().clear();
65 | size().set(0);
66 | }
67 |
68 | UserManagedCache cache();
69 |
70 | AtomicInteger size();
71 | }
72 |
--------------------------------------------------------------------------------
/src/main/java/io/github/azagniotov/stubby4j/caching/NoOpStubHttpLifecycleCache.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2012-2024 Alexander Zagniotov
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 | * http://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 io.github.azagniotov.stubby4j.caching;
18 |
19 | import io.github.azagniotov.stubby4j.stubs.StubHttpLifecycle;
20 | import java.util.Optional;
21 | import java.util.concurrent.atomic.AtomicInteger;
22 | import org.ehcache.UserManagedCache;
23 |
24 | class NoOpStubHttpLifecycleCache implements Cache {
25 |
26 | private static final AtomicInteger ATOMIC_INTEGER_ZERO = new AtomicInteger();
27 |
28 | NoOpStubHttpLifecycleCache() {}
29 |
30 | @Override
31 | public Optional get(final String key) {
32 | return Optional.empty();
33 | }
34 |
35 | @Override
36 | public void putIfAbsent(final String key, final StubHttpLifecycle value) {
37 | // NO-OP
38 | }
39 |
40 | @Override
41 | public boolean clearByKey(final String key) {
42 | return true;
43 | }
44 |
45 | @Override
46 | public void clear() {
47 | // NO-OP
48 | }
49 |
50 | @Override
51 | public UserManagedCache cache() {
52 | throw new UnsupportedOperationException();
53 | }
54 |
55 | @Override
56 | public AtomicInteger size() {
57 | return ATOMIC_INTEGER_ZERO;
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/main/java/io/github/azagniotov/stubby4j/caching/RegexPatternCache.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2012-2024 Alexander Zagniotov
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 | * http://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 io.github.azagniotov.stubby4j.caching;
18 |
19 | import java.time.Duration;
20 | import java.util.concurrent.atomic.AtomicInteger;
21 | import java.util.regex.Pattern;
22 | import org.ehcache.UserManagedCache;
23 | import org.ehcache.config.builders.ExpiryPolicyBuilder;
24 | import org.ehcache.config.builders.ResourcePoolsBuilder;
25 | import org.ehcache.config.builders.UserManagedCacheBuilder;
26 |
27 | class RegexPatternCache implements Cache {
28 |
29 | private final AtomicInteger cacheSize;
30 | private final UserManagedCache localCache;
31 |
32 | RegexPatternCache(final long cacheEntryLifetimeSeconds) {
33 | final Duration timeToLiveExpiration = Duration.ofSeconds(cacheEntryLifetimeSeconds);
34 |
35 | this.localCache = UserManagedCacheBuilder.newUserManagedCacheBuilder(Integer.class, Pattern.class)
36 | .withResourcePools(ResourcePoolsBuilder.heap(500L))
37 | .identifier(this.getClass().getSimpleName())
38 | .withExpiry(ExpiryPolicyBuilder.timeToLiveExpiration(timeToLiveExpiration))
39 | .build(true);
40 |
41 | this.cacheSize = new AtomicInteger(0);
42 | }
43 |
44 | @Override
45 | public UserManagedCache cache() {
46 | return localCache;
47 | }
48 |
49 | @Override
50 | public AtomicInteger size() {
51 | return cacheSize;
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/main/java/io/github/azagniotov/stubby4j/caching/StubHttpLifecycleCache.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2012-2024 Alexander Zagniotov
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 | * http://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 io.github.azagniotov.stubby4j.caching;
18 |
19 | import io.github.azagniotov.stubby4j.stubs.StubHttpLifecycle;
20 | import java.time.Duration;
21 | import java.util.concurrent.atomic.AtomicInteger;
22 | import org.ehcache.UserManagedCache;
23 | import org.ehcache.config.builders.ExpiryPolicyBuilder;
24 | import org.ehcache.config.builders.ResourcePoolsBuilder;
25 | import org.ehcache.config.builders.UserManagedCacheBuilder;
26 |
27 | class StubHttpLifecycleCache implements Cache {
28 |
29 | private final AtomicInteger cacheSize;
30 | private final UserManagedCache localCache;
31 |
32 | StubHttpLifecycleCache(final long cacheEntryLifetimeSeconds) {
33 | final Duration timeToLiveExpiration = Duration.ofSeconds(cacheEntryLifetimeSeconds);
34 |
35 | this.localCache = UserManagedCacheBuilder.newUserManagedCacheBuilder(String.class, StubHttpLifecycle.class)
36 | .withResourcePools(ResourcePoolsBuilder.heap(500L))
37 | .identifier(this.getClass().getSimpleName())
38 | .withExpiry(ExpiryPolicyBuilder.timeToLiveExpiration(timeToLiveExpiration))
39 | .build(true);
40 |
41 | this.cacheSize = new AtomicInteger(0);
42 | }
43 |
44 | @Override
45 | public UserManagedCache cache() {
46 | return localCache;
47 | }
48 |
49 | @Override
50 | public AtomicInteger size() {
51 | return cacheSize;
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/main/java/io/github/azagniotov/stubby4j/cli/EmptyLogger.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2012-2024 Alexander Zagniotov
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 | * http://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 io.github.azagniotov.stubby4j.cli;
18 |
19 | import io.github.azagniotov.stubby4j.annotations.GeneratedCodeClassCoverageExclusion;
20 | import org.eclipse.jetty.util.log.Logger;
21 |
22 | /**
23 | * Class used to suppress default console output of Jetty
24 | *
25 | * @author Eric Mrak
26 | */
27 | @GeneratedCodeClassCoverageExclusion
28 | public final class EmptyLogger implements Logger {
29 | @Override
30 | public String getName() {
31 | return null;
32 | }
33 |
34 | @Override
35 | public void warn(final String s, final Object... objects) {}
36 |
37 | @Override
38 | public void warn(final Throwable throwable) {}
39 |
40 | @Override
41 | public void warn(final String s, final Throwable throwable) {}
42 |
43 | @Override
44 | public void info(final String s, final Object... objects) {}
45 |
46 | @Override
47 | public void info(final Throwable throwable) {}
48 |
49 | @Override
50 | public void info(final String s, final Throwable throwable) {}
51 |
52 | @Override
53 | public boolean isDebugEnabled() {
54 | return false;
55 | }
56 |
57 | @Override
58 | public void setDebugEnabled(final boolean b) {}
59 |
60 | @Override
61 | public void debug(final String s, final Object... objects) {}
62 |
63 | @Override
64 | public void debug(final String msg, final long value) {}
65 |
66 | @Override
67 | public void debug(final Throwable throwable) {}
68 |
69 | @Override
70 | public void debug(final String s, final Throwable throwable) {}
71 |
72 | @Override
73 | public Logger getLogger(final String s) {
74 | return this;
75 | }
76 |
77 | @Override
78 | public void ignore(final Throwable throwable) {}
79 | }
80 |
--------------------------------------------------------------------------------
/src/main/java/io/github/azagniotov/stubby4j/client/Authorization.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2012-2024 Alexander Zagniotov
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 | * http://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 io.github.azagniotov.stubby4j.client;
18 |
19 | import io.github.azagniotov.stubby4j.annotations.GeneratedCodeMethodCoverageExclusion;
20 |
21 | public final class Authorization {
22 |
23 | private final AuthorizationType authorizationType;
24 | private final String value;
25 |
26 | public Authorization(final AuthorizationType authorizationType, final String value) {
27 | this.authorizationType = authorizationType;
28 | this.value = value;
29 | }
30 |
31 | public String asFullValue() {
32 | if (authorizationType == AuthorizationType.CUSTOM) {
33 | return value;
34 | } else {
35 | return String.format("%s %s", authorizationType.asString(), value);
36 | }
37 | }
38 |
39 | @Override
40 | @GeneratedCodeMethodCoverageExclusion
41 | public final String toString() {
42 | final StringBuilder sb = new StringBuilder();
43 | sb.append("Authorization");
44 | sb.append("{type=").append(authorizationType);
45 | sb.append(", value=").append(value);
46 | sb.append('}');
47 |
48 | return sb.toString();
49 | }
50 |
51 | enum AuthorizationType {
52 | BASIC("Basic"),
53 | BEARER("Bearer"),
54 | CUSTOM("Custom");
55 | private final String type;
56 |
57 | AuthorizationType(final String type) {
58 | this.type = type;
59 | }
60 |
61 | public String asString() {
62 | return type;
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/main/java/io/github/azagniotov/stubby4j/client/StubbyRequest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2012-2024 Alexander Zagniotov
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 | * http://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 io.github.azagniotov.stubby4j.client;
18 |
19 | import io.github.azagniotov.stubby4j.utils.StringUtils;
20 | import java.util.Locale;
21 |
22 | final class StubbyRequest {
23 |
24 | private static final String URL_TEMPLATE = "%s://%s:%s%s";
25 |
26 | private final String scheme;
27 | private final String method;
28 | private final String uri;
29 | private final String host;
30 | private final String post;
31 | private final Authorization authorization;
32 | private final int clientPort;
33 |
34 | StubbyRequest(
35 | final String scheme,
36 | final String method,
37 | final String uri,
38 | final String host,
39 | final int port,
40 | final Authorization authorization) {
41 | this(scheme, method, uri, host, port, authorization, null);
42 | }
43 |
44 | StubbyRequest(
45 | final String scheme,
46 | final String method,
47 | final String uri,
48 | final String host,
49 | final int clientPort,
50 | final Authorization authorization,
51 | final String post) {
52 | this.scheme = scheme;
53 | this.method = method;
54 | this.uri = uri;
55 | this.host = host;
56 | this.clientPort = clientPort;
57 | this.post = post;
58 | this.authorization = authorization;
59 | }
60 |
61 | String getMethod() {
62 | return method;
63 | }
64 |
65 | String getPost() {
66 | return StringUtils.isSet(post) ? post : "";
67 | }
68 |
69 | Authorization getAuthorization() {
70 | return authorization;
71 | }
72 |
73 | String constructFullUrl() {
74 | return String.format(
75 | URL_TEMPLATE, scheme.toLowerCase(Locale.US), host, clientPort, StringUtils.isSet(uri) ? uri : "");
76 | }
77 |
78 | int calculatePostLength() {
79 | return StringUtils.calculateStringLength(post);
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/src/main/java/io/github/azagniotov/stubby4j/client/StubbyResponse.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2012-2024 Alexander Zagniotov
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 | * http://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 io.github.azagniotov.stubby4j.client;
18 |
19 | import java.util.HashMap;
20 | import java.util.List;
21 | import java.util.Map;
22 |
23 | public final class StubbyResponse {
24 |
25 | private final int statusCode;
26 | private final String body;
27 | private final Map> headerFields;
28 |
29 | public StubbyResponse(final int statusCode, final String body, final Map> headerFields) {
30 | this.statusCode = statusCode;
31 | this.body = body;
32 | this.headerFields = headerFields;
33 | }
34 |
35 | public int statusCode() {
36 | return statusCode;
37 | }
38 |
39 | public String body() {
40 | return body;
41 | }
42 |
43 | public Map> headers() {
44 | return new HashMap<>(headerFields);
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/main/java/io/github/azagniotov/stubby4j/common/Common.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2012-2024 Alexander Zagniotov
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 | * http://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 io.github.azagniotov.stubby4j.common;
18 |
19 | import io.github.azagniotov.stubby4j.http.HttpMethodExtended;
20 | import java.util.Collections;
21 | import java.util.HashSet;
22 | import java.util.Set;
23 | import org.eclipse.jetty.http.HttpMethod;
24 |
25 | public final class Common {
26 |
27 | public static final Set POSTING_METHODS = Collections.unmodifiableSet(new HashSet() {
28 | {
29 | add(HttpMethod.PUT.asString());
30 | add(HttpMethod.POST.asString());
31 | // PATCH is not a part of org.eclipse.jetty.http.HttpMethod
32 | add(HttpMethodExtended.PATCH.asString());
33 | }
34 | });
35 |
36 | public static final String HEADER_APPLICATION_JSON = "application/json";
37 | public static final String HEADER_APPLICATION_XML = "application/xml";
38 | public static final String HEADER_X_STUBBY_RESOURCE_ID = "x-stubby-resource-id";
39 | public static final String HEADER_X_STUBBY_PROXY_CONFIG = "x-stubby4j-proxy-config-uuid";
40 | public static final String HEADER_X_STUBBY_PROXY_REQUEST = "x-stubby4j-proxy-request-uuid";
41 | public static final String HEADER_X_STUBBY_PROXY_RESPONSE = "x-stubby4j-proxy-response-uuid";
42 | public static final String HEADER_X_STUBBY_HTTP_ERROR_REAL_REASON = "x-stubby4j-http-error-real-reason";
43 |
44 | private Common() {}
45 | }
46 |
--------------------------------------------------------------------------------
/src/main/java/io/github/azagniotov/stubby4j/handlers/AbstractHandlerExtension.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2012-2024 Alexander Zagniotov
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 | * http://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 io.github.azagniotov.stubby4j.handlers;
18 |
19 | import io.github.azagniotov.stubby4j.utils.ConsoleUtils;
20 | import javax.servlet.http.HttpServletRequest;
21 | import javax.servlet.http.HttpServletResponse;
22 | import org.eclipse.jetty.server.Request;
23 |
24 | public interface AbstractHandlerExtension {
25 |
26 | default boolean logAndCheckIsHandled(
27 | final String handlerName,
28 | final Request baseRequest,
29 | final HttpServletRequest request,
30 | final HttpServletResponse response) {
31 | ConsoleUtils.logIncomingRequest(request);
32 | if (baseRequest.isHandled() || response.isCommitted()) {
33 | ConsoleUtils.logIncomingRequestError(
34 | request, handlerName, "HTTP response was committed or base request was handled, aborting..");
35 | return true;
36 | }
37 |
38 | return false;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/main/java/io/github/azagniotov/stubby4j/handlers/StubsPortalHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2012-2024 Alexander Zagniotov
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 | * http://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 io.github.azagniotov.stubby4j.handlers;
18 |
19 | import static io.github.azagniotov.stubby4j.handlers.strategy.stubs.StubsResponseHandlingStrategyFactory.getStrategy;
20 |
21 | import io.github.azagniotov.stubby4j.handlers.strategy.stubs.StubResponseHandlingStrategy;
22 | import io.github.azagniotov.stubby4j.stubs.StubRepository;
23 | import io.github.azagniotov.stubby4j.stubs.StubSearchResult;
24 | import io.github.azagniotov.stubby4j.utils.ConsoleUtils;
25 | import io.github.azagniotov.stubby4j.utils.HandlerUtils;
26 | import java.io.IOException;
27 | import javax.servlet.ServletException;
28 | import javax.servlet.http.HttpServletRequest;
29 | import javax.servlet.http.HttpServletResponse;
30 | import org.eclipse.jetty.http.HttpStatus;
31 | import org.eclipse.jetty.server.Request;
32 | import org.eclipse.jetty.server.handler.AbstractHandler;
33 |
34 | public class StubsPortalHandler extends AbstractHandler implements AbstractHandlerExtension {
35 |
36 | private final StubRepository stubRepository;
37 |
38 | public StubsPortalHandler(final StubRepository stubRepository) {
39 | this.stubRepository = stubRepository;
40 | }
41 |
42 | @Override
43 | public void handle(
44 | final String target,
45 | final Request baseRequest,
46 | final HttpServletRequest request,
47 | final HttpServletResponse response)
48 | throws IOException, ServletException {
49 | if (logAndCheckIsHandled("stubs", baseRequest, request, response)) {
50 | return;
51 | }
52 | baseRequest.setHandled(true);
53 |
54 | try {
55 | final StubSearchResult stubSearchResult = stubRepository.search(request);
56 | final StubResponseHandlingStrategy strategyStubResponse = getStrategy(stubSearchResult.getMatch());
57 |
58 | strategyStubResponse.handle(response, stubSearchResult.getInvariant());
59 | ConsoleUtils.logOutgoingResponse(stubSearchResult.getInvariant().getUrl(), response);
60 | } catch (final Exception ex) {
61 | HandlerUtils.configureErrorResponse(response, HttpStatus.INTERNAL_SERVER_ERROR_500, ex.toString());
62 | }
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/src/main/java/io/github/azagniotov/stubby4j/handlers/strategy/admin/AdminResponseHandlingStrategyFactory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2012-2024 Alexander Zagniotov
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 | * http://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 io.github.azagniotov.stubby4j.handlers.strategy.admin;
18 |
19 | import javax.servlet.http.HttpServletRequest;
20 |
21 | public final class AdminResponseHandlingStrategyFactory {
22 |
23 | private AdminResponseHandlingStrategyFactory() {}
24 |
25 | public static AdminResponseHandlingStrategy getStrategy(final HttpServletRequest request) {
26 |
27 | final String method = request.getMethod();
28 | final HttpVerbsEnum verbEnum;
29 |
30 | try {
31 | verbEnum = HttpVerbsEnum.valueOf(method);
32 | } catch (final IllegalArgumentException ex) {
33 | return new NullHandlingStrategy();
34 | }
35 |
36 | switch (verbEnum) {
37 | case POST:
38 | return new PostHandlingStrategy();
39 |
40 | case PUT:
41 | return new PutHandlingStrategy();
42 |
43 | case DELETE:
44 | return new DeleteHandlingStrategy();
45 |
46 | default:
47 | return new GetHandlingStrategy();
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/main/java/io/github/azagniotov/stubby4j/handlers/strategy/admin/HttpVerbsEnum.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2012-2024 Alexander Zagniotov
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 | * http://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 io.github.azagniotov.stubby4j.handlers.strategy.admin;
18 |
19 | public enum HttpVerbsEnum {
20 | GET,
21 | PUT,
22 | POST,
23 | DELETE;
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/io/github/azagniotov/stubby4j/handlers/strategy/admin/NullHandlingStrategy.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2012-2024 Alexander Zagniotov
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 | * http://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 io.github.azagniotov.stubby4j.handlers.strategy.admin;
18 |
19 | import io.github.azagniotov.stubby4j.stubs.StubRepository;
20 | import java.io.IOException;
21 | import javax.servlet.http.HttpServletRequest;
22 | import javax.servlet.http.HttpServletResponse;
23 | import org.eclipse.jetty.http.HttpStatus;
24 |
25 | public class NullHandlingStrategy implements AdminResponseHandlingStrategy {
26 |
27 | @Override
28 | public void handle(
29 | final HttpServletRequest request, final HttpServletResponse response, final StubRepository stubRepository)
30 | throws IOException {
31 | response.setStatus(HttpStatus.NOT_IMPLEMENTED_501);
32 | response.getWriter()
33 | .println(String.format(
34 | "Method %s is not implemented on URI %s", request.getMethod(), request.getRequestURI()));
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/io/github/azagniotov/stubby4j/handlers/strategy/admin/PostHandlingStrategy.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2012-2024 Alexander Zagniotov
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 | * http://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 io.github.azagniotov.stubby4j.handlers.strategy.admin;
18 |
19 | import io.github.azagniotov.stubby4j.handlers.AdminPortalHandler;
20 | import io.github.azagniotov.stubby4j.stubs.StubRepository;
21 | import io.github.azagniotov.stubby4j.utils.HandlerUtils;
22 | import io.github.azagniotov.stubby4j.yaml.YamlParser;
23 | import java.io.IOException;
24 | import java.util.Optional;
25 | import javax.servlet.http.HttpServletRequest;
26 | import javax.servlet.http.HttpServletResponse;
27 | import org.eclipse.jetty.http.HttpHeader;
28 | import org.eclipse.jetty.http.HttpStatus;
29 |
30 | public class PostHandlingStrategy implements AdminResponseHandlingStrategy {
31 |
32 | private static final int NUM_OF_STUBS_THRESHOLD = 1;
33 |
34 | @Override
35 | public void handle(
36 | final HttpServletRequest request, final HttpServletResponse response, final StubRepository stubRepository)
37 | throws Exception {
38 |
39 | if (!request.getRequestURI().equals(AdminPortalHandler.ADMIN_ROOT)) {
40 | response.setStatus(HttpStatus.METHOD_NOT_ALLOWED_405);
41 | return;
42 | }
43 |
44 | final Optional payloadOptional = extractRequestBodyWithOptionalError(request, response);
45 | if (payloadOptional.isPresent()) {
46 | try {
47 | stubRepository.refreshStubsByPost(new YamlParser(), payloadOptional.get());
48 | if (stubRepository.getStubs().size() == NUM_OF_STUBS_THRESHOLD) {
49 | response.addHeader(HttpHeader.LOCATION.asString(), stubRepository.getOnlyStubRequestUrl());
50 | }
51 |
52 | response.setStatus(HttpStatus.CREATED_201);
53 | response.getWriter().println("Configuration created successfully");
54 | } catch (IOException a) {
55 | // Thrown by YamlParser if there are duplicate UUID keys or un-parseable YAML
56 | HandlerUtils.configureErrorResponse(response, HttpStatus.BAD_REQUEST_400, a.getMessage());
57 | }
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/main/java/io/github/azagniotov/stubby4j/handlers/strategy/stubs/NotFoundResponseHandlingStrategy.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2012-2024 Alexander Zagniotov
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 | * http://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 io.github.azagniotov.stubby4j.handlers.strategy.stubs;
18 |
19 | import io.github.azagniotov.stubby4j.stubs.StubRequest;
20 | import io.github.azagniotov.stubby4j.utils.HandlerUtils;
21 | import javax.servlet.http.HttpServletResponse;
22 | import org.eclipse.jetty.http.HttpStatus;
23 | import org.json.JSONObject;
24 |
25 | public final class NotFoundResponseHandlingStrategy implements StubResponseHandlingStrategy {
26 |
27 | NotFoundResponseHandlingStrategy() {}
28 |
29 | @Override
30 | public void handle(final HttpServletResponse response, final StubRequest assertionStubRequest) throws Exception {
31 |
32 | HandlerUtils.setResponseMainHeaders(response);
33 |
34 | final String reason = String.format(
35 | "(404) Nothing found for %s request at URI %s",
36 | assertionStubRequest.getMethod().get(0), assertionStubRequest.getUrl());
37 |
38 | final JSONObject json404Response = new JSONObject();
39 | json404Response.put("reason", reason);
40 | json404Response.put("method", assertionStubRequest.getMethod().get(0));
41 | json404Response.put("url", assertionStubRequest.getUrl());
42 |
43 | if (assertionStubRequest.hasQuery()) {
44 | json404Response.put("query", new JSONObject(assertionStubRequest.getQuery()));
45 | }
46 |
47 | if (assertionStubRequest.hasHeaders()) {
48 | json404Response.put("headers", new JSONObject(assertionStubRequest.getHeaders()));
49 | }
50 |
51 | if (assertionStubRequest.hasPostBody()) {
52 | json404Response.put("post", assertionStubRequest.getPostBody());
53 | }
54 | HandlerUtils.configureErrorResponse(response, HttpStatus.NOT_FOUND_404, json404Response.toString());
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/main/java/io/github/azagniotov/stubby4j/handlers/strategy/stubs/RedirectResponseHandlingStrategy.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2012-2024 Alexander Zagniotov
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 | * http://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 io.github.azagniotov.stubby4j.handlers.strategy.stubs;
18 |
19 | import static io.github.azagniotov.stubby4j.utils.StringUtils.isTokenized;
20 | import static io.github.azagniotov.stubby4j.utils.StringUtils.replaceTokensInString;
21 |
22 | import io.github.azagniotov.stubby4j.stubs.StubRequest;
23 | import io.github.azagniotov.stubby4j.stubs.StubResponse;
24 | import io.github.azagniotov.stubby4j.utils.HandlerUtils;
25 | import io.github.azagniotov.stubby4j.utils.StringUtils;
26 | import java.util.Map;
27 | import java.util.concurrent.TimeUnit;
28 | import javax.servlet.http.HttpServletResponse;
29 | import org.eclipse.jetty.http.HttpHeader;
30 |
31 | public class RedirectResponseHandlingStrategy implements StubResponseHandlingStrategy {
32 |
33 | private final StubResponse foundStubResponse;
34 |
35 | RedirectResponseHandlingStrategy(final StubResponse foundStubResponse) {
36 | this.foundStubResponse = foundStubResponse;
37 | }
38 |
39 | @Override
40 | public void handle(final HttpServletResponse response, final StubRequest assertionStubRequest) throws Exception {
41 | HandlerUtils.setResponseMainHeaders(response);
42 | final Map regexGroups = assertionStubRequest.getRegexGroups();
43 |
44 | if (StringUtils.isSet(foundStubResponse.getLatency())) {
45 | final long latency = Long.parseLong(foundStubResponse.getLatency());
46 | TimeUnit.MILLISECONDS.sleep(latency);
47 | }
48 |
49 | final String headerLocation = foundStubResponse.getHeaders().get("location");
50 | if (isTokenized(headerLocation)) {
51 | response.setHeader(HttpHeader.LOCATION.asString(), replaceTokensInString(headerLocation, regexGroups));
52 | } else {
53 | response.setHeader(HttpHeader.LOCATION.asString(), headerLocation);
54 | }
55 |
56 | response.setStatus(foundStubResponse.getHttpStatusCode().getCode());
57 | response.setHeader(HttpHeader.CONNECTION.asString(), "close");
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/main/java/io/github/azagniotov/stubby4j/handlers/strategy/stubs/StubResponseHandlingStrategy.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2012-2024 Alexander Zagniotov
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 | * http://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 io.github.azagniotov.stubby4j.handlers.strategy.stubs;
18 |
19 | import io.github.azagniotov.stubby4j.stubs.StubRequest;
20 | import javax.servlet.http.HttpServletResponse;
21 |
22 | public interface StubResponseHandlingStrategy {
23 | void handle(final HttpServletResponse response, final StubRequest assertionStubRequest) throws Exception;
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/io/github/azagniotov/stubby4j/handlers/strategy/stubs/StubsResponseHandlingStrategyFactory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2012-2024 Alexander Zagniotov
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 | * http://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 io.github.azagniotov.stubby4j.handlers.strategy.stubs;
18 |
19 | import io.github.azagniotov.stubby4j.stubs.StubResponse;
20 | import org.eclipse.jetty.http.HttpStatus;
21 |
22 | public final class StubsResponseHandlingStrategyFactory {
23 |
24 | private StubsResponseHandlingStrategyFactory() {}
25 |
26 | public static StubResponseHandlingStrategy getStrategy(final StubResponse foundStubResponse) {
27 |
28 | final HttpStatus.Code httpStatusCode = foundStubResponse.getHttpStatusCode();
29 | switch (httpStatusCode) {
30 | case NOT_FOUND:
31 | if (foundStubResponse.getResponseBodyAsBytes().length == 0) {
32 | return new NotFoundResponseHandlingStrategy();
33 | }
34 | break;
35 | case UNAUTHORIZED:
36 | return new UnauthorizedResponseHandlingStrategy();
37 |
38 | case MOVED_PERMANENTLY:
39 | /*
40 | This is an example of industry practice contradicting the standard.
41 | The HTTP/1.0 specification (RFC 1945) required the client to perform a temporary redirect
42 | (the original describing phrase was "Moved Temporarily"), but popular browsers implemented 302 with
43 | the functionality of a 303 See Other. Therefore, HTTP/1.1 added status codes 303 and 307 to
44 | distinguish between the two behaviours. However, some Web applications and frameworks use the 302
45 | status code as if it were the 303.
46 | */
47 | case FOUND:
48 | case MOVED_TEMPORARILY:
49 | case SEE_OTHER:
50 | case TEMPORARY_REDIRECT:
51 | /*
52 | The request and all future requests should be repeated using another URI. 307 and 308 parallel the
53 | behaviors of 302 and 301, but do not allow the HTTP method to change. So, for example, submitting a
54 | form to a permanently redirected resource may continue smoothly.
55 | */
56 | case PERMANENT_REDIRECT:
57 | return new RedirectResponseHandlingStrategy(foundStubResponse);
58 | }
59 |
60 | return new DefaultResponseHandlingStrategy(foundStubResponse);
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/src/main/java/io/github/azagniotov/stubby4j/handlers/strategy/stubs/UnauthorizedResponseHandlingStrategy.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2012-2024 Alexander Zagniotov
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 | * http://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 io.github.azagniotov.stubby4j.handlers.strategy.stubs;
18 |
19 | import io.github.azagniotov.stubby4j.annotations.VisibleForTesting;
20 | import io.github.azagniotov.stubby4j.stubs.StubRequest;
21 | import io.github.azagniotov.stubby4j.utils.HandlerUtils;
22 | import io.github.azagniotov.stubby4j.utils.StringUtils;
23 | import javax.servlet.http.HttpServletResponse;
24 | import org.eclipse.jetty.http.HttpStatus;
25 |
26 | public final class UnauthorizedResponseHandlingStrategy implements StubResponseHandlingStrategy {
27 |
28 | @VisibleForTesting
29 | public static final String NO_AUTHORIZATION_HEADER =
30 | "You are not authorized to view this page without supplied 'Authorization' HTTP header";
31 |
32 | @VisibleForTesting
33 | public static final String WRONG_AUTHORIZATION_HEADER_TEMPLATE =
34 | "Unauthorized with supplied 'authorized' header value: '%s'";
35 |
36 | UnauthorizedResponseHandlingStrategy() {}
37 |
38 | @Override
39 | public void handle(final HttpServletResponse response, final StubRequest assertionStubRequest) throws Exception {
40 | HandlerUtils.setResponseMainHeaders(response);
41 | final String authorizationHeader = assertionStubRequest.getRawHeaderAuthorization();
42 | if (!StringUtils.isSet(authorizationHeader)) {
43 | HandlerUtils.configureErrorResponse(response, HttpStatus.UNAUTHORIZED_401, NO_AUTHORIZATION_HEADER);
44 | return;
45 | }
46 |
47 | HandlerUtils.configureErrorResponse(
48 | response,
49 | HttpStatus.UNAUTHORIZED_401,
50 | String.format(WRONG_AUTHORIZATION_HEADER_TEMPLATE, authorizationHeader));
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/main/java/io/github/azagniotov/stubby4j/http/HttpMethodExtended.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2012-2024 Alexander Zagniotov
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 | * http://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 io.github.azagniotov.stubby4j.http;
18 |
19 | public enum HttpMethodExtended {
20 | PATCH;
21 |
22 | HttpMethodExtended() {}
23 |
24 | public String asString() {
25 | return toString();
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/main/java/io/github/azagniotov/stubby4j/server/JettyContext.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2012-2024 Alexander Zagniotov
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 | * http://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 io.github.azagniotov.stubby4j.server;
18 |
19 | import io.github.azagniotov.stubby4j.annotations.GeneratedCodeClassCoverageExclusion;
20 |
21 | @GeneratedCodeClassCoverageExclusion
22 | public final class JettyContext {
23 |
24 | private final String host;
25 | private final int stubsSslPort;
26 | private final int stubsPort;
27 | private final int adminPort;
28 |
29 | public JettyContext(final String host, final int stubsPort, final int stubsSslPort, final int adminPort) {
30 | this.host = host;
31 | this.stubsSslPort = stubsSslPort;
32 | this.stubsPort = stubsPort;
33 | this.adminPort = adminPort;
34 | }
35 |
36 | public int getStubsTlsPort() {
37 | return stubsSslPort;
38 | }
39 |
40 | public int getStubsPort() {
41 | return stubsPort;
42 | }
43 |
44 | public int getAdminPort() {
45 | return adminPort;
46 | }
47 |
48 | public String getHost() {
49 | return host;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/main/java/io/github/azagniotov/stubby4j/server/ssl/LanIPv4Validator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2012-2024 Alexander Zagniotov
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 | * http://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 io.github.azagniotov.stubby4j.server.ssl;
18 |
19 | import java.util.regex.Pattern;
20 |
21 | public final class LanIPv4Validator {
22 |
23 | /**
24 | * 127.0.0.0 – 127.255.255.255 127.0.0.0 /8
25 | * 10.0.0.0 – 10.255.255.255 10.0.0.0 /8
26 | * 172.16.0.0 – 172. 31.255.255 172.16.0.0 /12
27 | * 192.168.0.0 – 192.168.255.255 192.168.0.0 /16
28 | */
29 | private static final String LAN_IPV4_PATTERN =
30 | "(^192\\.168\\.([0-9]|[0-9][0-9]|[0-2][0-5][0-5])\\.([0-9]|[0-9][0-9]|[0-2][0-5][0-5])$)|(^172\\.([1][6-9]|[2][0-9]|[3][0-1])\\.([0-9]|[0-9][0-9]|[0-2][0-5][0-5])\\.([0-9]|[0-9][0-9]|[0-2][0-5][0-5])$)|(^10\\.([0-9]|[0-9][0-9]|[0-2][0-5][0-5])\\.([0-9]|[0-9][0-9]|[0-2][0-5][0-5])\\.([0-9]|[0-9][0-9]|[0-2][0-5][0-5])$)";
31 |
32 | private static final Pattern PATTERN = Pattern.compile(LAN_IPV4_PATTERN);
33 |
34 | private LanIPv4Validator() {}
35 |
36 | static boolean isPrivateIp(final String privateIp) {
37 | return PATTERN.matcher(privateIp).matches();
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/io/github/azagniotov/stubby4j/stubs/AbstractBuilder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2012-2024 Alexander Zagniotov
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 | * http://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 io.github.azagniotov.stubby4j.stubs;
18 |
19 | import static io.github.azagniotov.generics.TypeSafeConverter.as;
20 |
21 | import io.github.azagniotov.stubby4j.yaml.ConfigurableYAMLProperty;
22 | import java.util.HashMap;
23 | import java.util.Map;
24 | import java.util.Optional;
25 |
26 | public abstract class AbstractBuilder {
27 |
28 | protected final Map fieldNameAndValues;
29 |
30 | public AbstractBuilder() {
31 | this.fieldNameAndValues = new HashMap<>();
32 | }
33 |
34 | public E getStaged(final Class clazzor, final ConfigurableYAMLProperty property, E defaultValue) {
35 | return fieldNameAndValues.containsKey(property) ? as(clazzor, fieldNameAndValues.get(property)) : defaultValue;
36 | }
37 |
38 | public void stage(final ConfigurableYAMLProperty fieldName, final Optional