Skip to content

Commit

Permalink
Merge branch 'master' into feat-collector-alarm
Browse files Browse the repository at this point in the history
  • Loading branch information
Aias00 authored Oct 29, 2024
2 parents 1caa633 + afe68ba commit 67cb93c
Show file tree
Hide file tree
Showing 112 changed files with 6,858 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/*
* 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.hertzbeat.collector.collect.ipmi2;

import lombok.extern.slf4j.Slf4j;
import org.apache.hertzbeat.collector.collect.AbstractCollect;
import org.apache.hertzbeat.collector.collect.common.cache.CacheIdentifier;
import org.apache.hertzbeat.collector.collect.common.cache.ConnectionCommonCache;
import org.apache.hertzbeat.collector.collect.ipmi2.cache.IpmiConnect;
import org.apache.hertzbeat.collector.collect.ipmi2.client.IpmiClient;
import org.apache.hertzbeat.collector.collect.ipmi2.client.IpmiConnection;
import org.apache.hertzbeat.collector.collect.ipmi2.client.IpmiHandlerManager;
import org.apache.hertzbeat.collector.dispatch.DispatchConstants;
import org.apache.hertzbeat.common.entity.job.Metrics;
import org.apache.hertzbeat.common.entity.job.protocol.IpmiProtocol;
import org.apache.hertzbeat.common.entity.message.CollectRep;
import org.springframework.util.Assert;

import java.io.IOException;
import java.util.Optional;

/**
* Ipmi collect implementation
*/
@Slf4j
public class IpmiCollectImpl extends AbstractCollect {

private final ConnectionCommonCache<CacheIdentifier, IpmiConnect> connectionCommonCache;

private final IpmiHandlerManager ipmiHandlerManager;

public IpmiCollectImpl() {
connectionCommonCache = new ConnectionCommonCache<>();
ipmiHandlerManager = new IpmiHandlerManager();
}


@Override
public void preCheck(Metrics metrics) throws IllegalArgumentException {
if (metrics == null || metrics.getIpmi() == null) {
throw new IllegalArgumentException("Ipmi collect must has ipmi params");
}
IpmiProtocol ipmiProtocol = metrics.getIpmi();
Assert.hasText(ipmiProtocol.getHost(), "Ipmi Protocol host is required.");
Assert.hasText(ipmiProtocol.getPort(), "Ipmi Protocol port is required.");
Assert.hasText(ipmiProtocol.getUsername(), "Ipmi Protocol username is required.");
Assert.hasText(ipmiProtocol.getPassword(), "Ipmi Protocol password is required.");
}

@Override
public void collect(CollectRep.MetricsData.Builder builder, long monitorId, String app, Metrics metrics) {
IpmiConnection connection = null;
try {
connection = getIpmiConnection(metrics.getIpmi());
} catch (Exception e) {
log.error("Ipmi session create error: {}", e.getMessage());
builder.setCode(CollectRep.Code.FAIL);
builder.setMsg(e.getMessage());
return;
}
try {
connection.getResource(builder, metrics);
} catch (IOException e) {
log.error("Get Ipmi {} detail resource error: {}", metrics.getName(), e.getMessage());
}
}

@Override
public String supportProtocol() {
return DispatchConstants.PROTOCOL_IPMI;
}


private IpmiConnection getIpmiConnection(IpmiProtocol ipmiProtocol) throws Exception {
CacheIdentifier identifier = CacheIdentifier.builder()
.ip(ipmiProtocol.getHost())
.port(ipmiProtocol.getPort())
.username(ipmiProtocol.getUsername())
.password(ipmiProtocol.getPassword())
.build();
IpmiConnection connection = null;
Optional<IpmiConnect> cacheOption = connectionCommonCache.getCache(identifier, true);
if (cacheOption.isPresent()) {
IpmiConnect ipmiConnect = cacheOption.get();
connection = ipmiConnect.getConnection();
if (connection == null || !connection.isActive()) {
connection = null;
connectionCommonCache.removeCache(identifier);
}
}
if (connection != null) {
return connection;
}
IpmiClient ipmiClient = IpmiClient.create(ipmiProtocol);
connection = ipmiClient.connect();
connectionCommonCache.addCache(identifier, new IpmiConnect(connection));
return connection;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* 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.hertzbeat.collector.collect.ipmi2.cache;


import org.apache.hertzbeat.collector.collect.common.cache.AbstractConnection;
import org.apache.hertzbeat.collector.collect.ipmi2.client.IpmiConnection;

/**
* ipmi connect session
*/
public class IpmiConnect extends AbstractConnection<IpmiConnection> {

private final IpmiConnection ipmiConnection;

public IpmiConnect(IpmiConnection ipmiConnection) {
this.ipmiConnection = ipmiConnection;
}

@Override
public IpmiConnection getConnection() {
return ipmiConnection;
}

@Override
public void closeConnection() throws Exception {
if (ipmiConnection != null) {
ipmiConnection.close();
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
* 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.hertzbeat.collector.collect.ipmi2.client;

import java.io.IOException;
import java.security.SecureRandom;

import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.payload.RakpMessage1;
import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.payload.RakpMessage2;
import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.payload.RakpMessage3;
import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.payload.RakpMessage4;
import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.payload.RmcpPlusOpenSessionRequest;
import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.payload.RmcpPlusOpenSessionResponse;
import org.apache.hertzbeat.common.entity.job.protocol.IpmiProtocol;

/**
* IpmiClient used to connect to a remote Ipmi server
*/
public class IpmiClient {

UdpConnection connection;
private final String host;
private final Integer port;
private final String username;
private final String password;

public IpmiClient(String host, Integer port, String username, String password) throws IOException {
this.host = host;
this.port = port;
this.username = username;
this.password = password;
connection = new UdpConnection(host, port);
}

public static IpmiClient create(IpmiProtocol ipmiProtocol) throws IOException {
return new IpmiClient(ipmiProtocol.getHost(), Integer.parseInt(ipmiProtocol.getPort()),
ipmiProtocol.getUsername(), ipmiProtocol.getPassword());
}

public IpmiConnection connect() throws IOException {
IpmiSession session = newSession(username, password);

RmcpPlusOpenSessionResponse rmcpPlusOpenSessionResponse = connection.get(session, new RmcpPlusOpenSessionRequest(), RmcpPlusOpenSessionResponse.class);
session.setSystemSessionId(rmcpPlusOpenSessionResponse.systemSessionId);

session.generateConsoleRandomNumber();
RakpMessage2 rakpMessage2 = connection.get(session, new RakpMessage1(), RakpMessage2.class);
session.setSystemRandomNumber(rakpMessage2.systemRandom);
session.setSystemGuid(rakpMessage2.systemGuid);


session.generateSik();
session.setK1(session.generateK(1));
session.setK2(session.generateK(2));
connection.get(session, new RakpMessage3(), RakpMessage4.class);

session.setConnected(true);
return new IpmiConnection(session, connection);
}

public IpmiSession newSession(String username, String password) {
SecureRandom random = new SecureRandom();
IpmiSession session = new IpmiSession(random.nextInt());
session.setUserName(username);
session.setPassword(password);
return session;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* 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.hertzbeat.collector.collect.ipmi2.client;

import java.io.IOException;
import org.apache.hertzbeat.collector.collect.ipmi2.client.handler.IpmiHandler;
import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command.messaging.CloseSessionRequest;
import org.apache.hertzbeat.collector.collect.ipmi2.protocol.ipmi.command.messaging.CloseSessionResponse;
import org.apache.hertzbeat.common.entity.job.Metrics;
import org.apache.hertzbeat.common.entity.message.CollectRep;

/**
* IpmiConnection used for sending ipmi request
*/
public class IpmiConnection implements AutoCloseable {

IpmiSession session;

UdpConnection udpConnection;

IpmiHandlerManager handlerManager = new IpmiHandlerManager();

private volatile boolean active = true;

IpmiConnection(IpmiSession session, UdpConnection udpConnection) {
this.session = session;
this.udpConnection = udpConnection;
}

public void getResource(CollectRep.MetricsData.Builder builder, Metrics metrics) throws IOException {
IpmiHandler handler = handlerManager.getHandler(metrics.getName());
if (handler == null) {
throw new RuntimeException("no handler for " + metrics.getIpmi().getType());
}
handler.handler(session, udpConnection, builder, metrics);
}


@Override
public void close() throws IOException {
udpConnection.get(session, new CloseSessionRequest(session.getSystemSessionId()), CloseSessionResponse.class);
udpConnection.close();
session = null;
active = false;
}

public boolean isActive() {
return this.active;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* 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.hertzbeat.collector.collect.ipmi2.client;

import java.nio.ByteBuffer;
import org.apache.hertzbeat.collector.collect.ipmi2.protocol.rmcp.RmcpPacket;

/**
* IPMI encoder and decoder
*/
public class IpmiEncoderDecoder {

public static ByteBuffer encode(IpmiPacketContext context, RmcpPacket rmcpPacket) {
int length = rmcpPacket.getWireLength(context.getIpmiSession());
ByteBuffer buffer = ByteBuffer.allocate(length);
rmcpPacket.toWire(context, buffer);
buffer.flip();
return buffer;
}

public static RmcpPacket decode(IpmiPacketContext context, ByteBuffer buffer) {
RmcpPacket rmcpPacket = new RmcpPacket();
rmcpPacket.fromWire(context, buffer);
return rmcpPacket;
}
}
Loading

0 comments on commit 67cb93c

Please sign in to comment.