Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,9 @@ Comparing to its Typescript counterpart, the Java library is still missing the f
These features will be added in the future releases.

## Changelog
### v0.7.1
- Fixed bug about having duplicate schema types with the same name.
- Improved minor code issues.
### v0.7.0
- Added ability to handle headers and params on webhook triggers.
### v0.6.0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import static io.polyapi.commons.api.model.UpdateStrategy.PROJECT;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

Expand Down Expand Up @@ -41,4 +42,11 @@
* @return boolean The flag indicating if this function is to be deployed.
*/
boolean deployFunction() default true;

/**
* The strategy to be used to update the function once it is deployed. By default, it delegates the strategy to the project.
*
* @return UpdateStrategy The strategy enum.
*/
UpdateStrategy updateStrategy() default PROJECT;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package io.polyapi.commons.api.model;

/**
* Enum that indicates how will the strategy to update to the latest versions of a function be.
*/
public enum UpdateStrategy {
/**
* The function will update to the latest version whenever it is redeployed. This safe version is recommended for final deployment of functions.
*/
MANUAL,
/**
* The function will update to the latest version whenever it is started. This unsafe version may fail suddenly if, for example, the server function is updated before being used and it changes the interface of the function.
* The advantage of this approach is that it doesn't require a redeployment for non-backwards compatibility changes on the function.
*/
AUTOMATIC,

/**
* The function will delegate the strategy of redeployment to the project. If no project property is set, it will default to AUTOMATIC.
*/
PROJECT;
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public String toJsonString(Object object) {
try {
log.debug("Parsing object of type {} to String.", object.getClass().getSimpleName());
String result = objectMapper.writeValueAsString(object);
log.debug("Parsing successful.");
log.debug("Object to String parsing successful.");
if (log.isTraceEnabled()) {
log.trace("Parsed result is:\n{}", result);
}
Expand All @@ -72,7 +72,7 @@ public InputStream toJsonInputStream(Object object) {
try {
log.debug("Parsing object of type {} to InputStream.", Optional.ofNullable(object).map(Object::getClass).map(Class::getName).orElse("null"));
InputStream result = new ByteArrayInputStream(object == null ? new byte[]{} : objectMapper.writeValueAsBytes(object));
log.debug("Parsing successful.");
log.debug("String to object parsing successful.");
if (log.isTraceEnabled()) {
log.trace("Parsed result is:\n{}", IOUtils.toString(result, defaultCharset()));
log.trace("Resetting InputStream.");
Expand Down Expand Up @@ -107,6 +107,7 @@ public <O> O parseString(String json, Type expectedResponseType) {
* @see JsonParser#parseInputStream(InputStream, Type)
*/
@Override
@SuppressWarnings("unchecked")
public <O> O parseInputStream(InputStream json, Type expectedResponseType) {
try {
if (log.isTraceEnabled()) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
package io.polyapi.commons.internal.websocket;

import com.fasterxml.jackson.databind.type.TypeFactory;
import static java.lang.Boolean.FALSE;
import static java.lang.String.format;
import static java.util.concurrent.TimeUnit.MILLISECONDS;

import java.lang.reflect.Type;
import java.net.URI;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

import io.polyapi.commons.api.error.parse.JsonToObjectParsingException;
import io.polyapi.commons.api.error.websocket.EventRegistrationException;
import io.polyapi.commons.api.error.websocket.WebsocketInputParsingException;
Expand All @@ -13,19 +23,6 @@
import io.socket.client.Socket;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Type;
import java.net.URI;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

import static java.lang.Boolean.FALSE;
import static java.lang.String.format;
import static java.util.concurrent.TimeUnit.MILLISECONDS;


@Slf4j
public class SocketIOWebSocketClient implements WebSocketClient {
private final String url;
Expand All @@ -35,7 +32,8 @@ public class SocketIOWebSocketClient implements WebSocketClient {
private final JsonParser jsonParser;
private Socket socket;

public SocketIOWebSocketClient(String url, String clientId, TokenProvider tokenProvider, JsonParser jsonParser, Long registrationTimeout) {
public SocketIOWebSocketClient(String url, String clientId, TokenProvider tokenProvider, JsonParser jsonParser,
Long registrationTimeout) {
this.clientId = clientId;
this.url = url;
this.tokenProvider = tokenProvider;
Expand All @@ -47,8 +45,8 @@ public SocketIOWebSocketClient(String url, String clientId, TokenProvider tokenP
private synchronized Socket getSocket() {
if (this.socket == null) {
this.socket = IO.socket(URI.create(format("%s/events", url)), IO.Options.builder()
.setTransports(new String[]{"websocket"})
.build())
.setTransports(new String[] { "websocket" })
.build())
.connect();
}
return socket;
Expand All @@ -59,14 +57,14 @@ public <T> Handle registerTrigger(String event, String handleId, Type eventType,
CompletableFuture<Boolean> completableFuture = new CompletableFuture<Boolean>()
.orTimeout(registrationTimeout, MILLISECONDS);
log.info("Registering event handler on server.");
getSocket().emit("registerWebhookEventHandler", new Object[]{Map.of("clientID", clientId,
"webhookHandleID", handleId,
"apiKey", tokenProvider.getToken())},
getSocket().emit("registerWebhookEventHandler", new Object[] { Map.of("clientID", clientId,
"webhookHandleID", handleId,
"apiKey", tokenProvider.getToken()) },
objects -> {
log.debug("Received response from server.");
completableFuture.complete((boolean) Optional.ofNullable(objects[0]).orElse(FALSE));
});
if (!completableFuture.get()) {
if (FALSE.equals(completableFuture.get())) {
throw new EventRegistrationException(event, handleId);
}
String eventKey = format("%s:%s", event, handleId);
Expand All @@ -93,7 +91,6 @@ public <T> Handle registerAuthFunctionEventHandler(String id, PolyEventConsumer<
return registerTrigger("", id, Object[].class, trigger);
}


@Override
public void close() {
socket.disconnect();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ public <T extends PolyApiFunction> T createApiFunctionProxy(Class<T> polyInterfa
return createProxy(apiFunctionInvocationHandler, polyInterface);
}

@SuppressWarnings("unchecked")
public <T> T createServerVariableProxy(String type, String packageName) {
return (T) switch (type.toLowerCase()) {
case "boolean" -> new Boolean(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Arrays;

import static java.util.stream.Collectors.joining;
import static java.util.stream.IntStream.range;

@Slf4j
Expand All @@ -26,10 +28,12 @@ public Object invoke(Object proxy, Method method, Object[] arguments) {
var polyMetadata = method.getDeclaringClass().getAnnotation(PolyMetadata.class);
log.debug("Executing method {} in proxy class {}.", method, proxy.getClass().getSimpleName());
log.debug("Executing Poly function with ID '{}'.", polyData.value());
log.debug("Poly metadata param names: {}.", polyMetadata.paramNames());
log.debug("Poly metadata param types: {}.", polyMetadata.paramTypes());

log.debug("Poly metadata param names: {}.", Arrays.stream(polyMetadata.paramNames()).collect(joining(",")));
log.debug("Poly metadata param types: {}.", Arrays.stream(polyMetadata.paramTypes()).collect(joining(",")));
Map<String, Object> body = new HashMap<>();
range(0, polyMetadata.paramNames().length).boxed().forEach(i -> body.put(polyMetadata.paramNames()[i], arguments[i]));
range(0, polyMetadata.paramNames().length).boxed()
.forEach(i -> body.put(polyMetadata.paramNames()[i], arguments[i]));
return invocation.invoke(invokingClass, polyData.value(), body, method.getGenericReturnType());
}
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
package io.polyapi.client.internal.proxy.invocation.handler;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.function.Consumer;

import io.polyapi.client.api.model.PolyEntity;
import io.polyapi.client.api.model.PolyMetadata;
import io.polyapi.client.error.PolyApiLibraryException;
import io.polyapi.commons.api.model.PolyEventConsumer;
import io.polyapi.commons.api.websocket.WebSocketClient;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.function.Consumer;

@Slf4j
public class PolyTriggerInvocationHandler implements InvocationHandler {

Expand All @@ -22,9 +21,10 @@ public PolyTriggerInvocationHandler(WebSocketClient webSocketClient) {
}

@Override
@SuppressWarnings("unchecked")
public Object invoke(Object proxy, Method method, Object[] args) {
try {
PolyEventConsumer<?> consumer = method.getParameterTypes()[0].equals(Consumer.class)? (payload, headers, params) -> Consumer.class.cast(args[0]).accept(payload) : PolyEventConsumer.class.cast(args[0]);
PolyEventConsumer<?> consumer = method.getParameterTypes()[0].equals(Consumer.class)? (payload, headers, params) -> ((Consumer<Object>)args[0]).accept(payload) : PolyEventConsumer.class.cast(args[0]);
Class<?> invokingClass = method.getDeclaringClass();
var polyData = invokingClass.getAnnotation(PolyEntity.class);
var polyMetadata = method.getDeclaringClass().getAnnotation(PolyMetadata.class);
Expand Down
Loading