From 4d5cfee4dfd51a1039a60400a1ddba80f7341c63 Mon Sep 17 00:00:00 2001 From: Matthias Cullmann Date: Thu, 18 Jan 2024 15:55:31 +0100 Subject: [PATCH] a little refactoring & cleaning --- LEARNINGS.MD | 3 +- .../baloise/azure/FunctionalOrgEndpoint.java | 136 ++++++++++-------- .../keyvault/secrets/quickstart/Graph.java | 1 - .../java/com/baloise/azure/DevServer.java | 10 +- 4 files changed, 78 insertions(+), 72 deletions(-) diff --git a/LEARNINGS.MD b/LEARNINGS.MD index da0206d..e0165bf 100644 --- a/LEARNINGS.MD +++ b/LEARNINGS.MD @@ -3,12 +3,11 @@ Documentation is sparse and forums (stack overflow ) out dated Use Typed APIs for GraphQL Monitoring / logging is far from real time Strange exception handling / retry logic -No support for REST in Function -> it's low level HTTP Debugging with mvn azure-functions:run -> slow start up & could get code hot swap to work +There are no standards Open points Use terraform? -Get all credentials out of the code -> into environment Use spring web? --> https://docs.spring.io/spring-cloud-function/docs/current/reference/html/azure.html --> https://github.com/spring-cloud/spring-cloud-function/tree/main/spring-cloud-function-samples/function-sample-azure-web diff --git a/src/main/java/com/baloise/azure/FunctionalOrgEndpoint.java b/src/main/java/com/baloise/azure/FunctionalOrgEndpoint.java index 4dc89b1..507f629 100644 --- a/src/main/java/com/baloise/azure/FunctionalOrgEndpoint.java +++ b/src/main/java/com/baloise/azure/FunctionalOrgEndpoint.java @@ -68,74 +68,16 @@ public HttpResponseMessage v1( @BindingName("team") String team ) { try { - context.getLogger().log(Level.INFO, "unit "+ unit); - context.getLogger().log(Level.INFO, "team "+ team); - if(!"null".equals(team)) { - Map> name2team = new HashMap<>(); - - for (Group group : graph().getTeams(unit+"-"+team)) { - Team t = Team.parse(group.displayName); - Map tmp = name2team.get(t.name()); - if(tmp== null) { - tmp = Map.of( - "name", t.name(), - "unit", t.unit(), - "url", getPath(request)+"/"+t.name(), - "members" , loadAndMapMembers(group, t.internal()) - ); - name2team.put(t.name(), tmp); - } else { - List> members = (List>) tmp.get("members"); - members.addAll(loadAndMapMembers(group, t.internal())); - } - } - return request.createResponseBuilder(HttpStatus.OK) - .header("Content-Type","application/json; charset=UTF-8") - .body( - objectMapper.writeValueAsString( - Map.of("teams", name2team.values())) - ).build(); + return createTeamResponse(request, unit, team); } if(!"null".equals(unit)) { - return request.createResponseBuilder(HttpStatus.OK) - .header("Content-Type","application/json; charset=UTF-8") - .body( - objectMapper.writeValueAsString( - Map.of("teams", - graph().getTeams(unit+"-").stream() - .map(g -> Team.parse(g.displayName)) - .map(t -> - Map.of( - "name", t.name(), - "unit", t.unit(), - "url", format("%s/%s/%s", getPath(request), t.unit(),t.name()) - ) - ) - .distinct() - .collect(Collectors.toList()) - )) - ).build(); + return createUnitResponse(request, unit); } - return request.createResponseBuilder(HttpStatus.OK) - .header("Content-Type","application/json; charset=UTF-8") - .body( - objectMapper.writeValueAsString( - Map.of("units", - graph().getTeams().stream() - .map(g -> Team.parse(g.displayName)) - .map(t -> - Map.of( - "name", t.unit(), - "url", request.getUri()+"/"+ t.unit() - ) - ) - .distinct() - .collect(Collectors.toList()) - )) - ).build(); + return createRootResponse(request); + } catch (JsonProcessingException e) { context.getLogger().warning(e.getLocalizedMessage()); return request.createResponseBuilder(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getLocalizedMessage()).build(); @@ -145,6 +87,76 @@ public HttpResponseMessage v1( } } + private HttpResponseMessage createRootResponse(HttpRequestMessage> request) + throws JsonProcessingException { + return request.createResponseBuilder(HttpStatus.OK) + .header("Content-Type","application/json; charset=UTF-8") + .body( + objectMapper.writeValueAsString( + Map.of("units", + graph().getTeams().stream() + .map(g -> Team.parse(g.displayName)) + .map(t -> + Map.of( + "name", t.unit(), + "url", request.getUri()+"/"+ t.unit() + ) + ) + .distinct() + .collect(Collectors.toList()) + )) + ).build(); + } + + private HttpResponseMessage createUnitResponse(HttpRequestMessage> request, String unit) throws JsonProcessingException { + return request.createResponseBuilder(HttpStatus.OK) + .header("Content-Type","application/json; charset=UTF-8") + .body( + objectMapper.writeValueAsString( + Map.of("teams", + graph().getTeams(unit+"-").stream() + .map(g -> Team.parse(g.displayName)) + .map(t -> + Map.of( + "name", t.name(), + "unit", t.unit(), + "url", format("%s/%s/%s", getPath(request), t.unit(),t.name()) + ) + ) + .distinct() + .collect(Collectors.toList()) + )) + ).build(); + } + + private HttpResponseMessage createTeamResponse(HttpRequestMessage> request, String unit, String team) throws JsonProcessingException { + Map> name2team = new HashMap<>(); + + for (Group group : graph().getTeams(unit+"-"+team)) { + Team t = Team.parse(group.displayName); + Map tmp = name2team.get(t.name()); + if(tmp== null) { + tmp = Map.of( + "name", t.name(), + "unit", t.unit(), + "url", getPath(request)+"/"+t.name(), + "members" , loadAndMapMembers(group, t.internal()) + ); + name2team.put(t.name(), tmp); + } else { + @SuppressWarnings("unchecked") + List> members = (List>) tmp.get("members"); + members.addAll(loadAndMapMembers(group, t.internal())); + } + } + return request.createResponseBuilder(HttpStatus.OK) + .header("Content-Type","application/json; charset=UTF-8") + .body( + objectMapper.writeValueAsString( + Map.of("teams", name2team.values())) + ).build(); + } + private List> loadAndMapMembers(Group group, boolean internal) { return graph().getGroupMembers(group.id).stream().map(u-> mapUser(u,internal)).collect(Collectors.toList()); } diff --git a/src/main/java/com/keyvault/secrets/quickstart/Graph.java b/src/main/java/com/keyvault/secrets/quickstart/Graph.java index fb56dcf..cdf8609 100644 --- a/src/main/java/com/keyvault/secrets/quickstart/Graph.java +++ b/src/main/java/com/keyvault/secrets/quickstart/Graph.java @@ -14,7 +14,6 @@ import com.microsoft.graph.http.ICollectionResponse; import com.microsoft.graph.models.DirectoryObject; import com.microsoft.graph.models.Group; -import com.microsoft.graph.models.User; import com.microsoft.graph.options.QueryOption; import com.microsoft.graph.requests.GraphServiceClient; diff --git a/src/test/java/com/baloise/azure/DevServer.java b/src/test/java/com/baloise/azure/DevServer.java index 36dc858..773c017 100644 --- a/src/test/java/com/baloise/azure/DevServer.java +++ b/src/test/java/com/baloise/azure/DevServer.java @@ -9,7 +9,6 @@ import java.io.IOException; import java.io.OutputStream; import java.io.UnsupportedEncodingException; -import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.lang.reflect.Parameter; import java.net.InetSocketAddress; @@ -71,7 +70,7 @@ public ParameterMapping(Method method) { public Object[] map(LinkedList path, HttpExchange exg) { return stream(parameters).map(p->{ if(p.getType().isAssignableFrom(ExecutionContextImpl.class)) { - return new ExecutionContextImpl(exg); + return new ExecutionContextImpl(); } if(p.getType().isAssignableFrom(HttpRequestMessageImpl.class)) { return new HttpRequestMessageImpl(exg); @@ -94,6 +93,7 @@ public Object[] map(LinkedList path, HttpExchange exg) { private Map, Object> instanceMapping = new HashMap<>(); private Map parameterMappings = new HashMap<>(); + @SuppressWarnings("unchecked") public DevServer(Class ... functionClasses) { stream(functionClasses).distinct() .map(clazz ->{ @@ -113,11 +113,6 @@ public DevServer(Class ... functionClasses) { private final class ExecutionContextImpl implements ExecutionContext { private String invocationId = randomUUID().toString(); - private HttpExchange exg; - - public ExecutionContextImpl(HttpExchange exg) { - this.exg = exg; - } @Override public Logger getLogger() { @@ -131,6 +126,7 @@ public String getInvocationId() { @Override public String getFunctionName() { + //TODO return name from annotation return name; } }