View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.syncope.client.console.rest;
20  
21  import com.fasterxml.jackson.databind.JsonNode;
22  import com.fasterxml.jackson.databind.json.JsonMapper;
23  import java.io.InputStream;
24  import java.util.ArrayList;
25  import java.util.Comparator;
26  import java.util.Iterator;
27  import java.util.List;
28  import java.util.Map;
29  import java.util.stream.Collectors;
30  import java.util.stream.Stream;
31  import javax.ws.rs.core.MediaType;
32  import javax.ws.rs.core.Response;
33  import org.apache.cxf.jaxrs.client.WebClient;
34  import org.apache.syncope.client.console.SyncopeWebApplication;
35  import org.apache.syncope.client.ui.commons.rest.RestClient;
36  import org.apache.syncope.common.keymaster.client.api.model.Domain;
37  import org.apache.syncope.common.keymaster.client.api.model.NetworkService;
38  import org.apache.syncope.common.lib.SyncopeConstants;
39  import org.apache.syncope.common.lib.types.AuditLoggerName;
40  import org.slf4j.Logger;
41  import org.slf4j.LoggerFactory;
42  import org.springframework.boot.logging.LogLevel;
43  
44  public class LoggerConfRestClient implements RestClient, LoggerConfOp {
45  
46      private static final long serialVersionUID = 16051907544728L;
47  
48      protected static final Logger LOG = LoggerFactory.getLogger(LoggerConfRestClient.class);
49  
50      protected static final JsonMapper MAPPER = JsonMapper.builder().findAndAddModules().build();
51  
52      private final List<NetworkService> instances;
53  
54      private final List<String> domains;
55  
56      public LoggerConfRestClient(final List<NetworkService> instances, final List<Domain> domains) {
57          this.instances = instances;
58          this.domains = Stream.concat(
59                  Stream.of(SyncopeConstants.MASTER_DOMAIN), domains.stream().map(Domain::getKey)).
60                  collect(Collectors.toList());
61      }
62  
63      protected String getActuatorEndpoint(final NetworkService instance) {
64          String address = instance.getAddress();
65          if (address.contains("/rest")) {
66              address = address.replace("/rest", "");
67          }
68          return address + "actuator/loggers";
69      }
70  
71      protected WebClient webClient(final NetworkService instance) {
72          return WebClient.create(
73                  getActuatorEndpoint(instance),
74                  SyncopeWebApplication.get().getAnonymousUser(),
75                  SyncopeWebApplication.get().getAnonymousKey(),
76                  null).
77                  accept(MediaType.APPLICATION_JSON_TYPE).
78                  type(MediaType.APPLICATION_JSON_TYPE);
79      }
80  
81      @Override
82      public List<LoggerConf> list() {
83          List<LoggerConf> loggerConfs = new ArrayList<>();
84  
85          try {
86              Response response = webClient(instances.get(0)).get();
87              if (response.getStatus() == Response.Status.OK.getStatusCode()) {
88                  JsonNode node = MAPPER.readTree((InputStream) response.getEntity());
89                  if (node.has("loggers")) {
90                      for (Iterator<Map.Entry<String, JsonNode>> itor = node.get("loggers").fields(); itor.hasNext();) {
91                          Map.Entry<String, JsonNode> entry = itor.next();
92  
93                          LoggerConf loggerConf = new LoggerConf();
94                          loggerConf.setKey(entry.getKey());
95                          if (entry.getValue().has("effectiveLevel")) {
96                              loggerConf.setLevel(LogLevel.valueOf(entry.getValue().get("effectiveLevel").asText()));
97                          } else {
98                              loggerConf.setLevel(LogLevel.OFF);
99                          }
100 
101                         if (!loggerConf.getKey().startsWith(AuditLoggerName.AUDIT_PREFIX)
102                                 && domains.stream().noneMatch(domain -> loggerConf.getKey().startsWith(domain))) {
103 
104                             loggerConfs.add(loggerConf);
105                         }
106                     }
107                 }
108             } else {
109                 LOG.error("Unexpected response for loggers from {}: {}",
110                         getActuatorEndpoint(instances.get(0)), response.getStatus());
111             }
112         } catch (Exception e) {
113             LOG.error("Could not fetch loggers from {}", getActuatorEndpoint(instances.get(0)), e);
114         }
115 
116         loggerConfs.sort(Comparator.comparing(LoggerConf::getKey));
117         return loggerConfs;
118     }
119 
120     @Override
121     public void setLevel(final String key, final LogLevel level) {
122         instances.forEach(i -> webClient(i).path(key).post("{\"configuredLevel\": \"" + level.name() + "\"}"));
123     }
124 }