blob: c7bef92e41c5447af533344b6e3805618b92cdd2 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.apache.skywalking.oap.server.receiver.trace.provider.parser.listener.service;
import lombok.Getter;
import lombok.Setter;
import org.apache.skywalking.apm.network.language.agent.SpanLayer;
import org.apache.skywalking.oap.server.core.Const;
import org.apache.skywalking.oap.server.core.CoreModule;
import org.apache.skywalking.oap.server.core.cache.NetworkAddressInventoryCache;
import org.apache.skywalking.oap.server.core.cache.ServiceInstanceInventoryCache;
import org.apache.skywalking.oap.server.core.cache.ServiceInventoryCache;
import org.apache.skywalking.oap.server.core.register.ServiceInstanceInventory;
import org.apache.skywalking.oap.server.core.register.service.IServiceInstanceInventoryRegister;
import org.apache.skywalking.oap.server.library.module.ModuleManager;
import org.apache.skywalking.oap.server.receiver.trace.provider.TraceServiceModuleConfig;
import org.apache.skywalking.oap.server.receiver.trace.provider.parser.decorator.SegmentCoreInfo;
import org.apache.skywalking.oap.server.receiver.trace.provider.parser.decorator.SpanDecorator;
import org.apache.skywalking.oap.server.receiver.trace.provider.parser.listener.EntrySpanListener;
import org.apache.skywalking.oap.server.receiver.trace.provider.parser.listener.SpanListener;
import org.apache.skywalking.oap.server.receiver.trace.provider.parser.listener.SpanListenerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
/**
* @author zhangwei
*/
public class ServiceInstanceMappingSpanListener implements EntrySpanListener {
private static final Logger logger = LoggerFactory.getLogger(ServiceInstanceMappingSpanListener.class);
private final IServiceInstanceInventoryRegister serviceInstanceInventoryRegister;
private final TraceServiceModuleConfig config;
private final ServiceInventoryCache serviceInventoryCache;
private final ServiceInstanceInventoryCache serviceInstanceInventoryCache;
private final NetworkAddressInventoryCache networkAddressInventoryCache;
private final List<ServiceInstanceMapping> serviceInstanceMappings = new ArrayList<>();
private final List<Integer> serviceInstancesToResetMapping = new ArrayList<>();
public ServiceInstanceMappingSpanListener(ModuleManager moduleManager, TraceServiceModuleConfig config) {
this.serviceInstanceInventoryCache = moduleManager.find(CoreModule.NAME).provider().getService(ServiceInstanceInventoryCache.class);
this.serviceInventoryCache = moduleManager.find(CoreModule.NAME).provider().getService(ServiceInventoryCache.class);
this.serviceInstanceInventoryRegister = moduleManager.find(CoreModule.NAME).provider().getService(IServiceInstanceInventoryRegister.class);
this.networkAddressInventoryCache = moduleManager.find(CoreModule.NAME).provider().getService(NetworkAddressInventoryCache.class);
this.config = config;
}
@Override
public void parseEntry(SpanDecorator spanDecorator, SegmentCoreInfo segmentCoreInfo) {
if (logger.isDebugEnabled()) {
logger.debug("service instance mapping listener parse reference");
}
if (!spanDecorator.getSpanLayer().equals(SpanLayer.MQ)) {
if (spanDecorator.getRefsCount() > 0) {
for (int i = 0; i < spanDecorator.getRefsCount(); i++) {
int networkAddressId = spanDecorator.getRefs(i).getNetworkAddressId();
String address = networkAddressInventoryCache.get(networkAddressId).getName();
int serviceInstanceId = serviceInstanceInventoryCache.getServiceInstanceId(serviceInventoryCache.getServiceId(networkAddressId), networkAddressId);
if (config.getUninstrumentedGatewaysConfig().isAddressConfiguredAsGateway(address)) {
if (logger.isDebugEnabled()) {
logger.debug("{} is configured as gateway, will reset its mapping service instance id", serviceInstanceId);
}
ServiceInstanceInventory instanceInventory = serviceInstanceInventoryCache.get(serviceInstanceId);
if (instanceInventory.getMappingServiceInstanceId() != Const.NONE && !serviceInstancesToResetMapping.contains(serviceInstanceId)) {
serviceInstancesToResetMapping.add(serviceInstanceId);
}
} else {
ServiceInstanceMapping serviceMapping = new ServiceInstanceMapping();
serviceMapping.setServiceInstanceId(serviceInstanceId);
serviceMapping.setMappingServiceInstanceId(segmentCoreInfo.getServiceInstanceId());
serviceInstanceMappings.add(serviceMapping);
}
}
}
}
}
@Override
public void build() {
serviceInstanceMappings.forEach(instanceMapping -> {
if (logger.isDebugEnabled()) {
logger.debug("service instance mapping listener build, service id: {}, mapping service id: {}", instanceMapping.getServiceInstanceId(), instanceMapping.getMappingServiceInstanceId());
}
serviceInstanceInventoryRegister.updateMapping(instanceMapping.getServiceInstanceId(), instanceMapping.getMappingServiceInstanceId());
});
serviceInstancesToResetMapping.forEach(instanceId -> {
if (logger.isDebugEnabled()) {
logger.debug("service instance mapping listener build, reset mapping of service id: {}", instanceId);
}
serviceInstanceInventoryRegister.resetMapping(instanceId);
});
}
@Override
public boolean containsPoint(Point point) {
return Point.Entry.equals(point);
}
public static class Factory implements SpanListenerFactory {
@Override
public SpanListener create(ModuleManager moduleManager, TraceServiceModuleConfig config) {
return new ServiceInstanceMappingSpanListener(moduleManager, config);
}
}
@Getter
@Setter
private static class ServiceInstanceMapping {
private int serviceInstanceId;
private int mappingServiceInstanceId;
}
}