Compare commits

...

81 Commits

Author SHA1 Message Date
Thomas-Leung2021
daabf38510 [NETEXP-2677] set clients disconnected in current client list when moving AP to another SP 2021-08-03 18:05:31 -04:00
Mike Hansen
91877f5305 Merge pull request #139 from Telecominfraproject/WIFI-3259-portal-user-event-payload-fix
[WIFI-3259] Adding default constructor to PortalUserEventPayload for …
2021-07-29 10:10:39 -04:00
ralphlee
11314e3395 [WIFI-3259] Adding default constructor to PortalUserEventPayload for serialization, updated yamls 2021-07-28 12:58:46 -04:00
Mike Hansen
fa6795369c Merge pull request #138 from Telecominfraproject/NETEXP-1632-temp
fix missing RADIO_CHANNEL status
2021-07-27 08:41:07 -04:00
Thomas-Leung2021
e6e06d7b70 fix missing RADIO_CHANNEL status 2021-07-26 17:29:49 -04:00
Mike Hansen
1e15e3cd94 Merge pull request #137 from Telecominfraproject/WIFI-3218-add-null-checks-to-rrm-bulk-update
[WIFI-3218] Adding null checks to RrmBulkUpdateItem
2021-07-22 17:25:38 -04:00
ralphlee
02e03780db [WIFI-3218] Adding null checks to RrmBulkUpdateItem 2021-07-22 17:19:03 -04:00
Mike Hansen
aac34150b2 APs running into Backoff shows as connected
Signed-off-by: Mike Hansen <mike.hansen@connectus.ai>
2021-07-22 15:31:58 -04:00
Mike Hansen
3085c34cde Merge pull request #135 from Telecominfraproject/WIFI-3180-portal-user-search-case-insensitive
[WIFI-3180] Adding case insensitivity to Portal User API Search
2021-07-20 11:53:47 -04:00
Mike Hansen
35fd038113 [WIFI-3166] Session ID is a -ve number in opensyncgw logs and on UI logs
Signed-off-by: Mike Hansen <mike.hansen@connectus.ai>
2021-07-20 11:31:07 -04:00
ralphlee
7c387f1940 [WIFI-3180] Adding case insensitivity to Portal User API Search 2021-07-20 10:38:04 -04:00
Mike Hansen
abb9b59659 Gateway pushes the threshholds as empty which causes AP not to connect any client
Signed-off-by: Mike Hansen <mike.hansen@connectus.ai>
2021-07-20 10:02:59 -04:00
norm-traxler
7f0497754c Merge pull request #134 from Telecominfraproject/WIFI-3042-alarm-remote-fix
[WIFI-3042] Fix alarmCode get url parameter
2021-07-20 08:30:40 -04:00
Norm Traxler
82095510f7 [WIFI-3042] Fix alarmCode get url parameter 2021-07-20 08:23:58 -04:00
Mike Hansen
0afd414870 Merge pull request #133 from Telecominfraproject/change_sessionId_to_String
[WIFI-3166] Session ID is a -ve number in opensyncgw logs and on UI logs
2021-07-19 19:30:42 -04:00
Mike Hansen
772beab902 [WIFI-3166] Session ID is a -ve number in opensyncgw logs and on UI logs
Signed-off-by: Mike Hansen <mike.hansen@connectus.ai>
2021-07-19 19:10:37 -04:00
Mike Hansen
4a764db007 [WIFI-3166] Session ID is a -ve number in opensyncgw logs and on UI logs
Signed-off-by: Mike Hansen <mike.hansen@connectus.ai>
2021-07-19 18:03:13 -04:00
Mike Hansen
41add1922b Merge pull request #132 from Telecominfraproject/WIFI-3041
[WIFI-3041] move if statusment for custmerId check to a different location
2021-07-19 17:54:58 -04:00
Thomas-Leung2021
90ac57b988 [WIFI-3041] move if statement to make it more logical 2021-07-19 17:52:49 -04:00
Thomas-Leung2021
0cc90764c6 [WIFI-3041] move if statusment for custmerId check to a different location 2021-07-19 17:00:54 -04:00
Mike Hansen
1e277f5650 [WIFI-3165] Keep last stats received timestamp in gateway client session map
Adding API call to gateway controller

Signed-off-by: Mike Hansen <mike.hansen@connectus.ai>
2021-07-19 14:13:19 -04:00
Mike Hansen
716ba7e043 Merge pull request #131 from Telecominfraproject/WIFI-3041
[Wifi 3041] A disconnected Alarm is raised when a disconnected AP is moved out of a Customer Inventory.
2021-07-16 16:28:16 -04:00
Thomas-Leung2021
3d2f4db32a [WIFI-3041] remove unnecessary dependencies 2021-07-16 12:22:23 -04:00
Thomas-Leung2021
c75d44ff03 [WIFI-3041] create a new EquipmentCustomerChangedEvent to handle status and alarm migration 2021-07-16 10:44:23 -04:00
Mike Hansen
f9dbe12c8c Merge pull request #130 from Telecominfraproject/WIFI-3056-event-stats
[WIFI-3056] Add API to get system event statistics
2021-07-16 07:44:06 -04:00
Norm Traxler
910a2cbe0c [WIFI-3056] Add API to get system event statistics 2021-07-15 22:15:01 -04:00
Thomas-Leung2021
799b243cc4 [WIFI-3041] move alarms to new customerId if customerId changed 2021-07-15 16:45:07 -04:00
Mike Hansen
8834c33d90 Merge pull request #129 from Telecominfraproject/WIFI-3042-alarms-by-alarmcode
[WIFI-3042] Add Alarm endpoint for get alarms by AlarmCode
2021-07-15 09:26:20 -04:00
Norm Traxler
e9c54a892b [WIFI-3042] Add Alarm endpoint for get alarms by AlarmCode 2021-07-14 20:18:22 -04:00
Mike Hansen
8353dd375f Control LED off via Equipment AP profile
Signed-off-by: Mike Hansen <mike.hansen@connectus.ai>
2021-07-14 18:45:33 -04:00
Mike Hansen
46de84b28b Add NULL check in EquipmentController
Signed-off-by: Mike Hansen <mike.hansen@connectus.ai>
2021-07-14 18:00:10 -04:00
Mike Hansen
9edca1fd9d CloudBackend:
Control LED off via Equipment AP profile

Signed-off-by: Mike Hansen <mike.hansen@connectus.ai>
2021-07-14 17:30:06 -04:00
Mike Hansen
5714c9bf32 CloudBackend:
Control LED off via Equipment AP profile and Show LED status in EQUIPMENT_ADMIN status

Signed-off-by: Mike Hansen <mike.hansen@connectus.ai>
2021-07-14 16:03:39 -04:00
Mike Hansen
2b2e34a064 Merge pull request #128 from Telecominfraproject/WIFI-2987
[WIFI-2987] add protocol status when switching customer
2021-07-13 14:09:02 -04:00
Thomas-Leung2021
d7a75faf4c check when status is null 2021-07-13 12:10:04 -04:00
Thomas-Leung2021
5fd977f064 [WIFI-2987] add protocol status when switching customer 2021-07-12 14:47:36 -04:00
Mike Hansen
bafec1fdd8 Merge pull request #127 from Telecominfraproject/hotfix/wifi-2970
[WIFI-2970] add equipment admin status when switching customer
2021-07-09 10:52:49 -04:00
Thomas-Leung2021
6b046e0a7a [WIFI-2970] remove unnecessary comments 2021-07-09 10:48:40 -04:00
Thomas-Leung2021
fb6604cdf5 add required dependencies in tests for new changes in EquipmentController 2021-07-08 17:48:20 -04:00
Thomas-Leung2021
2c1c60344e add equipment admin status when switching customer 2021-07-08 17:47:26 -04:00
Mike Hansen
9e959e258f Merge pull request #126 from Telecominfraproject/WIFI-2932-Client-ip-event
[WIFI-2932] Change IP event ipAddress from byte[] to InetAddress
2021-07-06 10:21:04 -04:00
Norm Traxler
2410233046 [WIFI-2932] Change IP event ipAddress from byte[] to InetAddress 2021-07-05 17:58:01 -04:00
norm-traxler
a7f91a29f8 Merge pull request #125 from Telecominfraproject/updateAPI
Update APIs to reflect new map in EquipmentChannelStatusData
2021-06-28 16:23:39 -04:00
Thomas-Leung2021
80cd0abd58 Update APIs to reflect new map in EquipmentChannelStatusData 2021-06-28 11:50:49 -04:00
Mike Hansen
4555ff339b Merge pull request #124 from Telecominfraproject/feature/netexp-2237
add tx_power status
2021-06-25 13:07:27 -04:00
Thomas-Leung2021
04a13877d1 add tx_power status 2021-06-25 12:39:30 -04:00
Mike Hansen
e148bab291 Merge pull request #123 from Telecominfraproject/WIFI-2699-modify-GET-/portal/profile/equipmentCounts-to-support-child-profiles-for-the-count
WIFI-2699  Modify GET /portal/profile/equipmentCounts to support child profiles for the count
2021-06-24 10:09:38 -04:00
Thomas Currie
9ad3cec4af rework top level profile tracking, so as to not include any profiles that were not in the Set argument 2021-06-23 11:30:06 -04:00
Thomas Currie
dc0b838f83 complete the test case cleanup 2021-06-23 11:11:54 -04:00
Thomas Currie
7cac7fff3f rework the algorithm at endpoint /portal/profile/equipmentCounts to include the correct child profile count for equipment 2021-06-23 10:58:02 -04:00
Mike Hansen
b48340b709 Merge pull request #122 from Telecominfraproject/disable_eq_alarms_sp
disable equipment-alarms-sp functionality, part of task to move the r…
2021-06-22 16:03:36 -04:00
Mike Hansen
44b3836758 disable equipment-alarms-sp functionality, part of task to move the raising and clearing of the threshold alarms into the gateway controller when the device information is received
Signed-off-by: Mike Hansen <mike.hansen@connectus.ai>
2021-06-22 15:43:09 -04:00
Mike Hansen
4f0b032549 Merge branch 'disable_eq_alarms_sp' of github.com:Telecominfraproject/wlan-cloud-services into disable_eq_alarms_sp 2021-06-22 15:40:54 -04:00
Mike Hansen
5ba0c4c242 Merge pull request #121 from Telecominfraproject/WIFI-2698-Update-visibility-of-fields-in-PortalUserDAO
WIFI-2698-Update-visibility-of-fields-in-PortalUserDAO
2021-06-22 10:42:01 -04:00
Mike Hansen
304e80332a disable equipment-alarms-sp functionality, part of task to move the raising and clearing of the threshold alarms into the gateway controller when the device information is received
Signed-off-by: Mike Hansen <mike.hansen@connectus.ai>
2021-06-22 10:19:41 -04:00
Thomas Currie
9fd3e73398 increase visibility of some fields in PortalUserDAO to allow classes to extend upon without duplication of values 2021-06-21 19:59:45 -04:00
Mike Hansen
b9db744aee Merge pull request #120 from Telecominfraproject/updateAPI
[WIFI-2646] update API to support WPA3-EAP-192
2021-06-17 13:43:53 -04:00
norm-traxler
1eee65d284 Merge pull request #119 from Telecominfraproject/WIFI-2670_2
[WIFI-2670] Add more counters to the ClientSessionCounts
2021-06-17 13:11:18 -04:00
Norm Traxler
75c943211a [WIFI-2670] Add more counters to the ClientSessionCounts 2021-06-17 12:14:38 -04:00
Thomas-Leung2021
d0a0ed59fe update API to support WPA3-EAP-192 2021-06-17 12:14:12 -04:00
norm-traxler
a200fcc12e Merge pull request #118 from Telecominfraproject/WIFI-2664
WIFI-2664 added private macs to return map
2021-06-17 12:12:39 -04:00
Kareem Dabbour
1f6996abb2 Merge branch 'master' of github.com:Telecominfraproject/wlan-cloud-services into WIFI-2664 2021-06-17 11:46:20 -04:00
Kareem Dabbour
1ebaa4a539 WIFI-2664 added private macs to return map 2021-06-17 11:44:02 -04:00
norm-traxler
f1e1bdffd7 Merge pull request #117 from Telecominfraproject/WIFI-2664
WIFI-2664 added private mac address filtering to /oui/list endpoint
2021-06-16 13:36:26 -04:00
Kareem Dabbour
37f5872552 Merge branch 'master' of github.com:Telecominfraproject/wlan-cloud-services into WIFI-2664 2021-06-16 12:59:23 -04:00
Kareem Dabbour
367b9ec428 WIFI-2664 adjusting unit tests to reflect added oui of ffffff 2021-06-16 12:55:57 -04:00
Kareem Dabbour
87ca619ad5 WIFI-2664 added private mac address filtering to /oui/list endpoint 2021-06-16 12:28:01 -04:00
norm-traxler
622f78f681 Merge pull request #116 from Telecominfraproject/WIFI-2664
WIFI-2664 Non-global mac addresses will now return an Uknown (private address) rather than null
2021-06-15 16:44:59 -04:00
Kareem Dabbour
faeb65d8d6 Merge branch 'master' of github.com:Telecominfraproject/wlan-cloud-services into WIFI-2664 2021-06-15 16:43:14 -04:00
Kareem Dabbour
34841a3a04 WIFI-2664 moving logic from in memory and DAO to controller 2021-06-15 16:37:30 -04:00
Kareem Dabbour
4fc8bc4018 WIFI-2664 renamed group to global address and did some refractoring 2021-06-15 15:26:51 -04:00
Kareem Dabbour
cce36019fe WIFI-2664 Non-global mac addresses will now return an Uknown (private address) rather than null 2021-06-15 14:46:14 -04:00
norm-traxler
4596280090 Merge pull request #115 from Telecominfraproject/WIFI-2670
[WIFI-2670] Client Session API support OUI attribute and count query
2021-06-15 14:44:44 -04:00
Norm Traxler
caaa8fb4e3 [WIFI-2670] Client Session API support OUI attribute and count query 2021-06-15 14:15:52 -04:00
Mike Hansen
b957c8bf72 Merge branch 'master' of github.com:Telecominfraproject/wlan-cloud-services 2021-06-14 11:55:58 -04:00
Mike Hansen
b797cc392f WIFI-2639: CloudBackend: upgrade CEGWBlinkRequest definition
Adding API call to portal, /portal/equipmentGateway/requestApBlinkLEDs

Adding RequestMapping to EquipmentPortalGatewayController

Signed-off-by: Mike Hansen <mike.hansen@connectus.ai>
2021-06-14 11:53:54 -04:00
norm-traxler
5fc9715649 Merge pull request #114 from Telecominfraproject/WIFI-2601-Add-check-for-valid-equipment-ID-when-creating-new-alarms-via-the-alarm-prov-controller
add check for validity of equipment ID when creating new alarms
2021-06-14 11:07:28 -04:00
Mike Hansen
0a66897e48 WIFI-2639: CloudBackend: upgrade CEGWBlinkRequest definition
Signed-off-by: Mike Hansen <mike.hansen@connectus.ai>
2021-06-11 15:58:30 -04:00
Mike Hansen
8d77fcb090 WIFI-2607: CloudBackend: add dynamicDiscovery attribute to RadiusProxyConfiguration
Signed-off-by: Mike Hansen <mike.hansen@connectus.ai>
2021-06-09 15:10:02 -04:00
Thomas Currie
256d9fbd16 throw better exception when equipment ID does not exist. 2021-06-09 09:20:30 -04:00
Thomas Currie
39e14da2e6 add check for validity of equipment ID when creating new alarms 2021-06-09 08:55:16 -04:00
105 changed files with 2225 additions and 2119 deletions

View File

@@ -121,6 +121,10 @@ public class AlarmDatastoreCassandra implements AlarmDatastore {
" from " + TABLE_NAME + " " + " from " + TABLE_NAME + " " +
" where customerId = ? "; " where customerId = ? ";
private static final String CQL_GET_ALL =
"select " + ALL_COLUMNS +
" from " + TABLE_NAME + " ";
private static final String CQL_GET_LASTMOD_BY_ID = private static final String CQL_GET_LASTMOD_BY_ID =
"select lastModifiedTimestamp " + "select lastModifiedTimestamp " +
" from "+TABLE_NAME+" " + " from "+TABLE_NAME+" " +
@@ -922,4 +926,51 @@ public class AlarmDatastoreCassandra implements AlarmDatastore {
return alarmCounts; return alarmCounts;
} }
@Override
public List<Alarm> get(Set<AlarmCode> alarmCodes, long createdAfterTimestamp) {
if (alarmCodes == null || alarmCodes.isEmpty()) {
throw new IllegalArgumentException("alarmCodes must be provided");
}
LOG.debug("Looking up Alarms for alarmCodes {} createdAfter {}", alarmCodes, createdAfterTimestamp);
String query = CQL_GET_ALL;
// add filters for the query
ArrayList<Object> queryArgs = new ArrayList<>();
// add alarmCodes filters
alarmCodes.forEach(ac -> queryArgs.add(ac.getId()));
StringBuilder strb = new StringBuilder(100);
strb.append("where alarmCode in (");
for (int i = 0; i < alarmCodes.size(); i++) {
strb.append("?");
if (i < alarmCodes.size() - 1) {
strb.append(",");
}
}
strb.append(") ");
if (createdAfterTimestamp > 0) {
strb.append(" and createdTimestamp > ?");
queryArgs.add(createdAfterTimestamp);
}
strb.append(" allow filtering");
query += strb.toString();
List<Alarm> ret = new ArrayList<>();
PreparedStatement preparedStmt_getListForCustomer = cqlSession.prepare(query);
ResultSet rs = cqlSession.execute(preparedStmt_getListForCustomer.bind(queryArgs.toArray()));
rs.forEach(row -> ret.add(alarmRowMapper.mapRow(row)));
LOG.debug("Found {} Alarms for alarmCodes {} createdAfter {}", ret.size(), alarmCodes, createdAfterTimestamp);
return ret;
}
} }

View File

@@ -356,4 +356,25 @@ public class AlarmDatastoreInMemory extends BaseInMemoryDatastore implements Ala
return alarmCounts; return alarmCounts;
} }
@Override
public List<Alarm> get(Set<AlarmCode> alarmCodeSet, long createdAfterTimestamp) {
if (alarmCodeSet == null || alarmCodeSet.isEmpty()) {
throw new IllegalArgumentException("alarmCodeSet must be provided");
}
List<Alarm> ret = new ArrayList<>();
idToAlarmMap.values().forEach(a -> {
if (alarmCodeSet.contains(a.getAlarmCode()) && a.getCreatedTimestamp() > createdAfterTimestamp) {
ret.add(a.clone());
}
});
LOG.debug("Found Alarms {}", ret);
return ret;
}
} }

View File

@@ -71,4 +71,14 @@ public interface AlarmDatastore {
*/ */
AlarmCounts getAlarmCounts(int customerId, Set<Long> equipmentIdSet, Set<AlarmCode> alarmCodeSet, Boolean acknowledged); AlarmCounts getAlarmCounts(int customerId, Set<Long> equipmentIdSet, Set<AlarmCode> alarmCodeSet, Boolean acknowledged);
/**
* Retrieves a list of Alarms for the given alarm codes.
*
* @param alarmCodeSet - null or empty means include all alarm codes
* @param createdAfterTimestamp
* @return list of matching Alarm objects.
* @throws IllegalArgumentException if supplied alarmCodeSet is null or empty
*/
List<Alarm> get(Set<AlarmCode> alarmCodeSet, long createdAfterTimestamp);
} }

View File

@@ -113,5 +113,16 @@ public interface AlarmServiceInterface {
* @return alarm counts for the given filters * @return alarm counts for the given filters
*/ */
AlarmCounts getAlarmCounts(int customerId, Set<Long> equipmentIdSet, Set<AlarmCode> alarmCodeSet, Boolean acknowledged); AlarmCounts getAlarmCounts(int customerId, Set<Long> equipmentIdSet, Set<AlarmCode> alarmCodeSet, Boolean acknowledged);
/**
* Retrieves a list of Alarms for the given alarm codes.
*
* @param alarmCodeSet - null or empty means include all alarm codes
* @param createdAfterTimestamp
* @return list of matching Alarm objects.
* @throws IllegalArgumentException if supplied alarmCodeSet is null or empty
*/
List<Alarm> get(Set<AlarmCode> alarmCodeSet, long createdAfterTimestamp);
} }

View File

@@ -47,6 +47,10 @@ public class AlarmServiceLocal implements AlarmServiceInterface {
return alarmController.getAllForEquipment(customerId, equipmentIdSet, alarmCodeSet, createdAfterTimestamp); return alarmController.getAllForEquipment(customerId, equipmentIdSet, alarmCodeSet, createdAfterTimestamp);
} }
@Override
public List<Alarm> get(Set<AlarmCode> alarmCodeSet, long createdAfterTimestamp) {
return alarmController.getAllForAlarmCode(alarmCodeSet, createdAfterTimestamp);
}
@Override @Override
public Alarm update(Alarm alarm) { public Alarm update(Alarm alarm) {

View File

@@ -52,6 +52,17 @@
<version>1.2.0-SNAPSHOT</version> <version>1.2.0-SNAPSHOT</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<artifactId>equipment-service-local</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependency>
<artifactId>equipment-datastore-inmemory</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@@ -241,14 +241,45 @@ public class AlarmServiceRemote extends BaseRemoteClient implements AlarmService
return ret; return ret;
} }
@Override
public List<Alarm> get(Set<AlarmCode> alarmCodeSet, long createdAfterTimestamp) {
LOG.debug("get({},{})", alarmCodeSet, createdAfterTimestamp);
if (alarmCodeSet == null || alarmCodeSet.isEmpty()) {
throw new IllegalArgumentException("alarmCodeSet must be provided");
}
String alarmCodeSetStr = alarmCodeSet.toString();
// remove [] around the string, otherwise will get:
// Failed to convert value of type 'java.lang.String' to required
// type 'java.util.Set'; nested exception is
// java.lang.NumberFormatException: For input string: "[690]"
alarmCodeSetStr = alarmCodeSetStr.substring(1, alarmCodeSetStr.length() - 1);
try {
ResponseEntity<List<Alarm>> responseEntity =
restTemplate.exchange(getBaseUrl() + "/forAlarmCode?alarmCode={alarmCodeSetStr}&createdAfterTimestamp={createdAfterTimestamp}",
HttpMethod.GET, null, Alarm_LIST_CLASS_TOKEN, alarmCodeSetStr, createdAfterTimestamp);
List<Alarm> result = responseEntity.getBody();
if (null == result) {
result = Collections.emptyList();
}
LOG.debug("get({},{}) return {} entries", alarmCodeSet, createdAfterTimestamp, result.size());
return result;
} catch (Exception exp) {
LOG.error("getAllInSet({},{}) exception ", alarmCodeSet, createdAfterTimestamp, exp);
throw exp;
}
}
public String getBaseUrl() { public String getBaseUrl() {
if(baseUrl==null) { if(baseUrl==null) {
baseUrl = environment.getProperty("tip.wlan.alarmServiceBaseUrl").trim()+"/api/alarm"; baseUrl = environment.getProperty("tip.wlan.alarmServiceBaseUrl").trim()+"/api/alarm";
} }
return baseUrl; return baseUrl;
} }
} }

View File

@@ -19,6 +19,7 @@ import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Import;
import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.context.junit4.SpringRunner;
@@ -26,12 +27,17 @@ import com.telecominfraproject.wlan.alarm.models.Alarm;
import com.telecominfraproject.wlan.alarm.models.AlarmCode; import com.telecominfraproject.wlan.alarm.models.AlarmCode;
import com.telecominfraproject.wlan.alarm.models.AlarmCounts; import com.telecominfraproject.wlan.alarm.models.AlarmCounts;
import com.telecominfraproject.wlan.alarm.models.AlarmDetails; import com.telecominfraproject.wlan.alarm.models.AlarmDetails;
import com.telecominfraproject.wlan.cloudeventdispatcher.CloudEventDispatcherEmpty;
import com.telecominfraproject.wlan.core.model.equipment.EquipmentType;
import com.telecominfraproject.wlan.core.model.pagination.ColumnAndSort; import com.telecominfraproject.wlan.core.model.pagination.ColumnAndSort;
import com.telecominfraproject.wlan.core.model.pagination.PaginationContext; import com.telecominfraproject.wlan.core.model.pagination.PaginationContext;
import com.telecominfraproject.wlan.core.model.pagination.PaginationResponse; import com.telecominfraproject.wlan.core.model.pagination.PaginationResponse;
import com.telecominfraproject.wlan.core.model.pagination.SortOrder; import com.telecominfraproject.wlan.core.model.pagination.SortOrder;
import com.telecominfraproject.wlan.datastore.exceptions.DsConcurrentModificationException; import com.telecominfraproject.wlan.datastore.exceptions.DsConcurrentModificationException;
import com.telecominfraproject.wlan.datastore.exceptions.DsEntityNotFoundException; import com.telecominfraproject.wlan.datastore.exceptions.DsEntityNotFoundException;
import com.telecominfraproject.wlan.equipment.EquipmentServiceLocal;
import com.telecominfraproject.wlan.equipment.datastore.inmemory.EquipmentDatastoreInMemory;
import com.telecominfraproject.wlan.equipment.models.Equipment;
import com.telecominfraproject.wlan.remote.tests.BaseRemoteTest; import com.telecominfraproject.wlan.remote.tests.BaseRemoteTest;
import com.telecominfraproject.wlan.status.models.StatusCode; import com.telecominfraproject.wlan.status.models.StatusCode;
@@ -44,10 +50,16 @@ import com.telecominfraproject.wlan.status.models.StatusCode;
"integration_test", "integration_test",
"no_ssl","http_digest_auth","rest-template-single-user-per-service-digest-auth", "no_ssl","http_digest_auth","rest-template-single-user-per-service-digest-auth",
}) //NOTE: these profiles will be ADDED to the list of active profiles }) //NOTE: these profiles will be ADDED to the list of active profiles
@Import(value = {
EquipmentServiceLocal.class,
EquipmentDatastoreInMemory.class,
CloudEventDispatcherEmpty.class
})
public class AlarmServiceRemoteTest extends BaseRemoteTest { public class AlarmServiceRemoteTest extends BaseRemoteTest {
@Autowired AlarmServiceRemote remoteInterface; @Autowired AlarmServiceRemote remoteInterface;
@Autowired EquipmentServiceLocal equipmentServicelocal;
@Before public void urlSetup(){ @Before public void urlSetup(){
configureBaseUrl("tip.wlan.alarmServiceBaseUrl"); configureBaseUrl("tip.wlan.alarmServiceBaseUrl");
@@ -505,8 +517,10 @@ public class AlarmServiceRemoteTest extends BaseRemoteTest {
public void testAlarmCountsRetrieval() { public void testAlarmCountsRetrieval() {
//create some Alarms //create some Alarms
Alarm mdl; Alarm mdl;
int customerId_1 = getNextCustomerId(); final int customerId_1 = getNextCustomerId();
int customerId_2 = getNextCustomerId(); final int customerId_2 = getNextCustomerId();
final long equipmentId_1 = createEquipmentObject(customerId_1).getId();
int apNameIdx = 0; int apNameIdx = 0;
Set<Long> equipmentIds = new HashSet<>(); Set<Long> equipmentIds = new HashSet<>();
@@ -514,8 +528,8 @@ public class AlarmServiceRemoteTest extends BaseRemoteTest {
Set<Long> equipmentIds_AccessPointIsUnreachable = new HashSet<>(); Set<Long> equipmentIds_AccessPointIsUnreachable = new HashSet<>();
for(int i = 0; i< 50; i++){ for(int i = 0; i< 50; i++){
mdl = createAlarmObject(); mdl = createAlarmObject(customerId_1, createEquipmentObject(customerId_1).getId());
mdl.setCustomerId(customerId_1); mdl.setEquipmentId(createEquipmentObject(customerId_1).getId());
mdl.setScopeId("qr_"+apNameIdx); mdl.setScopeId("qr_"+apNameIdx);
if((i%2) == 0) { if((i%2) == 0) {
mdl.setAlarmCode(AlarmCode.CPUUtilization); mdl.setAlarmCode(AlarmCode.CPUUtilization);
@@ -530,16 +544,14 @@ public class AlarmServiceRemoteTest extends BaseRemoteTest {
remoteInterface.create(mdl); remoteInterface.create(mdl);
} }
mdl = createAlarmObject(); mdl = createAlarmObject(customerId_1, equipmentId_1);
mdl.setCustomerId(customerId_1); mdl.setCustomerId(customerId_1);
mdl.setEquipmentId(0);
mdl.setAlarmCode(AlarmCode.GenericError); mdl.setAlarmCode(AlarmCode.GenericError);
remoteInterface.create(mdl); remoteInterface.create(mdl);
for(int i = 0; i< 50; i++){ for(int i = 0; i< 50; i++){
mdl = createAlarmObject(); mdl = createAlarmObject(customerId_2, createEquipmentObject(customerId_2).getId());
mdl.setCustomerId(customerId_2);
mdl.setScopeId("qr_"+apNameIdx); mdl.setScopeId("qr_"+apNameIdx);
mdl.setAcknowledged(false); mdl.setAcknowledged(false);
mdl.setAlarmCode(AlarmCode.GenericError); mdl.setAlarmCode(AlarmCode.GenericError);
@@ -651,18 +663,33 @@ public class AlarmServiceRemoteTest extends BaseRemoteTest {
} }
private Alarm createAlarmObject() { private Alarm createAlarmObject() {
Alarm result = new Alarm(); int customerId = getNextCustomerId();
result.setCustomerId(getNextCustomerId()); return createAlarmObject(customerId, createEquipmentObject(customerId).getId());
result.setEquipmentId(getNextEquipmentId()); }
private Alarm createAlarmObject(int customerId, long equipmentId) {
Alarm result = new Alarm();
result.setCustomerId(customerId);
result.setAlarmCode(AlarmCode.AccessPointIsUnreachable); result.setAlarmCode(AlarmCode.AccessPointIsUnreachable);
result.setCreatedTimestamp(System.currentTimeMillis()); result.setCreatedTimestamp(System.currentTimeMillis());
result.setEquipmentId(equipmentId);
result.setScopeId("test-scope-" + result.getEquipmentId()); result.setScopeId("test-scope-" + result.getEquipmentId());
AlarmDetails details = new AlarmDetails(); AlarmDetails details = new AlarmDetails();
details.setMessage("test-details-" + result.getEquipmentId()); details.setMessage("test-details-" + result.getEquipmentId());
result.setDetails(details ); result.setDetails(details );
return result; return result;
} }
private Equipment createEquipmentObject(int customerId)
{
Equipment equipment = new Equipment();
equipment.setName("testName");
equipment.setInventoryId("test-inv");
equipment.setEquipmentType(EquipmentType.AP);
equipment.setCustomerId(customerId);
return equipmentServicelocal.create(equipment);
}
} }

View File

@@ -1,53 +1,70 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <project xmlns="http://maven.apache.org/POM/4.0.0"
<modelVersion>4.0.0</modelVersion> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<parent> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<groupId>com.telecominfraproject.wlan</groupId> <modelVersion>4.0.0</modelVersion>
<artifactId>tip-wlan-cloud-root-pom</artifactId> <parent>
<version>1.2.0-SNAPSHOT</version> <groupId>com.telecominfraproject.wlan</groupId>
<relativePath>../../wlan-cloud-root</relativePath> <artifactId>tip-wlan-cloud-root-pom</artifactId>
</parent> <version>1.2.0-SNAPSHOT</version>
<relativePath>../../wlan-cloud-root</relativePath>
</parent>
<artifactId>alarm-service</artifactId> <artifactId>alarm-service</artifactId>
<name>alarm-service</name> <name>alarm-service</name>
<description>Server side implementation of the service.</description> <description>Server side implementation of the service.</description>
<dependencies>
<dependency>
<artifactId>base-container</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
</dependency>
<dependency>
<artifactId>cloud-event-dispatcher-interface</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
</dependency>
<dependency>
<artifactId>alarm-models</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
</dependency>
<dependency>
<artifactId>alarm-datastore-interface</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
</dependency>
<dependency>
<artifactId>alarm-datastore-inmemory</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependencies>
<dependency>
<artifactId>base-container</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
</dependency>
<dependency> <dependency>
<artifactId>cloud-event-dispatcher-empty</artifactId> <artifactId>cloud-event-dispatcher-interface</artifactId>
<groupId>com.telecominfraproject.wlan</groupId> <groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version> <version>1.2.0-SNAPSHOT</version>
<scope>test</scope> </dependency>
</dependency>
</dependencies> <dependency>
<artifactId>alarm-models</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
</dependency>
<dependency>
<artifactId>alarm-datastore-interface</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
</dependency>
<dependency>
<artifactId>equipment-service-interface</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
</dependency>
<dependency>
<artifactId>alarm-datastore-inmemory</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependency>
<artifactId>equipment-service-local</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependency>
<artifactId>equipment-datastore-inmemory</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependency>
<artifactId>cloud-event-dispatcher-empty</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
</dependencies>
</project> </project>

View File

@@ -20,6 +20,7 @@ import com.telecominfraproject.wlan.core.model.pagination.ColumnAndSort;
import com.telecominfraproject.wlan.core.model.pagination.PaginationContext; import com.telecominfraproject.wlan.core.model.pagination.PaginationContext;
import com.telecominfraproject.wlan.core.model.pagination.PaginationResponse; import com.telecominfraproject.wlan.core.model.pagination.PaginationResponse;
import com.telecominfraproject.wlan.datastore.exceptions.DsDataValidationException; import com.telecominfraproject.wlan.datastore.exceptions.DsDataValidationException;
import com.telecominfraproject.wlan.equipment.EquipmentServiceInterface;
import com.telecominfraproject.wlan.systemevent.models.SystemEvent; import com.telecominfraproject.wlan.systemevent.models.SystemEvent;
import com.telecominfraproject.wlan.alarm.datastore.AlarmDatastore; import com.telecominfraproject.wlan.alarm.datastore.AlarmDatastore;
@@ -48,6 +49,7 @@ public class AlarmController {
@Autowired private AlarmDatastore alarmDatastore; @Autowired private AlarmDatastore alarmDatastore;
@Autowired private CloudEventDispatcherInterface cloudEventDispatcher; @Autowired private CloudEventDispatcherInterface cloudEventDispatcher;
@Autowired private EquipmentServiceInterface equipmentServiceInterface;
/** /**
@@ -66,6 +68,14 @@ public class AlarmController {
LOG.error("Failed to create Alarm, request contains unsupported value: {}", alarm); LOG.error("Failed to create Alarm, request contains unsupported value: {}", alarm);
throw new DsDataValidationException("Alarm contains unsupported value"); throw new DsDataValidationException("Alarm contains unsupported value");
} }
if (alarm.getEquipmentId() != 0)
{
if (equipmentServiceInterface.getOrNull(alarm.getEquipmentId()) == null)
{
throw new DsDataValidationException(String.format("Unable to create alarm for non-existant equipment ID: %d", alarm.getEquipmentId()));
}
}
long ts = alarm.getCreatedTimestamp(); long ts = alarm.getCreatedTimestamp();
if (ts == 0) { if (ts == 0) {
@@ -119,6 +129,24 @@ public class AlarmController {
throw exp; throw exp;
} }
} }
@RequestMapping(value = "/forAlarmCode", method = RequestMethod.GET)
public ListOfAlarms getAllForAlarmCode(
@RequestParam Set<AlarmCode> alarmCode,
@RequestParam long createdAfterTimestamp) {
LOG.debug("getAllForAlarmCode({}, {})", alarmCode, createdAfterTimestamp);
try {
List<Alarm> result = alarmDatastore.get(alarmCode, createdAfterTimestamp);
LOG.debug("getAllForAlarmCode({},{}) return {} entries", alarmCode, createdAfterTimestamp, result.size());
ListOfAlarms ret = new ListOfAlarms();
ret.addAll(result);
return ret;
} catch (Exception exp) {
LOG.error("getAllForAlarmCode({},{}) exception ", alarmCode, createdAfterTimestamp, exp);
throw exp;
}
}
@RequestMapping(value = "/forCustomer", method = RequestMethod.GET) @RequestMapping(value = "/forCustomer", method = RequestMethod.GET)
public PaginationResponse<Alarm> getForCustomer(@RequestParam int customerId, public PaginationResponse<Alarm> getForCustomer(@RequestParam int customerId,

View File

@@ -17,7 +17,11 @@ import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.context.junit4.SpringRunner;
import com.telecominfraproject.wlan.cloudeventdispatcher.CloudEventDispatcherEmpty; import com.telecominfraproject.wlan.cloudeventdispatcher.CloudEventDispatcherEmpty;
import com.telecominfraproject.wlan.core.model.equipment.EquipmentType;
import com.telecominfraproject.wlan.equipment.EquipmentServiceLocal;
import com.telecominfraproject.wlan.equipment.controller.EquipmentController;
import com.telecominfraproject.wlan.equipment.datastore.inmemory.EquipmentDatastoreInMemory;
import com.telecominfraproject.wlan.equipment.models.Equipment;
import com.telecominfraproject.wlan.alarm.datastore.inmemory.AlarmDatastoreInMemory; import com.telecominfraproject.wlan.alarm.datastore.inmemory.AlarmDatastoreInMemory;
import com.telecominfraproject.wlan.alarm.models.Alarm; import com.telecominfraproject.wlan.alarm.models.Alarm;
import com.telecominfraproject.wlan.alarm.models.AlarmCode; import com.telecominfraproject.wlan.alarm.models.AlarmCode;
@@ -39,10 +43,14 @@ import com.telecominfraproject.wlan.alarm.models.AlarmDetails;
CloudEventDispatcherEmpty.class, CloudEventDispatcherEmpty.class,
AlarmDatastoreInMemory.class, AlarmDatastoreInMemory.class,
AlarmControllerTest.Config.class, AlarmControllerTest.Config.class,
EquipmentServiceLocal.class,
EquipmentController.class,
EquipmentDatastoreInMemory.class
}) })
public class AlarmControllerTest { public class AlarmControllerTest {
@Autowired private AlarmController alarmController; @Autowired private AlarmController alarmController;
@Autowired EquipmentServiceLocal equipmentServicelocal;
@Configuration @Configuration
@@ -59,8 +67,9 @@ public class AlarmControllerTest {
//Create new Alarm - success //Create new Alarm - success
Alarm alarm = new Alarm(); Alarm alarm = new Alarm();
alarm.setCustomerId((int) testSequence.getAndIncrement()); int customerId = (int) testSequence.getAndIncrement();
alarm.setEquipmentId(testSequence.getAndIncrement()); alarm.setCustomerId(customerId);
alarm.setEquipmentId(createEquipmentObject(customerId).getId());
alarm.setAlarmCode(AlarmCode.AccessPointIsUnreachable); alarm.setAlarmCode(AlarmCode.AccessPointIsUnreachable);
alarm.setCreatedTimestamp(System.currentTimeMillis()); alarm.setCreatedTimestamp(System.currentTimeMillis());
@@ -91,5 +100,14 @@ public class AlarmControllerTest {
assertEquals(expected.getDetails(), actual.getDetails()); assertEquals(expected.getDetails(), actual.getDetails());
//TODO: add more fields to check here //TODO: add more fields to check here
} }
private Equipment createEquipmentObject(int customerId)
{
Equipment equipment = new Equipment();
equipment.setName("testName");
equipment.setInventoryId("test-inv");
equipment.setEquipmentType(EquipmentType.AP);
equipment.setCustomerId(customerId);
return equipmentServicelocal.create(equipment);
}
} }

View File

@@ -349,12 +349,6 @@
<version>1.2.0-SNAPSHOT</version> <version>1.2.0-SNAPSHOT</version>
</dependency> </dependency>
<dependency>
<artifactId>equipment-alarms-sp</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
</dependency>
<dependency> <dependency>
<artifactId>adoption-metrics-sp</artifactId> <artifactId>adoption-metrics-sp</artifactId>
<groupId>com.telecominfraproject.wlan</groupId> <groupId>com.telecominfraproject.wlan</groupId>

View File

@@ -811,10 +811,10 @@ public class AllInOneWithGatewayStartListener implements ApplicationRunner {
sessionDetails.setRadioType(radioType); sessionDetails.setRadioType(radioType);
sessionDetails.setSecurityType(SecurityType.PSK); sessionDetails.setSecurityType(SecurityType.PSK);
sessionDetails.setSsid(ssidConfig.getSsid()); sessionDetails.setSsid(ssidConfig.getSsid());
sessionDetails.setSessionId(System.currentTimeMillis()); sessionDetails.setSessionId(Long.toUnsignedString(System.currentTimeMillis()));
sessionDetails.setAssocTimestamp(System.currentTimeMillis() - getRandomLong(10000, 1000000)); sessionDetails.setAssocTimestamp(System.currentTimeMillis() - getRandomLong(10000, 1000000));
ClientDhcpDetails dhcpDetails = new ClientDhcpDetails(System.currentTimeMillis()); ClientDhcpDetails dhcpDetails = new ClientDhcpDetails(Long.toUnsignedString(System.currentTimeMillis()));
dhcpDetails.setLeaseStartTimestamp(System.currentTimeMillis() - getRandomLong(0, TimeUnit.HOURS.toMillis(4))); dhcpDetails.setLeaseStartTimestamp(System.currentTimeMillis() - getRandomLong(0, TimeUnit.HOURS.toMillis(4)));
dhcpDetails.setLeaseTimeInSeconds((int)TimeUnit.HOURS.toSeconds(4)); dhcpDetails.setLeaseTimeInSeconds((int)TimeUnit.HOURS.toSeconds(4));
try { try {

View File

@@ -250,12 +250,6 @@
<version>1.2.0-SNAPSHOT</version> <version>1.2.0-SNAPSHOT</version>
</dependency> </dependency>
<dependency>
<artifactId>equipment-alarms-sp</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
</dependency>
<dependency> <dependency>
<artifactId>adoption-metrics-sp</artifactId> <artifactId>adoption-metrics-sp</artifactId>
<groupId>com.telecominfraproject.wlan</groupId> <groupId>com.telecominfraproject.wlan</groupId>

View File

@@ -336,12 +336,6 @@
<version>1.2.0-SNAPSHOT</version> <version>1.2.0-SNAPSHOT</version>
</dependency> </dependency>
<dependency>
<artifactId>equipment-alarms-sp</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
</dependency>
<dependency> <dependency>
<artifactId>adoption-metrics-sp</artifactId> <artifactId>adoption-metrics-sp</artifactId>
<groupId>com.telecominfraproject.wlan</groupId> <groupId>com.telecominfraproject.wlan</groupId>

View File

@@ -1,14 +1,11 @@
package com.telecominfraproject.wlan.startuptasks; package com.telecominfraproject.wlan.startuptasks;
import java.io.BufferedWriter;
import java.io.IOException; import java.io.IOException;
import java.net.Inet4Address; import java.net.Inet4Address;
import java.net.Inet6Address; import java.net.Inet6Address;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.nio.file.StandardOpenOption; import java.nio.file.StandardOpenOption;
@@ -1241,7 +1238,7 @@ public class AllInOneStartListener implements ApplicationRunner {
clientMetrics.setNumRxBytes(getRandomLong(3000000, 7000000)); clientMetrics.setNumRxBytes(getRandomLong(3000000, 7000000));
clientMetrics.setNumTxBytes(getRandomLong(3000000, 7000000)); clientMetrics.setNumTxBytes(getRandomLong(3000000, 7000000));
clientMetrics.setSessionId(getRandomLong(3000000, 7000000)); clientMetrics.setSessionId(Long.toUnsignedString(getRandomLong(3000000, 7000000)));
clientMetrics.setTxRetries(getRandomInt(30, 70)); clientMetrics.setTxRetries(getRandomInt(30, 70));
clientMetrics.setRxDuplicatePackets(getRandomInt(30, 70)); clientMetrics.setRxDuplicatePackets(getRandomInt(30, 70));
@@ -1268,7 +1265,7 @@ public class AllInOneStartListener implements ApplicationRunner {
clientMetrics.setNumRxBytes(getRandomLong(3000000, 7000000)); clientMetrics.setNumRxBytes(getRandomLong(3000000, 7000000));
clientMetrics.setNumTxBytes(getRandomLong(3000000, 7000000)); clientMetrics.setNumTxBytes(getRandomLong(3000000, 7000000));
clientMetrics.setSessionId(getRandomLong(3000000, 7000000)); clientMetrics.setSessionId(Long.toUnsignedString(getRandomLong(3000000, 7000000)));
clientMetrics.setTxRetries(getRandomInt(30, 70)); clientMetrics.setTxRetries(getRandomInt(30, 70));
clientMetrics.setRxDuplicatePackets(getRandomInt(30, 70)); clientMetrics.setRxDuplicatePackets(getRandomInt(30, 70));
@@ -1295,7 +1292,7 @@ public class AllInOneStartListener implements ApplicationRunner {
clientMetrics.setNumRxBytes(getRandomLong(3000000, 7000000)); clientMetrics.setNumRxBytes(getRandomLong(3000000, 7000000));
clientMetrics.setNumTxBytes(getRandomLong(3000000, 7000000)); clientMetrics.setNumTxBytes(getRandomLong(3000000, 7000000));
clientMetrics.setSessionId(getRandomLong(3000000, 7000000)); clientMetrics.setSessionId(Long.toUnsignedString(getRandomLong(3000000, 7000000)));
clientMetrics.setTxRetries(getRandomInt(30, 70)); clientMetrics.setTxRetries(getRandomInt(30, 70));
clientMetrics.setRxDuplicatePackets(getRandomInt(30, 70)); clientMetrics.setRxDuplicatePackets(getRandomInt(30, 70));
@@ -1364,10 +1361,10 @@ public class AllInOneStartListener implements ApplicationRunner {
sessionDetails.setRadioType(radioType); sessionDetails.setRadioType(radioType);
sessionDetails.setSecurityType(SecurityType.PSK); sessionDetails.setSecurityType(SecurityType.PSK);
sessionDetails.setSsid(ssidConfig.getSsid()); sessionDetails.setSsid(ssidConfig.getSsid());
sessionDetails.setSessionId(System.currentTimeMillis()); sessionDetails.setSessionId(Long.toUnsignedString(System.currentTimeMillis()));
sessionDetails.setAssocTimestamp(System.currentTimeMillis() - getRandomLong(10000, 1000000)); sessionDetails.setAssocTimestamp(System.currentTimeMillis() - getRandomLong(10000, 1000000));
ClientDhcpDetails dhcpDetails = new ClientDhcpDetails(System.currentTimeMillis()); ClientDhcpDetails dhcpDetails = new ClientDhcpDetails(Long.toUnsignedString(System.currentTimeMillis()));
dhcpDetails dhcpDetails
.setLeaseStartTimestamp(System.currentTimeMillis() - getRandomLong(0, TimeUnit.HOURS.toMillis(4))); .setLeaseStartTimestamp(System.currentTimeMillis() - getRandomLong(0, TimeUnit.HOURS.toMillis(4)));
dhcpDetails.setLeaseTimeInSeconds((int) TimeUnit.HOURS.toSeconds(4)); dhcpDetails.setLeaseTimeInSeconds((int) TimeUnit.HOURS.toSeconds(4));

View File

@@ -12,6 +12,7 @@ import com.telecominfraproject.wlan.core.model.pagination.PaginationContext;
import com.telecominfraproject.wlan.core.model.pagination.PaginationResponse; import com.telecominfraproject.wlan.core.model.pagination.PaginationResponse;
import com.telecominfraproject.wlan.client.datastore.ClientDatastore; import com.telecominfraproject.wlan.client.datastore.ClientDatastore;
import com.telecominfraproject.wlan.client.info.models.ClientSessionCounts;
import com.telecominfraproject.wlan.client.models.Client; import com.telecominfraproject.wlan.client.models.Client;
import com.telecominfraproject.wlan.client.session.models.ClientSession; import com.telecominfraproject.wlan.client.session.models.ClientSession;
@@ -108,6 +109,13 @@ public class ClientDatastoreCassandra implements ClientDatastore {
return clientSessionDAO.getSessionsForCustomer(customerId, equipmentIds, locationIds, macSubstring, sortBy, context); return clientSessionDAO.getSessionsForCustomer(customerId, equipmentIds, locationIds, macSubstring, sortBy, context);
} }
@Override
public ClientSessionCounts getSessionCounts(int customerId) {
// Not yet supported.
ClientSessionCounts counts = new ClientSessionCounts();
return counts;
}
} }

View File

@@ -3,6 +3,7 @@ package com.telecominfraproject.wlan.client.datastore.inmemory;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -15,6 +16,7 @@ import org.springframework.context.annotation.Configuration;
import com.telecominfraproject.wlan.client.datastore.ClientDatastore; import com.telecominfraproject.wlan.client.datastore.ClientDatastore;
import com.telecominfraproject.wlan.client.info.models.ClientInfoDetails; import com.telecominfraproject.wlan.client.info.models.ClientInfoDetails;
import com.telecominfraproject.wlan.client.info.models.ClientSessionCounts;
import com.telecominfraproject.wlan.client.models.Client; import com.telecominfraproject.wlan.client.models.Client;
import com.telecominfraproject.wlan.client.session.models.ClientSession; import com.telecominfraproject.wlan.client.session.models.ClientSession;
import com.telecominfraproject.wlan.core.model.equipment.MacAddress; import com.telecominfraproject.wlan.core.model.equipment.MacAddress;
@@ -512,4 +514,56 @@ public class ClientDatastoreInMemory extends BaseInMemoryDatastore implements Cl
return ret; return ret;
} }
@Override
public ClientSessionCounts getSessionCounts(int customerId) {
ClientSessionCounts counts = new ClientSessionCounts();
counts.setCustomerId(customerId);
long totalCount = 0;
Map<String, Long> perEquipmentMap = new HashMap<>();
Map<String, Long> perOuiMap = new HashMap<>();
Map<String, Long> perRadioMap = new HashMap<>();
for (ClientSession session : idToClientSessionMap.values()) {
if (session.getCustomerId() == customerId) {
totalCount++;
String equipmentIdString = Long.toString(session.getEquipmentId());
Long cnt = perEquipmentMap.get(equipmentIdString);
if (cnt == null) {
cnt = 0L;
} else {
cnt++;
}
perEquipmentMap.put(equipmentIdString, cnt);
if (session.getOui() != null) {
cnt = perOuiMap.get(session.getOui());
if (cnt == null) {
cnt = 0L;
} else {
cnt++;
}
perOuiMap.put(session.getOui(), cnt);
}
if (session.getDetails() != null && session.getDetails().getRadioType() != null) {
String radioTypeString = session.getDetails().getRadioType().toString();
cnt = perRadioMap.get(radioTypeString);
if (cnt == null) {
cnt = 0L;
} else {
cnt++;
}
perRadioMap.put(radioTypeString, cnt);
}
}
}
counts.setTotalCount(totalCount);
counts.setEquipmentCounts(perEquipmentMap);
counts.setOuiCounts(perOuiMap);
counts.setRadioCounts(perRadioMap);
return counts;
}
} }

View File

@@ -4,6 +4,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import com.telecominfraproject.wlan.client.info.models.ClientSessionCounts;
import com.telecominfraproject.wlan.client.models.Client; import com.telecominfraproject.wlan.client.models.Client;
import com.telecominfraproject.wlan.client.session.models.ClientSession; import com.telecominfraproject.wlan.client.session.models.ClientSession;
import com.telecominfraproject.wlan.core.model.equipment.MacAddress; import com.telecominfraproject.wlan.core.model.equipment.MacAddress;
@@ -105,5 +106,12 @@ public interface ClientDatastore {
*/ */
PaginationResponse<ClientSession> getSessionsForCustomer(int customerId, Set<Long> equipmentIds, Set<Long> locationIds, String macSubstring, List<ColumnAndSort> sortBy, PaginationContext<ClientSession> context); PaginationResponse<ClientSession> getSessionsForCustomer(int customerId, Set<Long> equipmentIds, Set<Long> locationIds, String macSubstring, List<ColumnAndSort> sortBy, PaginationContext<ClientSession> context);
/**
* Get Client Session counts for the given customerId.
*
* @param customerId
* @return
*/
ClientSessionCounts getSessionCounts(int customerId);
} }

View File

@@ -0,0 +1,90 @@
package com.telecominfraproject.wlan.client.info.models;
import java.util.HashMap;
import java.util.Map;
import com.telecominfraproject.wlan.core.model.json.BaseJsonModel;
/**
* Total and per-oui/equipment/radio counts of the Client Sessions
*/
public class ClientSessionCounts extends BaseJsonModel {
private static final long serialVersionUID = 7697349699510565184L;
private int customerId;
/**
* Total count of all client sessions for the customer Id.
*/
private long totalCount;
/**
* Counts of client sessions per equipment Id.
*/
private Map<String, Long> equipmentCounts = new HashMap<>();
/**
* Counts of client sessions per OUI.
*/
private Map<String, Long> ouiCounts = new HashMap<>();
/**
* Counts of client sessions per Radio Type.
*/
private Map<String, Long> radioCounts = new HashMap<>();
public int getCustomerId() {
return customerId;
}
public void setCustomerId(int customerId) {
this.customerId = customerId;
}
public long getTotalCount() {
return totalCount;
}
public void setTotalCount(long totalCount) {
this.totalCount = totalCount;
}
public Map<String, Long> getEquipmentCounts() {
return equipmentCounts;
}
public void setEquipmentCounts(Map<String, Long> equipmentCounts) {
this.equipmentCounts = equipmentCounts;
}
public Map<String, Long> getOuiCounts() {
return ouiCounts;
}
public void setOuiCounts(Map<String, Long> ouiCounts) {
this.ouiCounts = ouiCounts;
}
public Map<String, Long> getRadioCounts() {
return radioCounts;
}
public void setRadioCounts(Map<String, Long> radioCounts) {
this.radioCounts = radioCounts;
}
@Override
public ClientSessionCounts clone() {
ClientSessionCounts ret = (ClientSessionCounts) super.clone();
if (equipmentCounts != null) {
ret.equipmentCounts = new HashMap<>(equipmentCounts);
}
if (ouiCounts != null) {
ret.ouiCounts = new HashMap<>(ouiCounts);
}
if (radioCounts != null) {
ret.radioCounts = new HashMap<>(radioCounts);
}
return ret;
}
}

View File

@@ -12,7 +12,7 @@ import com.telecominfraproject.wlan.systemevent.equipment.realtime.RealTimeEvent
public class ClientAssocEvent extends RealTimeEvent implements HasClientMac { public class ClientAssocEvent extends RealTimeEvent implements HasClientMac {
private static final long serialVersionUID = 7015822981315570338L; private static final long serialVersionUID = 7015822981315570338L;
private long sessionId; private String sessionId;
private String ssid; private String ssid;
private MacAddress clientMacAddress; private MacAddress clientMacAddress;
private RadioType radioType; private RadioType radioType;
@@ -29,7 +29,7 @@ public class ClientAssocEvent extends RealTimeEvent implements HasClientMac {
} }
public ClientAssocEvent(int customerId, long locationId, long equipmentId, long timestamp, long sessionId, String ssid, public ClientAssocEvent(int customerId, long locationId, long equipmentId, long timestamp, String sessionId, String ssid,
MacAddress clientMacAddress, RadioType radioType, boolean isReassociation, WlanStatusCode status, MacAddress clientMacAddress, RadioType radioType, boolean isReassociation, WlanStatusCode status,
Integer internalSC, Integer rssi) { Integer internalSC, Integer rssi) {
super(RealTimeEventType.STA_Client_Assoc, customerId, locationId, equipmentId, timestamp); super(RealTimeEventType.STA_Client_Assoc, customerId, locationId, equipmentId, timestamp);
@@ -50,7 +50,7 @@ public class ClientAssocEvent extends RealTimeEvent implements HasClientMac {
/** /**
* @return the sessionId * @return the sessionId
*/ */
public long getSessionId() { public String getSessionId() {
return sessionId; return sessionId;
} }
@@ -58,7 +58,7 @@ public class ClientAssocEvent extends RealTimeEvent implements HasClientMac {
* @param sessionId * @param sessionId
* the sessionId to set * the sessionId to set
*/ */
public void setSessionId(long sessionId) { public void setSessionId(String sessionId) {
this.sessionId = sessionId; this.sessionId = sessionId;
} }

View File

@@ -13,7 +13,7 @@ public class ClientAuthEvent extends RealTimeEvent implements HasClientMac {
private static final long serialVersionUID = 1221389696911864515L; private static final long serialVersionUID = 1221389696911864515L;
private long sessionId; private String sessionId;
private String ssid; private String ssid;
private MacAddress clientMacAddress; private MacAddress clientMacAddress;
private WlanStatusCode authStatus; private WlanStatusCode authStatus;
@@ -32,11 +32,11 @@ public class ClientAuthEvent extends RealTimeEvent implements HasClientMac {
super(eventType, timestamp); super(eventType, timestamp);
} }
public long getSessionId() { public String getSessionId() {
return sessionId; return sessionId;
} }
public void setSessionId(long sessionId) { public void setSessionId(String sessionId) {
this.sessionId = sessionId; this.sessionId = sessionId;
} }

View File

@@ -14,7 +14,7 @@ public class ClientConnectSuccessEvent extends RealTimeEvent implements HasClien
private static final long serialVersionUID = -6082134146801575193L; private static final long serialVersionUID = -6082134146801575193L;
private MacAddress clientMacAddress; private MacAddress clientMacAddress;
private long sessionId; private String sessionId;
private RadioType radioType; private RadioType radioType;
private boolean isReassociation; private boolean isReassociation;
private String ssid; private String ssid;
@@ -61,7 +61,7 @@ public class ClientConnectSuccessEvent extends RealTimeEvent implements HasClien
/** /**
* @return the sessionId * @return the sessionId
*/ */
public long getSessionId() { public String getSessionId() {
return sessionId; return sessionId;
} }
@@ -69,7 +69,7 @@ public class ClientConnectSuccessEvent extends RealTimeEvent implements HasClien
* @param sessionId * @param sessionId
* the sessionId to set * the sessionId to set
*/ */
public void setSessionId(long sessionId) { public void setSessionId(String sessionId) {
this.sessionId = sessionId; this.sessionId = sessionId;
} }

View File

@@ -45,7 +45,7 @@ public class ClientDisconnectEvent extends RealTimeEvent implements HasClientMac
} }
private static final long serialVersionUID = -7674230178565760938L; private static final long serialVersionUID = -7674230178565760938L;
private long sessionId; private String sessionId;
private byte[] macAddressBytes; private byte[] macAddressBytes;
private MacAddress clientMacAddress; private MacAddress clientMacAddress;
private long lastRecvTime; private long lastRecvTime;
@@ -104,7 +104,7 @@ public class ClientDisconnectEvent extends RealTimeEvent implements HasClientMac
return rssi; return rssi;
} }
public long getSessionId() { public String getSessionId() {
return sessionId; return sessionId;
} }
@@ -148,7 +148,7 @@ public class ClientDisconnectEvent extends RealTimeEvent implements HasClientMac
this.rssi = rssi; this.rssi = rssi;
} }
public void setSessionId(long sessionId) { public void setSessionId(String sessionId) {
this.sessionId = sessionId; this.sessionId = sessionId;
} }

View File

@@ -14,7 +14,7 @@ import com.telecominfraproject.wlan.systemevent.equipment.realtime.RealTimeEvent
public class ClientFailureEvent extends RealTimeEvent implements HasClientMac { public class ClientFailureEvent extends RealTimeEvent implements HasClientMac {
private static final long serialVersionUID = -16021752050335131L; private static final long serialVersionUID = -16021752050335131L;
private long sessionId; private String sessionId;
private String ssid; private String ssid;
private MacAddress clientMacAddress; private MacAddress clientMacAddress;
private WlanReasonCode reasonCode; private WlanReasonCode reasonCode;
@@ -38,11 +38,11 @@ public class ClientFailureEvent extends RealTimeEvent implements HasClientMac {
this.clientMacAddress = clientMacAddress; this.clientMacAddress = clientMacAddress;
} }
public long getSessionId() { public String getSessionId() {
return sessionId; return sessionId;
} }
public void setSessionId(long sessionId) { public void setSessionId(String sessionId) {
this.sessionId = sessionId; this.sessionId = sessionId;
} }

View File

@@ -10,7 +10,7 @@ import com.telecominfraproject.wlan.systemevent.equipment.realtime.RealTimeEvent
public class ClientFirstDataEvent extends RealTimeEvent implements HasClientMac { public class ClientFirstDataEvent extends RealTimeEvent implements HasClientMac {
private static final long serialVersionUID = 298223061973506469L; private static final long serialVersionUID = 298223061973506469L;
private long sessionId; private String sessionId;
private MacAddress clientMacAddress; private MacAddress clientMacAddress;
private long firstDataRcvdTs; private long firstDataRcvdTs;
private long firstDataSentTs; private long firstDataSentTs;
@@ -28,11 +28,11 @@ public class ClientFirstDataEvent extends RealTimeEvent implements HasClientMac
super(eventType, timestamp); super(eventType, timestamp);
} }
public long getSessionId() { public String getSessionId() {
return sessionId; return sessionId;
} }
public void setSessionId(long sessionId) { public void setSessionId(String sessionId) {
this.sessionId = sessionId; this.sessionId = sessionId;
} }

View File

@@ -1,6 +1,7 @@
package com.telecominfraproject.wlan.client.models.events.realtime; package com.telecominfraproject.wlan.client.models.events.realtime;
import java.util.Arrays; import java.util.Arrays;
import java.util.Objects;
import com.telecominfraproject.wlan.core.model.equipment.MacAddress; import com.telecominfraproject.wlan.core.model.equipment.MacAddress;
import com.telecominfraproject.wlan.core.model.json.interfaces.HasClientMac; import com.telecominfraproject.wlan.core.model.json.interfaces.HasClientMac;
@@ -10,7 +11,7 @@ import com.telecominfraproject.wlan.systemevent.equipment.realtime.RealTimeEvent
public class ClientIdEvent extends RealTimeEvent implements HasClientMac { public class ClientIdEvent extends RealTimeEvent implements HasClientMac {
private static final long serialVersionUID = 298223061973506469L; private static final long serialVersionUID = 298223061973506469L;
private long sessionId; private String sessionId;
private byte[] macAddressBytes; private byte[] macAddressBytes;
private MacAddress clientMacAddress; private MacAddress clientMacAddress;
private String userId; private String userId;
@@ -27,7 +28,7 @@ public class ClientIdEvent extends RealTimeEvent implements HasClientMac {
/** /**
* @return the sessionId * @return the sessionId
*/ */
public long getSessionId() { public String getSessionId() {
return sessionId; return sessionId;
} }
@@ -35,7 +36,7 @@ public class ClientIdEvent extends RealTimeEvent implements HasClientMac {
* @param sessionId * @param sessionId
* the sessionId to set * the sessionId to set
*/ */
public void setSessionId(long sessionId) { public void setSessionId(String sessionId) {
this.sessionId = sessionId; this.sessionId = sessionId;
} }
@@ -65,58 +66,28 @@ public class ClientIdEvent extends RealTimeEvent implements HasClientMac {
this.userId = userId; this.userId = userId;
} }
/*
* (non-Javadoc)
*
* @see java.lang.Object#hashCode()
*/
@Override @Override
public int hashCode() { public int hashCode() {
final int prime = 31; final int prime = 31;
int result = 1; int result = super.hashCode();
result = prime * result + Arrays.hashCode(macAddressBytes); result = prime * result + Arrays.hashCode(macAddressBytes);
result = prime * result + (int) (sessionId ^ (sessionId >>> 32)); result = prime * result + Objects.hash(clientMacAddress, sessionId, userId);
result = prime * result + ((userId == null) ? 0 : userId.hashCode());
result = prime * result + ((clientMacAddress == null) ? 0 : clientMacAddress.hashCode());
return result; return result;
} }
/*
* (non-Javadoc)
*
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
if (this == obj) { if (this == obj)
return true; return true;
} if (!super.equals(obj))
if (obj == null) {
return false; return false;
} if (getClass() != obj.getClass())
if (!super.equals(obj)) {
return false; return false;
}
if (!(obj instanceof ClientIdEvent)) {
return false;
}
ClientIdEvent other = (ClientIdEvent) obj; ClientIdEvent other = (ClientIdEvent) obj;
if (!Arrays.equals(macAddressBytes, other.macAddressBytes)) return Objects.equals(clientMacAddress, other.clientMacAddress) && Arrays.equals(macAddressBytes, other.macAddressBytes)
return false; && Objects.equals(sessionId, other.sessionId) && Objects.equals(userId, other.userId);
if (sessionId != other.sessionId)
return false;
if (userId == null) {
if (other.userId != null)
return false;
} else if (!userId.equals(other.userId))
return false;
if (clientMacAddress == null) {
if (other.clientMacAddress != null)
return false;
} else if (!clientMacAddress.equals(other.clientMacAddress))
return false;
return true;
} }
@Override @Override

View File

@@ -1,6 +1,6 @@
package com.telecominfraproject.wlan.client.models.events.realtime; package com.telecominfraproject.wlan.client.models.events.realtime;
import java.util.Arrays; import java.net.InetAddress;
import java.util.Objects; import java.util.Objects;
import com.telecominfraproject.wlan.core.model.equipment.MacAddress; import com.telecominfraproject.wlan.core.model.equipment.MacAddress;
@@ -12,9 +12,9 @@ public class ClientIpAddressEvent extends RealTimeEvent implements HasClientMac
private static final long serialVersionUID = -5332534925768685589L; private static final long serialVersionUID = -5332534925768685589L;
private long sessionId; private String sessionId;
private MacAddress clientMacAddress; private MacAddress clientMacAddress;
private byte[] ipAddr; private InetAddress ipAddr;
public ClientIpAddressEvent() { public ClientIpAddressEvent() {
// serialization // serialization
@@ -29,11 +29,11 @@ public class ClientIpAddressEvent extends RealTimeEvent implements HasClientMac
super(eventType, timestamp); super(eventType, timestamp);
} }
public long getSessionId() { public String getSessionId() {
return sessionId; return sessionId;
} }
public void setSessionId(long sessionId) { public void setSessionId(String sessionId) {
this.sessionId = sessionId; this.sessionId = sessionId;
} }
@@ -45,11 +45,11 @@ public class ClientIpAddressEvent extends RealTimeEvent implements HasClientMac
this.clientMacAddress = clientMacAddress; this.clientMacAddress = clientMacAddress;
} }
public byte[] getIpAddr() { public InetAddress getIpAddr() {
return ipAddr; return ipAddr;
} }
public void setIpAddr(byte[] ipAddr) { public void setIpAddr(InetAddress ipAddr) {
this.ipAddr = ipAddr; this.ipAddr = ipAddr;
} }
@@ -57,8 +57,7 @@ public class ClientIpAddressEvent extends RealTimeEvent implements HasClientMac
public int hashCode() { public int hashCode() {
final int prime = 31; final int prime = 31;
int result = super.hashCode(); int result = super.hashCode();
result = prime * result + Arrays.hashCode(this.ipAddr); result = prime * result + Objects.hash(ipAddr, clientMacAddress, sessionId);
result = prime * result + Objects.hash(clientMacAddress, sessionId);
return result; return result;
} }
@@ -74,7 +73,7 @@ public class ClientIpAddressEvent extends RealTimeEvent implements HasClientMac
return false; return false;
} }
ClientIpAddressEvent other = (ClientIpAddressEvent) obj; ClientIpAddressEvent other = (ClientIpAddressEvent) obj;
return Objects.equals(clientMacAddress, other.clientMacAddress) && Arrays.equals(ipAddr, other.ipAddr) return Objects.equals(clientMacAddress, other.clientMacAddress) && Objects.equals(ipAddr, other.ipAddr)
&& this.sessionId == other.sessionId; && this.sessionId == other.sessionId;
} }

View File

@@ -26,7 +26,7 @@ public class ClientTimeoutEvent extends RealTimeEvent implements HasClientMac {
} }
} }
private long sessionId; private String sessionId;
private MacAddress clientMacAddress; private MacAddress clientMacAddress;
private long lastRecvTime; private long lastRecvTime;
private long lastSentTime; private long lastSentTime;
@@ -45,11 +45,11 @@ public class ClientTimeoutEvent extends RealTimeEvent implements HasClientMac {
super(eventType, timestamp); super(eventType, timestamp);
} }
public long getSessionId() { public String getSessionId() {
return sessionId; return sessionId;
} }
public void setSessionId(long sessionId) { public void setSessionId(String sessionId) {
this.sessionId = sessionId; this.sessionId = sessionId;
} }

View File

@@ -1,6 +1,7 @@
package com.telecominfraproject.wlan.client.session.models; package com.telecominfraproject.wlan.client.session.models;
import java.net.InetAddress; import java.net.InetAddress;
import java.util.Objects;
import com.telecominfraproject.wlan.core.model.equipment.WiFiSessionUtility; import com.telecominfraproject.wlan.core.model.equipment.WiFiSessionUtility;
import com.telecominfraproject.wlan.core.model.json.BaseJsonModel; import com.telecominfraproject.wlan.core.model.json.BaseJsonModel;
@@ -29,10 +30,9 @@ public class ClientDhcpDetails extends BaseJsonModel {
/** /**
* Identifies the association where DHCP last occurred. * Identifies the association where DHCP last occurred.
*/ */
private long associationId; private String associationId;
public ClientDhcpDetails(String sessionId) {
public ClientDhcpDetails(long sessionId) {
this.associationId = sessionId; this.associationId = sessionId;
} }
@@ -101,10 +101,10 @@ public class ClientDhcpDetails extends BaseJsonModel {
this.firstDiscoverTimestamp = firstDiscoverTimestamp; this.firstDiscoverTimestamp = firstDiscoverTimestamp;
} }
public long getAssociationId() { public String getAssociationId() {
return associationId; return associationId;
} }
public void setAssociationId(Long associationId) { public void setAssociationId(String associationId) {
this.associationId = associationId; this.associationId = associationId;
} }
@@ -116,123 +116,6 @@ public class ClientDhcpDetails extends BaseJsonModel {
this.nakTimestamp = nakTimestamp; this.nakTimestamp = nakTimestamp;
} }
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (int) (associationId ^ (associationId >>> 32));
result = prime * result + ((dhcpServerIp == null) ? 0 : dhcpServerIp.hashCode());
result = prime * result + ((firstDiscoverTimestamp == null) ? 0 : firstDiscoverTimestamp.hashCode());
result = prime * result + ((firstOfferTimestamp == null) ? 0 : firstOfferTimestamp.hashCode());
result = prime * result + ((firstRequestTimestamp == null) ? 0 : firstRequestTimestamp.hashCode());
result = prime * result + (fromInternal ? 1231 : 1237);
result = prime * result + ((gatewayIp == null) ? 0 : gatewayIp.hashCode());
result = prime * result + ((leaseStartTimestamp == null) ? 0 : leaseStartTimestamp.hashCode());
result = prime * result + ((leaseTimeInSeconds == null) ? 0 : leaseTimeInSeconds.hashCode());
result = prime * result + ((nakTimestamp == null) ? 0 : nakTimestamp.hashCode());
result = prime * result + ((primaryDns == null) ? 0 : primaryDns.hashCode());
result = prime * result + ((secondaryDns == null) ? 0 : secondaryDns.hashCode());
result = prime * result + ((subnetMask == null) ? 0 : subnetMask.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof ClientDhcpDetails)) {
return false;
}
ClientDhcpDetails other = (ClientDhcpDetails) obj;
if (associationId != other.associationId) {
return false;
}
if (dhcpServerIp == null) {
if (other.dhcpServerIp != null) {
return false;
}
} else if (!dhcpServerIp.equals(other.dhcpServerIp)) {
return false;
}
if (firstDiscoverTimestamp == null) {
if (other.firstDiscoverTimestamp != null) {
return false;
}
} else if (!firstDiscoverTimestamp.equals(other.firstDiscoverTimestamp)) {
return false;
}
if (firstOfferTimestamp == null) {
if (other.firstOfferTimestamp != null) {
return false;
}
} else if (!firstOfferTimestamp.equals(other.firstOfferTimestamp)) {
return false;
}
if (firstRequestTimestamp == null) {
if (other.firstRequestTimestamp != null) {
return false;
}
} else if (!firstRequestTimestamp.equals(other.firstRequestTimestamp)) {
return false;
}
if (fromInternal != other.fromInternal) {
return false;
}
if (gatewayIp == null) {
if (other.gatewayIp != null) {
return false;
}
} else if (!gatewayIp.equals(other.gatewayIp)) {
return false;
}
if (leaseStartTimestamp == null) {
if (other.leaseStartTimestamp != null) {
return false;
}
} else if (!leaseStartTimestamp.equals(other.leaseStartTimestamp)) {
return false;
}
if (leaseTimeInSeconds == null) {
if (other.leaseTimeInSeconds != null) {
return false;
}
} else if (!leaseTimeInSeconds.equals(other.leaseTimeInSeconds)) {
return false;
}
if (nakTimestamp == null) {
if (other.nakTimestamp != null) {
return false;
}
} else if (!nakTimestamp.equals(other.nakTimestamp)) {
return false;
}
if (primaryDns == null) {
if (other.primaryDns != null) {
return false;
}
} else if (!primaryDns.equals(other.primaryDns)) {
return false;
}
if (secondaryDns == null) {
if (other.secondaryDns != null) {
return false;
}
} else if (!secondaryDns.equals(other.secondaryDns)) {
return false;
}
if (subnetMask == null) {
if (other.subnetMask != null) {
return false;
}
} else if (!subnetMask.equals(other.subnetMask)) {
return false;
}
return true;
}
@Override @Override
public ClientDhcpDetails clone() { public ClientDhcpDetails clone() {
ClientDhcpDetails ret = (ClientDhcpDetails) super.clone(); ClientDhcpDetails ret = (ClientDhcpDetails) super.clone();
@@ -241,8 +124,7 @@ public class ClientDhcpDetails extends BaseJsonModel {
public void mergeDetails(ClientDhcpDetails other) { public void mergeDetails(ClientDhcpDetails other) {
if(other == null) return; if(other == null) return;
if(WiFiSessionUtility.decodeWiFiAssociationId(Long.parseUnsignedLong(other.associationId))>WiFiSessionUtility.decodeWiFiAssociationId(Long.parseUnsignedLong(associationId))) {
if(WiFiSessionUtility.decodeWiFiAssociationId(other.associationId)>WiFiSessionUtility.decodeWiFiAssociationId(associationId)) {
// The other dhcp details are from a newer session and so everything must be reset. // The other dhcp details are from a newer session and so everything must be reset.
this.dhcpServerIp = null; this.dhcpServerIp = null;
this.firstDiscoverTimestamp = null; this.firstDiscoverTimestamp = null;
@@ -258,8 +140,7 @@ public class ClientDhcpDetails extends BaseJsonModel {
this.associationId = other.associationId; this.associationId = other.associationId;
this.fromInternal = false; this.fromInternal = false;
} }
else if(other.associationId != associationId) { if(!Objects.equals(this.associationId, other.associationId)) {
// other is older, ignore it
return; return;
} }
dhcpServerIp = (InetAddress) assignOtherIfOtherNotNull(dhcpServerIp, other.dhcpServerIp); dhcpServerIp = (InetAddress) assignOtherIfOtherNotNull(dhcpServerIp, other.dhcpServerIp);
@@ -305,4 +186,28 @@ public class ClientDhcpDetails extends BaseJsonModel {
this.fromInternal = fromInternal; this.fromInternal = fromInternal;
} }
@Override
public int hashCode() {
return Objects.hash(associationId, dhcpServerIp, firstDiscoverTimestamp, firstOfferTimestamp, firstRequestTimestamp, fromInternal, gatewayIp,
leaseStartTimestamp, leaseTimeInSeconds, nakTimestamp, primaryDns, secondaryDns, subnetMask);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ClientDhcpDetails other = (ClientDhcpDetails) obj;
return Objects.equals(associationId, other.associationId) && Objects.equals(dhcpServerIp, other.dhcpServerIp)
&& Objects.equals(firstDiscoverTimestamp, other.firstDiscoverTimestamp) && Objects.equals(firstOfferTimestamp, other.firstOfferTimestamp)
&& Objects.equals(firstRequestTimestamp, other.firstRequestTimestamp) && fromInternal == other.fromInternal
&& Objects.equals(gatewayIp, other.gatewayIp) && Objects.equals(leaseStartTimestamp, other.leaseStartTimestamp)
&& Objects.equals(leaseTimeInSeconds, other.leaseTimeInSeconds) && Objects.equals(nakTimestamp, other.nakTimestamp)
&& Objects.equals(primaryDns, other.primaryDns) && Objects.equals(secondaryDns, other.secondaryDns)
&& Objects.equals(subnetMask, other.subnetMask);
}
} }

View File

@@ -8,6 +8,8 @@ import com.telecominfraproject.wlan.core.model.json.interfaces.HasCustomerId;
public class ClientSession extends BaseJsonModel implements HasCustomerId { public class ClientSession extends BaseJsonModel implements HasCustomerId {
private static final String UNKNOWN_OUI = "ffffff";
private static final long serialVersionUID = -7714023056859882994L; private static final long serialVersionUID = -7714023056859882994L;
private MacAddress macAddress; private MacAddress macAddress;
@@ -16,6 +18,7 @@ public class ClientSession extends BaseJsonModel implements HasCustomerId {
private long locationId; private long locationId;
private ClientSessionDetails details; private ClientSessionDetails details;
private long lastModifiedTimestamp; private long lastModifiedTimestamp;
private String oui;
public long getEquipmentId() { public long getEquipmentId() {
return equipmentId; return equipmentId;
@@ -47,6 +50,12 @@ public class ClientSession extends BaseJsonModel implements HasCustomerId {
public void setMacAddress(MacAddress macAddress) { public void setMacAddress(MacAddress macAddress) {
this.macAddress = macAddress; this.macAddress = macAddress;
if (macAddress != null && macAddress.isGlobalAddress()) {
this.oui = macAddress.toOuiString();
}
else {
this.oui = UNKNOWN_OUI;
}
} }
public long getLastModifiedTimestamp() { public long getLastModifiedTimestamp() {
@@ -65,6 +74,14 @@ public class ClientSession extends BaseJsonModel implements HasCustomerId {
this.details = details; this.details = details;
} }
public String getOui() {
return oui;
}
public void setOui(String oui) {
this.oui = oui;
}
@Override @Override
public ClientSession clone() { public ClientSession clone() {
ClientSession ret = (ClientSession) super.clone(); ClientSession ret = (ClientSession) super.clone();
@@ -79,7 +96,7 @@ public class ClientSession extends BaseJsonModel implements HasCustomerId {
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash(customerId, details, equipmentId, locationId, lastModifiedTimestamp, macAddress); return Objects.hash(customerId, details, equipmentId, locationId, lastModifiedTimestamp, macAddress, oui);
} }
@Override @Override
@@ -95,7 +112,8 @@ public class ClientSession extends BaseJsonModel implements HasCustomerId {
&& equipmentId == other.equipmentId && equipmentId == other.equipmentId
&& locationId == other.locationId && locationId == other.locationId
&& lastModifiedTimestamp == other.lastModifiedTimestamp && lastModifiedTimestamp == other.lastModifiedTimestamp
&& Objects.equals(macAddress, other.macAddress); && Objects.equals(macAddress, other.macAddress)
&& Objects.equals(oui, other.oui);
} }
@Override @Override

View File

@@ -19,7 +19,7 @@ public class ClientSessionDetails extends BaseJsonModel {
private static final long serialVersionUID = -7714023056859882994L; private static final long serialVersionUID = -7714023056859882994L;
private long sessionId; private String sessionId;
private Long authTimestamp; private Long authTimestamp;
private Long assocTimestamp; private Long assocTimestamp;
private Integer assocInternalSC; private Integer assocInternalSC;
@@ -54,22 +54,22 @@ public class ClientSessionDetails extends BaseJsonModel {
private Boolean is11VUsed; private Boolean is11VUsed;
private SecurityType securityType; private SecurityType securityType;
private SteerType steerType; private SteerType steerType;
private Long previousValidSessionId; private String previousValidSessionId;
private ClientFailureDetails lastFailureDetails; private ClientFailureDetails lastFailureDetails;
private ClientFailureDetails firstFailureDetails; private ClientFailureDetails firstFailureDetails;
private Integer associationStatus; private Integer associationStatus;
private Integer dynamicVlan; private Integer dynamicVlan;
private Integer assocRssi; private Integer assocRssi;
private Long priorSessionId; private String priorSessionId;
private Long priorEquipmentId; private Long priorEquipmentId;
private String classificationName; private String classificationName;
private AssociationState associationState; private AssociationState associationState;
public long getSessionId() { public String getSessionId() {
return sessionId; return sessionId;
} }
public void setSessionId(long sessionId) { public void setSessionId(String sessionId) {
this.sessionId = sessionId; this.sessionId = sessionId;
} }
@@ -413,11 +413,11 @@ public class ClientSessionDetails extends BaseJsonModel {
this.steerType = steerType; this.steerType = steerType;
} }
public Long getPreviousValidSessionId() { public String getPreviousValidSessionId() {
return previousValidSessionId; return previousValidSessionId;
} }
public void setPreviousValidSessionId(Long previousValidSessionId) { public void setPreviousValidSessionId(String previousValidSessionId) {
this.previousValidSessionId = previousValidSessionId; this.previousValidSessionId = previousValidSessionId;
} }
@@ -821,11 +821,11 @@ public class ClientSessionDetails extends BaseJsonModel {
this.assocRssi = assocRssi; this.assocRssi = assocRssi;
} }
public Long getPriorSessionId() { public String getPriorSessionId() {
return priorSessionId; return priorSessionId;
} }
public void setPriorSessionId(Long priorSessionId) { public void setPriorSessionId(String priorSessionId) {
this.priorSessionId = priorSessionId; this.priorSessionId = priorSessionId;
} }

View File

@@ -8,7 +8,7 @@ import com.telecominfraproject.wlan.core.model.json.GenericResponse;
import com.telecominfraproject.wlan.core.model.pagination.ColumnAndSort; import com.telecominfraproject.wlan.core.model.pagination.ColumnAndSort;
import com.telecominfraproject.wlan.core.model.pagination.PaginationContext; import com.telecominfraproject.wlan.core.model.pagination.PaginationContext;
import com.telecominfraproject.wlan.core.model.pagination.PaginationResponse; import com.telecominfraproject.wlan.core.model.pagination.PaginationResponse;
import com.telecominfraproject.wlan.client.info.models.ClientSessionCounts;
import com.telecominfraproject.wlan.client.models.Client; import com.telecominfraproject.wlan.client.models.Client;
import com.telecominfraproject.wlan.client.session.models.ClientSession; import com.telecominfraproject.wlan.client.session.models.ClientSession;
@@ -144,4 +144,12 @@ public interface ClientServiceInterface {
*/ */
PaginationResponse<ClientSession> getSessionsForCustomer(int customerId, Set<Long> equipmentIds, Set<Long> locationIds, String macSubstring, List<ColumnAndSort> sortBy, PaginationContext<ClientSession> context); PaginationResponse<ClientSession> getSessionsForCustomer(int customerId, Set<Long> equipmentIds, Set<Long> locationIds, String macSubstring, List<ColumnAndSort> sortBy, PaginationContext<ClientSession> context);
/**
* Get Client Session counts for the given customerId.
*
* @param customerId
* @return
*/
ClientSessionCounts getSessionCounts(int customerId);
} }

View File

@@ -3,13 +3,12 @@ package com.telecominfraproject.wlan.client;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import com.telecominfraproject.wlan.client.controller.ClientController; import com.telecominfraproject.wlan.client.controller.ClientController;
import com.telecominfraproject.wlan.client.controller.ClientController.ListOfClientSessions; import com.telecominfraproject.wlan.client.controller.ClientController.ListOfClientSessions;
import com.telecominfraproject.wlan.client.info.models.ClientSessionCounts;
import com.telecominfraproject.wlan.client.models.Client; import com.telecominfraproject.wlan.client.models.Client;
import com.telecominfraproject.wlan.client.session.models.ClientSession; import com.telecominfraproject.wlan.client.session.models.ClientSession;
import com.telecominfraproject.wlan.core.model.equipment.MacAddress; import com.telecominfraproject.wlan.core.model.equipment.MacAddress;
@@ -26,7 +25,6 @@ import com.telecominfraproject.wlan.core.model.pagination.PaginationResponse;
public class ClientServiceLocal implements ClientServiceInterface { public class ClientServiceLocal implements ClientServiceInterface {
@Autowired private ClientController clientController; @Autowired private ClientController clientController;
private static final Logger LOG = LoggerFactory.getLogger(ClientServiceLocal.class);
@Override @Override
public Client create(Client client) { public Client create(Client client) {
@@ -109,5 +107,10 @@ public class ClientServiceLocal implements ClientServiceInterface {
public GenericResponse deleteSessions(long createdBeforeTimestamp) { public GenericResponse deleteSessions(long createdBeforeTimestamp) {
return clientController.deleteSessions(createdBeforeTimestamp); return clientController.deleteSessions(createdBeforeTimestamp);
} }
@Override
public ClientSessionCounts getSessionCounts(int customerId) {
return clientController.getSessionCounts(customerId);
}
} }

View File

@@ -12,6 +12,7 @@ import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import com.telecominfraproject.wlan.client.info.models.ClientSessionCounts;
import com.telecominfraproject.wlan.client.models.Client; import com.telecominfraproject.wlan.client.models.Client;
import com.telecominfraproject.wlan.client.session.models.ClientSession; import com.telecominfraproject.wlan.client.session.models.ClientSession;
import com.telecominfraproject.wlan.core.client.BaseRemoteClient; import com.telecominfraproject.wlan.core.client.BaseRemoteClient;
@@ -365,5 +366,21 @@ public class ClientServiceRemote extends BaseRemoteClient implements ClientServi
return baseUrl; return baseUrl;
} }
@Override
public ClientSessionCounts getSessionCounts(int customerId) {
LOG.debug("calling getSessionCounts( {} )", customerId);
try {
ResponseEntity<ClientSessionCounts> responseEntity = restTemplate.exchange(getBaseUrl() + "/session/countsForCustomer?customerId={customerId}",
HttpMethod.GET, null, ClientSessionCounts.class, customerId);
ClientSessionCounts result = responseEntity.getBody();
LOG.debug("getSessionCounts({}) returns {} ", customerId, result);
return result;
} catch (Exception exp) {
LOG.error("getSessionCounts({}) exception ", customerId, exp);
throw exp;
}
}
} }

View File

@@ -8,6 +8,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestMethod;
@@ -15,6 +16,7 @@ import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import com.telecominfraproject.wlan.client.datastore.ClientDatastore; import com.telecominfraproject.wlan.client.datastore.ClientDatastore;
import com.telecominfraproject.wlan.client.info.models.ClientSessionCounts;
import com.telecominfraproject.wlan.client.models.Client; import com.telecominfraproject.wlan.client.models.Client;
import com.telecominfraproject.wlan.client.models.events.ClientAddedEvent; import com.telecominfraproject.wlan.client.models.events.ClientAddedEvent;
import com.telecominfraproject.wlan.client.models.events.ClientBlockListChangedEvent; import com.telecominfraproject.wlan.client.models.events.ClientBlockListChangedEvent;
@@ -430,6 +432,13 @@ public class ClientController {
return new GenericResponse(true, ""); return new GenericResponse(true, "");
} }
@GetMapping("/session/countsForCustomer")
public ClientSessionCounts getSessionCounts(@RequestParam int customerId) {
ClientSessionCounts ret = clientDatastore.getSessionCounts(customerId);
LOG.debug("countsForCustomer({}) {}", customerId, ret);
return ret;
}
private void publishEvent(SystemEvent event) { private void publishEvent(SystemEvent event) {
if (event == null) { if (event == null) {

View File

@@ -147,8 +147,7 @@ components:
type: object type: object
properties: properties:
sessionId: sessionId:
type: integer type: string
format: int64
authTimestamp: authTimestamp:
type: integer type: integer
format: int64 format: int64
@@ -235,8 +234,7 @@ components:
steerType: steerType:
$ref: '#/components/schemas/SteerType' $ref: '#/components/schemas/SteerType'
previousValidSessionId: previousValidSessionId:
type: integer type: string
format: int64
lastFailureDetails: lastFailureDetails:
$ref: '#/components/schemas/ClientFailureDetails' $ref: '#/components/schemas/ClientFailureDetails'
firstFailureDetails: firstFailureDetails:
@@ -251,8 +249,7 @@ components:
type: integer type: integer
format: int32 format: int32
priorSessionId: priorSessionId:
type: integer type: string
format: int64
priorEquipmentId: priorEquipmentId:
type: integer type: integer
format: int64 format: int64

View File

@@ -59,8 +59,7 @@
<version>1.2.0-SNAPSHOT</version> <version>1.2.0-SNAPSHOT</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
<artifactId>base-stream-interface</artifactId> <artifactId>base-stream-interface</artifactId>
<groupId>com.telecominfraproject.wlan</groupId> <groupId>com.telecominfraproject.wlan</groupId>

View File

@@ -555,7 +555,7 @@ components:
type: integer type: integer
format: int32 format: int32
payload: payload:
$ref: '#/components/schemas/PortalUser' $ref: '#/components/schemas/PortalUserEventPayload'
PortalUserChangedEvent: PortalUserChangedEvent:
properties: properties:
@@ -566,7 +566,7 @@ components:
type: integer type: integer
format: int32 format: int32
payload: payload:
$ref: '#/components/schemas/PortalUser' $ref: '#/components/schemas/PortalUserEventPayload'
PortalUserRemovedEvent: PortalUserRemovedEvent:
properties: properties:
@@ -577,7 +577,7 @@ components:
type: integer type: integer
format: int32 format: int32
payload: payload:
$ref: '#/components/schemas/PortalUser' $ref: '#/components/schemas/PortalUserEventPayload'
ProfileAddedEvent: ProfileAddedEvent:
properties: properties:
@@ -662,8 +662,7 @@ components:
clientMacAddress: clientMacAddress:
$ref: '#/components/schemas/MacAddress' $ref: '#/components/schemas/MacAddress'
sessionId: sessionId:
type: integer type: string
format: int64
customerId: customerId:
type: integer type: integer
format: int32 format: int32
@@ -759,8 +758,7 @@ components:
allOf: allOf:
$ref: '#/components/schemas/RealTimeEvent' $ref: '#/components/schemas/RealTimeEvent'
sessionId: sessionId:
type: integer type: string
format: int64
ssid: ssid:
type: string type: string
clientMacAddress: clientMacAddress:
@@ -791,8 +789,7 @@ components:
clientMacAddress: clientMacAddress:
$ref: '#/components/schemas/MacAddress' $ref: '#/components/schemas/MacAddress'
sessionId: sessionId:
type: integer type: string
format: int64
radioType: radioType:
$ref: '#/components/schemas/RadioType' $ref: '#/components/schemas/RadioType'
isReassociation: isReassociation:
@@ -844,8 +841,7 @@ components:
allOf: allOf:
$ref: '#/components/schemas/RealTimeEvent' $ref: '#/components/schemas/RealTimeEvent'
sessionId: sessionId:
type: integer type: string
format: int64
ssid: ssid:
type: string type: string
clientMacAddress: clientMacAddress:
@@ -860,8 +856,7 @@ components:
allOf: allOf:
$ref: '#/components/schemas/RealTimeEvent' $ref: '#/components/schemas/RealTimeEvent'
sessionId: sessionId:
type: integer type: string
format: int64
macAddressBytes: macAddressBytes:
type: array type: array
items: items:
@@ -884,8 +879,7 @@ components:
allOf: allOf:
$ref: '#/components/schemas/RealTimeEvent' $ref: '#/components/schemas/RealTimeEvent'
sessionId: sessionId:
type: integer type: string
format: int64
clientMacAddress: clientMacAddress:
$ref: '#/components/schemas/MacAddress' $ref: '#/components/schemas/MacAddress'
lastRecvTime: lastRecvTime:
@@ -902,8 +896,7 @@ components:
allOf: allOf:
$ref: '#/components/schemas/RealTimeEvent' $ref: '#/components/schemas/RealTimeEvent'
sessionId: sessionId:
type: integer type: string
format: int64
ssid: ssid:
type: string type: string
clientMacAddress: clientMacAddress:
@@ -934,8 +927,7 @@ components:
allOf: allOf:
$ref: '#/components/schemas/RealTimeEvent' $ref: '#/components/schemas/RealTimeEvent'
sessionId: sessionId:
type: integer type: string
format: int64
ssid: ssid:
type: string type: string
clientMacAddress: clientMacAddress:
@@ -971,8 +963,7 @@ components:
allOf: allOf:
$ref: '#/components/schemas/RealTimeEvent' $ref: '#/components/schemas/RealTimeEvent'
sessionId: sessionId:
type: integer type: string
format: int64
clientMacAddress: clientMacAddress:
$ref: '#/components/schemas/MacAddress' $ref: '#/components/schemas/MacAddress'
firstDataRcvdTs: firstDataRcvdTs:
@@ -987,8 +978,7 @@ components:
allOf: allOf:
$ref: '#/components/schemas/RealTimeEvent' $ref: '#/components/schemas/RealTimeEvent'
sessionId: sessionId:
type: integer type: string
format: int64
clientMacAddress: clientMacAddress:
$ref: '#/components/schemas/MacAddress' $ref: '#/components/schemas/MacAddress'
ipAddr: ipAddr:
@@ -1061,8 +1051,7 @@ components:
type: integer type: integer
format: int64 format: int64
associationId: associationId:
type: integer type: string
format: int64
clientMacAddress: clientMacAddress:
$ref: '#/components/schemas/MacAddress' $ref: '#/components/schemas/MacAddress'
radioType: radioType:
@@ -1104,8 +1093,7 @@ components:
type: integer type: integer
format: int64 format: int64
associationId: associationId:
type: integer type: string
format: int64
macAddress: macAddress:
$ref: '#/components/schemas/MacAddress' $ref: '#/components/schemas/MacAddress'
radioType: radioType:
@@ -1144,11 +1132,9 @@ components:
allOf: allOf:
$ref: '#/components/schemas/RealTimeEvent' $ref: '#/components/schemas/RealTimeEvent'
videoSessionId: videoSessionId:
type: integer type: string
format: int64
sessionId: sessionId:
type: integer type: string
format: int64
clientMac: clientMac:
$ref: '#/components/schemas/MacAddress' $ref: '#/components/schemas/MacAddress'
serverIp: serverIp:
@@ -1164,11 +1150,9 @@ components:
allOf: allOf:
$ref: '#/components/schemas/RealTimeEvent' $ref: '#/components/schemas/RealTimeEvent'
videoSessionId: videoSessionId:
type: integer type: string
format: int64
sessionId: sessionId:
type: integer type: string
format: int64
clientMac: clientMac:
$ref: '#/components/schemas/MacAddress' $ref: '#/components/schemas/MacAddress'
serverIp: serverIp:
@@ -1185,8 +1169,7 @@ components:
type: integer type: integer
format: int64 format: int64
sessionId: sessionId:
type: integer type: string
format: int64
clientMac: clientMac:
$ref: '#/components/schemas/MacAddress' $ref: '#/components/schemas/MacAddress'
serverIp: serverIp:
@@ -1555,8 +1538,7 @@ components:
type: object type: object
properties: properties:
sessionId: sessionId:
type: integer type: string
format: int64
authTimestamp: authTimestamp:
type: integer type: integer
format: int64 format: int64
@@ -1643,8 +1625,7 @@ components:
steerType: steerType:
$ref: '#/components/schemas/SteerType' $ref: '#/components/schemas/SteerType'
previousValidSessionId: previousValidSessionId:
type: integer type: string
format: int64
lastFailureDetails: lastFailureDetails:
$ref: '#/components/schemas/ClientFailureDetails' $ref: '#/components/schemas/ClientFailureDetails'
firstFailureDetails: firstFailureDetails:
@@ -1659,8 +1640,7 @@ components:
type: integer type: integer
format: int32 format: int32
priorSessionId: priorSessionId:
type: integer type: string
format: int64
priorEquipmentId: priorEquipmentId:
type: integer type: integer
format: int64 format: int64
@@ -2402,7 +2382,7 @@ components:
# Portal User data models # Portal User data models
# #
PortalUser: PortalUserEventPayload:
type: object type: object
properties: properties:
id: id:
@@ -2413,10 +2393,6 @@ components:
format: int32 format: int32
username: username:
type: string type: string
password:
type: string
role:
$ref: '#/components/schemas/PortalUserRole'
createdTimestamp: createdTimestamp:
type: integer type: integer
format: int64 format: int64
@@ -2427,8 +2403,6 @@ components:
example: example:
customerId: 2 customerId: 2
username: new_user username: new_user
password: pwd
role: CustomerIT
PortalUserRole: PortalUserRole:
type: string type: string
@@ -2856,6 +2830,9 @@ components:
sharedSecret: sharedSecret:
type: string type: string
format: password format: password
dynamicDiscovery:
description: Dynamic discovery of HSP and IdPs (home service and identity providers). Regardless of configured value, this will only be set 'true' on the AP if useRadSec is also true.
type: boolean
example: example:
model_type: RadiusProxyConfiguration model_type: RadiusProxyConfiguration
caCert: caCert:
@@ -3159,6 +3136,14 @@ components:
- wpa2OnlyPSK - wpa2OnlyPSK
- wpa2OnlyRadius - wpa2OnlyRadius
- wep - wep
- wpaEAP
- wpa2EAP
- wpa2OnlyEAP
- wpa3OnlySAE
- wpa3MixedSAE
- wpa3OnlyEAP
- wpa3MixedEAP
- wpa3OnlyEAP192
RadioBasedSsidConfigurationMap: RadioBasedSsidConfigurationMap:
properties: properties:
@@ -3453,7 +3438,16 @@ components:
$ref: '#/components/schemas/StatusCode' $ref: '#/components/schemas/StatusCode'
statusMessage: statusMessage:
type: string type: string
ledStatus:
$ref: '#/components/schemas/LedStatus'
LedStatus:
type: string
enum:
- led_blink
- led_off
- UNKNOWN
StatusCode: StatusCode:
type: string type: string
enum: enum:
@@ -4387,7 +4381,9 @@ components:
- RADIO_CHANNEL - RADIO_CHANNEL
channelNumberStatusDataMap: channelNumberStatusDataMap:
$ref: '#/components/schemas/IntegerPerRadioTypeMap' $ref: '#/components/schemas/IntegerPerRadioTypeMap'
txPowerDataMap:
$ref: '#/components/schemas/IntegerPerRadioTypeMap'
# #
# Equipment configuration data models # Equipment configuration data models
# #
@@ -4496,6 +4492,8 @@ components:
type: boolean type: boolean
forwardMode: forwardMode:
$ref: '#/components/schemas/NetworkForwardMode' $ref: '#/components/schemas/NetworkForwardMode'
blinkAllLEDs:
type: boolean
radioMap: radioMap:
$ref: '#/components/schemas/RadioMap' $ref: '#/components/schemas/RadioMap'
advancedRadioMap: advancedRadioMap:
@@ -5040,9 +5038,8 @@ components:
format: int32 format: int32
sessionId: sessionId:
type: integer type: string
format: int64
classificationName: classificationName:
type: string type: string

View File

@@ -189,7 +189,6 @@
<module>../provisioning-sp</module> <module>../provisioning-sp</module>
<module>../dashboard-sp</module> <module>../dashboard-sp</module>
<module>../equipment-alarms-sp</module>
<module>../adoption-metrics-sp</module> <module>../adoption-metrics-sp</module>
<module>../single-process-streams</module> <module>../single-process-streams</module>

View File

@@ -1 +0,0 @@
/target/

View File

@@ -1,111 +0,0 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.telecominfraproject.wlan</groupId>
<artifactId>tip-wlan-cloud-root-pom</artifactId>
<version>1.2.0-SNAPSHOT</version>
<relativePath>../../wlan-cloud-root</relativePath>
</parent>
<artifactId>equipment-alarms-sp</artifactId>
<name>equipment-alarms-sp</name>
<description>Stream Processors for raising/clearing equipment alarms based on reported metrics.</description>
<dependencies>
<dependency>
<artifactId>base-stream-consumer</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
</dependency>
<dependency>
<artifactId>service-metric-models</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
</dependency>
<dependency>
<artifactId>system-event-models</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
</dependency>
<dependency>
<artifactId>alarm-service-interface</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
</dependency>
<dependency>
<artifactId>status-service-interface</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
</dependency>
<dependency>
<artifactId>equipment-service-interface</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
</dependency>
<!-- unit tests dependencies -->
<dependency>
<artifactId>single-process-streams</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependency>
<artifactId>alarm-service-local</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependency>
<artifactId>status-service-local</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependency>
<artifactId>equipment-service-local</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependency>
<artifactId>alarm-datastore-inmemory</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependency>
<artifactId>status-datastore-inmemory</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependency>
<artifactId>equipment-datastore-inmemory</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependency>
<artifactId>cloud-event-dispatcher-empty</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@@ -1,187 +0,0 @@
package com.telecominfraproject.wlan.streams.equipmentalarms;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import com.telecominfraproject.wlan.alarm.models.Alarm;
import com.telecominfraproject.wlan.alarm.models.AlarmCode;
import com.telecominfraproject.wlan.servicemetric.apnode.models.ApNodeMetrics;
/**
* <br>This context keeps track of information needed for raising/clearing the alarms with the following codes:
* <ul>
* <li>AlarmCode.CPUTemperature
* <li>AlarmCode.CPUUtilization
* <li>AlarmCode.MemoryUtilization
* <li>AlarmCode.NoMetricsReceived
* </ul>
*
* @author dtop
*/
public class EquipmentAlarmsContext {
private final int customerId;
private final long equipmentId;
private final Map<AlarmCode, Alarm> existingAlarms = new ConcurrentHashMap<>();
private final long timeBucketMs;
private final int temperatureThresholdInC;
private final int cpuUtilThresholdPct;
private final int memoryUtilThresholdPct;
private final Map<Long, Integer> cpuTempSamples = new ConcurrentHashMap<>();
private final Map<Long, Integer> cpuUtilSamples = new ConcurrentHashMap<>();
private final Map<Long, Integer> memoryUtilSamples = new ConcurrentHashMap<>();
private final Map<Long, Long> metricReceivedTimestamps = new ConcurrentHashMap<>();
private long totalAvailableMemoryKb;
private final long contextCreationTimestampMs = System.currentTimeMillis();
public EquipmentAlarmsContext(int customerId, long equipmentId, List<Alarm> existingAlarmsList, long timeBucketMs, int temperatureThresholdInC, int cpuUtilThresholdPct, int memoryUtilThresholdPct) {
this.customerId = customerId;
this.equipmentId = equipmentId;
existingAlarmsList.forEach(a -> this.existingAlarms.put(a.getAlarmCode(), a));
this.timeBucketMs = timeBucketMs;
this.temperatureThresholdInC = temperatureThresholdInC;
this.cpuUtilThresholdPct = cpuUtilThresholdPct;
this.memoryUtilThresholdPct = memoryUtilThresholdPct;
}
public long getTotalAvailableMemoryKb() {
return totalAvailableMemoryKb;
}
public void setTotalAvailableMemoryKb(long totalAvailableMemoryKb) {
this.totalAvailableMemoryKb = totalAvailableMemoryKb;
}
public int getCustomerId() {
return customerId;
}
public long getEquipmentId() {
return equipmentId;
}
public Map<AlarmCode, Alarm> getExistingAlarms() {
return existingAlarms;
}
public void addDataSamples(long timestamp, ApNodeMetrics model) {
// add new samples
if(model.getApPerformance()!=null ) {
if(model.getApPerformance().getCpuTemperature()!=null) {
cpuTempSamples.put(timestamp, model.getApPerformance().getCpuTemperature());
}
if(model.getApPerformance().getAvgCpuUtilized()!=null) {
cpuUtilSamples.put(timestamp, model.getApPerformance().getAvgCpuUtilized().intValue());
}
if(model.getApPerformance().getFreeMemory()!=null && totalAvailableMemoryKb>0) {
memoryUtilSamples.put(timestamp, 100 - (int) (model.getApPerformance().getFreeMemory() * 100 / totalAvailableMemoryKb));
}
}
//we are using our own timestamp in here in case AP's time is out of sync - we do not want to raise connectivity alarm in that case
Long currentTs = System.currentTimeMillis();
metricReceivedTimestamps.put(currentTs, currentTs);
}
public void removeOldDataSamples() {
// remove samples older than timeBucketMs
long timeThresholdMs = System.currentTimeMillis() - timeBucketMs;
cpuTempSamples.entrySet().removeIf( t -> t.getKey() < timeThresholdMs );
cpuUtilSamples.entrySet().removeIf( t -> t.getKey() < timeThresholdMs );
memoryUtilSamples.entrySet().removeIf( t -> t.getKey() < timeThresholdMs );
metricReceivedTimestamps.entrySet().removeIf( t -> t.getKey() < timeThresholdMs );
}
public boolean isAlarmNeedsToBeRaised(AlarmCode alarmCode) {
if(existingAlarms.containsKey(alarmCode) || System.currentTimeMillis() < contextCreationTimestampMs + timeBucketMs) {
//no need to check for thresholds - alarm is either already present, or it is too early to tell because the first time bucket has not been filled yet
return false;
}
boolean ret = false;
AtomicInteger sum = new AtomicInteger();
AtomicInteger count = new AtomicInteger();
//check alarms against thresholds
if(alarmCode.getId() == AlarmCode.NoMetricsReceived.getId()) {
ret = metricReceivedTimestamps.isEmpty();
} else if(alarmCode.getId() == AlarmCode.CPUTemperature.getId()) {
cpuTempSamples.values().forEach(v -> { sum.addAndGet(v); count.incrementAndGet(); });
if(count.get() > 0) {
int avg = sum.get() / count.get();
ret = avg >= temperatureThresholdInC ;
}
} else if(alarmCode.getId() == AlarmCode.CPUUtilization.getId()) {
cpuUtilSamples.values().forEach(v -> { sum.addAndGet(v); count.incrementAndGet(); });
if(count.get() > 0) {
int avg = sum.get() / count.get();
ret = avg >= cpuUtilThresholdPct ;
}
} else if(alarmCode.getId() == AlarmCode.MemoryUtilization.getId()) {
memoryUtilSamples.values().forEach(v -> { sum.addAndGet(v); count.incrementAndGet(); });
if(count.get() > 0) {
int avg = sum.get() / count.get();
ret = avg >= memoryUtilThresholdPct ;
}
}
return ret;
}
public boolean isAlarmNeedsToBeCleared(AlarmCode alarmCode) {
if(!existingAlarms.containsKey(alarmCode) || System.currentTimeMillis() < contextCreationTimestampMs + timeBucketMs) {
//no need to check for thresholds - alarm is either not present, or it is too early to tell because the first time bucket has not been filled yet
return false;
}
boolean ret = false;
AtomicInteger sum = new AtomicInteger();
AtomicInteger count = new AtomicInteger();
//check alarms against thresholds
if(alarmCode.getId() == AlarmCode.NoMetricsReceived.getId()) {
ret = !metricReceivedTimestamps.isEmpty();
} else if(alarmCode.getId() == AlarmCode.CPUTemperature.getId()) {
cpuTempSamples.values().forEach(v -> { sum.addAndGet(v); count.incrementAndGet(); });
if(count.get() > 0) {
int avg = sum.get() / count.get();
ret = avg < temperatureThresholdInC ;
} else {
//no new data available, but the alarm exists -> clear the alarm
ret = true;
}
} else if(alarmCode.getId() == AlarmCode.CPUUtilization.getId()) {
cpuUtilSamples.values().forEach(v -> { sum.addAndGet(v); count.incrementAndGet(); });
if(count.get() > 0) {
int avg = sum.get() / count.get();
ret = avg < cpuUtilThresholdPct ;
} else {
//no new data available, but the alarm exists -> clear the alarm
ret = true;
}
} else if(alarmCode.getId() == AlarmCode.MemoryUtilization.getId()) {
memoryUtilSamples.values().forEach(v -> { sum.addAndGet(v); count.incrementAndGet(); });
if(count.get() > 0) {
int avg = sum.get() / count.get();
ret = avg < memoryUtilThresholdPct ;
} else {
//no new data available, but the alarm exists -> clear the alarm
ret = true;
}
}
return ret;
}
}

View File

@@ -1,322 +0,0 @@
package com.telecominfraproject.wlan.streams.equipmentalarms;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import javax.annotation.PostConstruct;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import com.telecominfraproject.wlan.alarm.AlarmServiceInterface;
import com.telecominfraproject.wlan.alarm.models.Alarm;
import com.telecominfraproject.wlan.alarm.models.AlarmCode;
import com.telecominfraproject.wlan.alarm.models.AlarmDetails;
import com.telecominfraproject.wlan.alarm.models.AlarmScopeType;
import com.telecominfraproject.wlan.alarm.models.OriginatorType;
import com.telecominfraproject.wlan.core.model.json.BaseJsonModel;
import com.telecominfraproject.wlan.core.model.streams.QueuedStreamMessage;
import com.telecominfraproject.wlan.equipment.EquipmentServiceInterface;
import com.telecominfraproject.wlan.equipment.models.Equipment;
import com.telecominfraproject.wlan.servicemetric.apnode.models.ApNodeMetrics;
import com.telecominfraproject.wlan.servicemetric.models.ServiceMetric;
import com.telecominfraproject.wlan.servicemetric.models.ServiceMetricDetails;
import com.telecominfraproject.wlan.status.StatusServiceInterface;
import com.telecominfraproject.wlan.status.equipment.report.models.OperatingSystemPerformance;
import com.telecominfraproject.wlan.status.models.Status;
import com.telecominfraproject.wlan.status.models.StatusCode;
import com.telecominfraproject.wlan.status.models.StatusDataType;
import com.telecominfraproject.wlan.stream.StreamProcessor;
/**
* @author dtop
* <br> This stream processor is listening for APNodeMetrics, aggregating them in sliding windows of 5 minutes and raising/clearing alarms based on preconfigured thresholds.
* <br> "No metrics received" alarm is raised when no APNodeMetrics have been received for the equipment in the last interval, cleared when APNodeMetrics appear again
* <br> "Temperature too high" alarm is raised when average temperature over the last interval goes above the configured threshold of 80C, cleared when average temperature goes below the threshold
* <br> "CPU utilization is too high" alarm is raised when average CPU utilization on AP over the last interval goes above the configured threshold of 80%, cleared when average CPU utilization goes below the threshold
* <br> "Memory utilization is too high" alarm is raised when average RAM utilization on AP over the last interval goes above the configured threshold of 70%, cleared when average RAM utilization goes below the threshold
*
*/
@Component
public class EquipmentAlarmsProcessor extends StreamProcessor {
private static final Logger LOG = LoggerFactory.getLogger(EquipmentAlarmsProcessor.class);
@Value("${tip.wlan.wlanServiceMetricsTopic:wlan_service_metrics}")
private String wlanServiceMetricsTopic;
@Value("${tip.wlan.equipmentAlarmProcessor.timeBucketMs:300000}") //5 minutes aggregation buckets
private long timeBucketMs;
@Value("${tip.wlan.equipmentAlarmProcessor.checkAlarmsIntervalMs:15000}") //check for raising/clearing alarms every 15 seconds
private long checkAlarmsIntervalMs;
@Value("${tip.wlan.equipmentAlarmProcessor.temperatureThresholdInC:80}")
private int temperatureThresholdInC;
@Value("${tip.wlan.equipmentAlarmProcessor.cpuUtilThresholdPct:80}")
private int cpuUtilThresholdPct;
@Value("${tip.wlan.equipmentAlarmProcessor.memoryUtilThresholdPct:70}")
private int memoryUtilThresholdPct;
private final ConcurrentHashMap<Long, EquipmentAlarmsContext> contextPerEquipmentIdMap = new ConcurrentHashMap<>();
private final Set<AlarmCode> alarmCodeSet = new HashSet<>();
@Autowired
private AlarmServiceInterface alarmServiceInterface;
@Autowired
private StatusServiceInterface statusServiceInterface;
@Autowired
private EquipmentServiceInterface equipmentServiceInterface;
@Override
protected boolean acceptMessage(QueuedStreamMessage message) {
boolean ret = message.getTopic().equals(wlanServiceMetricsTopic);
if(ret && ( message.getModel() instanceof ServiceMetric) ) {
ServiceMetric sm = (ServiceMetric) message.getModel();
ret = ret &&
(
sm.getDetails() instanceof ApNodeMetrics
);
} else {
ret = false;
}
LOG.trace("acceptMessage {}", ret);
return ret;
}
@Override
protected void processMessage(QueuedStreamMessage message) {
ServiceMetric mdl = (ServiceMetric) message.getModel();
ServiceMetricDetails smd = mdl.getDetails();
LOG.debug("Processing {}", mdl);
switch ( smd.getClass().getSimpleName() ) {
case "ApNodeMetrics":
process(mdl.getCustomerId(), mdl.getCreatedTimestamp(), mdl.getEquipmentId(), (ApNodeMetrics) smd);
break;
default:
process(mdl);
}
}
private void process(int customerId, long timestamp, long equipmentId, ApNodeMetrics model) {
LOG.debug("Processing ApNodeMetrics");
//get context for the equipmentId
EquipmentAlarmsContext context = contextPerEquipmentIdMap.get(equipmentId);
if(context == null) {
//When creating EquipmentAlarmsContext - read currently raised alarms of the types we're interested, keep it in memory.
//Only this SP is responsible for raising/clearing those alarms for this particular equipment
List<Alarm> existingAlarms = alarmServiceInterface.get(customerId, Collections.singleton(equipmentId), alarmCodeSet);
//All alarms that are handled by this stream processor logically exist only once-per-alarmCode-per-equipment.
//Ensure that there is only one alarm per alarmCode per equipment (the latest one), remove all others.
//This is needed to recover from some corner-case scenarios that can happen with the distributed datastores (for example split-brain).
existingAlarms = cleanUpDuplicateAlarms(existingAlarms);
context = new EquipmentAlarmsContext(customerId, equipmentId, existingAlarms, timeBucketMs, temperatureThresholdInC, cpuUtilThresholdPct, memoryUtilThresholdPct);
context = contextPerEquipmentIdMap.putIfAbsent(equipmentId, context);
if(context == null) {
context = contextPerEquipmentIdMap.get(equipmentId);
}
}
//find out TotalAvailableMemory in kb, which is available as part of the OperatingSystemPerformance status object
//we look for it separately because this status may not be populated when the first service_metrics_collection_config are coming in
if(context.getTotalAvailableMemoryKb()==0L) {
Status osPerformanceStatus = statusServiceInterface.getOrNull(customerId, equipmentId, StatusDataType.OS_PERFORMANCE);
if(osPerformanceStatus!=null) {
OperatingSystemPerformance osPerformance = (OperatingSystemPerformance) osPerformanceStatus.getDetails();
if(osPerformance !=null && osPerformance.getTotalAvailableMemoryKb() > 0) {
context.setTotalAvailableMemoryKb(osPerformance.getTotalAvailableMemoryKb());
}
}
}
// Update counters on the context
context.addDataSamples(timestamp, model);
LOG.debug("Processed {}", model);
}
private List<Alarm> cleanUpDuplicateAlarms(List<Alarm> existingAlarms) {
Map<AlarmCode, Alarm> alarmsToKeep= new HashMap<>();
//find out the latest existing alarms for each alarmCode
existingAlarms.forEach(a -> {
Alarm eA = alarmsToKeep.get(a.getAlarmCode());
if(eA == null) {
eA = a;
alarmsToKeep.put(a.getAlarmCode(), a);
}
if(eA.getCreatedTimestamp() < a.getCreatedTimestamp() ) {
alarmsToKeep.put(a.getAlarmCode(), a);
}
});
List<Alarm> alarmsToRemove = new ArrayList<>(existingAlarms);
alarmsToRemove.removeAll(alarmsToKeep.values());
alarmsToRemove.forEach(a -> {
try {
alarmServiceInterface.delete(a.getCustomerId(), a.getEquipmentId(), a.getAlarmCode(), a.getCreatedTimestamp());
} catch(Exception e) {
LOG.debug("Alarm was already deleted: {}", a);
}
});
return new ArrayList<>(alarmsToKeep.values());
}
private void process(BaseJsonModel model) {
LOG.warn("Unprocessed model: {}", model);
}
@PostConstruct
private void postCreate() {
Thread equipmentAlarmsThread = new Thread( new Runnable() {
@Override
public void run() {
LOG.info("Starting equipmentAlarmsThread");
while(true) {
LOG.trace("Checking if alarms need to be raised");
//take a snapshot of existing contexts for this iteration of alarm checks
List<EquipmentAlarmsContext> contexts = new ArrayList<>(contextPerEquipmentIdMap.values());
HashSet<Long> equipmentIdsFromContexts = new HashSet<>();
contexts.forEach(ctx -> equipmentIdsFromContexts.add(ctx.getEquipmentId()));
//get a list of equipment records for the current contexts
HashSet<Long> existingEquipmentIds = new HashSet<>();
try {
List<Equipment> existingEquipment = equipmentServiceInterface.get(equipmentIdsFromContexts);
existingEquipment.forEach(e -> existingEquipmentIds.add(e.getId()));
} catch(Exception e) {
LOG.error("Error when retrieving existing equipment", e);
sleep(checkAlarmsIntervalMs);
continue;
}
for(EquipmentAlarmsContext context : contexts ) {
if(!existingEquipmentIds.contains(context.getEquipmentId())) {
//equipment was removed, let's delete the context and remove all existing alarms for that equipmentId
try {
contextPerEquipmentIdMap.remove(context.getEquipmentId());
alarmServiceInterface.delete(context.getCustomerId(), context.getEquipmentId());
} catch(Exception e) {
LOG.error("Error when removing stale alarms for deleted equipment", e);
}
//nothing else to do for this context
continue;
}
context.removeOldDataSamples();
alarmCodeSet.forEach(alarmCode -> {
try {
//check alarms against thresholds
//if alarm needs to be raised - check if it is currently present, and if not - raise it, and add it to the context
if(context.isAlarmNeedsToBeRaised(alarmCode)) {
Alarm alarm = new Alarm();
alarm.setCustomerId(context.getCustomerId());
alarm.setEquipmentId(context.getEquipmentId());
alarm.setAlarmCode(alarmCode);
alarm.setOriginatorType(OriginatorType.AP);
alarm.setSeverity(alarmCode.getSeverity());
alarm.setScopeType(AlarmScopeType.EQUIPMENT);
alarm.setScopeId("" + context.getEquipmentId());
AlarmDetails alarmDetails = new AlarmDetails();
alarmDetails.setMessage(alarmCode.getDescription());
alarmDetails.setAffectedEquipmentIds(Collections.singletonList(context.getEquipmentId()));
alarm.setDetails(alarmDetails);
alarm = alarmServiceInterface.create(alarm);
context.getExistingAlarms().put(alarmCode, alarm);
}
if(context.isAlarmNeedsToBeCleared(alarmCode)) {
//if alarm needs to be cleared - check if it is currently present, and if it is - clear it, and remove it from the context
Alarm alarm = context.getExistingAlarms().remove(alarmCode);
if(alarm!=null) {
//All alarms that are handled by this stream processor logically exist only once-per-alarmCode-per-equipment.
//In order to self-heal from the corner cases with the datastore where more than one alarm with the same alarmCode
// is raised per equipment (for example when the datastore experienced a split-brain scenario), we would remove
// all alarms with the specified alarmCode for this equipment.
//Most of the time the existingAlarms list below would contain only one alarm.
//
List<Alarm> existingAlarms = alarmServiceInterface.get(alarm.getCustomerId(), Collections.singleton(alarm.getEquipmentId()), Collections.singleton(alarmCode));
existingAlarms.forEach(a -> {
try {
alarmServiceInterface.delete(a.getCustomerId(), a.getEquipmentId(), a.getAlarmCode(), a.getCreatedTimestamp());
} catch(Exception e) {
LOG.debug("Alarm was already deleted: {}", alarm);
}
});
}
}
} catch(Exception e) {
LOG.error("Error when processing context for customer {}", context.getCustomerId(), e);
}
});
}
LOG.trace("Done alarms check");
sleep(checkAlarmsIntervalMs);
}
}
}, "equipmentAlarmsThread");
equipmentAlarmsThread.setDaemon(true);
equipmentAlarmsThread.start();
//populate alarm codes this SP is responsible for
alarmCodeSet.add(AlarmCode.NoMetricsReceived);
alarmCodeSet.add(AlarmCode.CPUTemperature);
alarmCodeSet.add(AlarmCode.CPUUtilization);
alarmCodeSet.add(AlarmCode.MemoryUtilization);
}
private static void sleep(long ms) {
try {
Thread.sleep(ms);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}

View File

@@ -1,342 +0,0 @@
package com.telecominfraproject.wlan.streams.equipmentalarms;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.test.context.junit4.SpringRunner;
import com.telecominfraproject.wlan.alarm.AlarmServiceInterface;
import com.telecominfraproject.wlan.alarm.AlarmServiceLocal;
import com.telecominfraproject.wlan.alarm.controller.AlarmController;
import com.telecominfraproject.wlan.alarm.datastore.inmemory.AlarmDatastoreInMemory;
import com.telecominfraproject.wlan.alarm.models.Alarm;
import com.telecominfraproject.wlan.alarm.models.AlarmCode;
import com.telecominfraproject.wlan.cloudeventdispatcher.CloudEventDispatcherEmpty;
import com.telecominfraproject.wlan.core.model.equipment.EquipmentType;
import com.telecominfraproject.wlan.equipment.EquipmentServiceInterface;
import com.telecominfraproject.wlan.equipment.EquipmentServiceLocal;
import com.telecominfraproject.wlan.equipment.controller.EquipmentController;
import com.telecominfraproject.wlan.equipment.datastore.inmemory.EquipmentDatastoreInMemory;
import com.telecominfraproject.wlan.equipment.models.Equipment;
import com.telecominfraproject.wlan.servicemetric.apnode.models.ApNodeMetrics;
import com.telecominfraproject.wlan.servicemetric.apnode.models.ApPerformance;
import com.telecominfraproject.wlan.servicemetric.models.ServiceMetric;
import com.telecominfraproject.wlan.status.StatusServiceLocal;
import com.telecominfraproject.wlan.status.controller.StatusController;
import com.telecominfraproject.wlan.status.datastore.inmemory.StatusDatastoreInMemory;
import com.telecominfraproject.wlan.stream.StreamInterface;
import com.telecominfraproject.wlan.stream.StreamMessageDispatcher;
import com.telecominfraproject.wlan.streams.simple.SimpleStreamsConfig;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.NONE, classes = EquipmentAlarmsProcessor.class)
@Import(value = { EquipmentAlarmsProcessor.class, SimpleStreamsConfig.class, StreamMessageDispatcher.class,
AlarmServiceLocal.class, AlarmController.class, AlarmDatastoreInMemory.class,
StatusServiceLocal.class, StatusController.class, StatusDatastoreInMemory.class,
EquipmentServiceLocal.class, EquipmentController.class, EquipmentDatastoreInMemory.class,
CloudEventDispatcherEmpty.class,
//EquipmentAlarmsProcessorTests.Config.class,
})
@Ignore("make these tests more robust, there are intermittent failures")
/*
expected: <0> but was: <1>
org.opentest4j.AssertionFailedError: expected: <0> but was: <1>
at com.telecominfraproject.wlan.streams.equipmentalarms.EquipmentAlarmsProcessorTests.testAccessPointIsUnreachableAlarm(EquipmentAlarmsProcessorTests.java:313)
*/
public class EquipmentAlarmsProcessorTests {
private static final long testTimeBucketMs = 200;
private static final long testCheckAlarmsIntervalMs = 50;
static {
System.setProperty("tip.wlan.equipmentAlarmProcessor.checkAlarmsIntervalMs", "" + testCheckAlarmsIntervalMs);
System.setProperty("tip.wlan.equipmentAlarmProcessor.timeBucketMs", "" + testTimeBucketMs);
}
@Autowired @Qualifier("metricStreamInterface")
StreamInterface<ServiceMetric> metricStreamInterface;
@Autowired
EquipmentAlarmsProcessor equipmentAlarmsProcessor;
@Autowired
AlarmServiceInterface alarmService;
@Autowired
EquipmentServiceInterface equipmentService;
protected static final AtomicLong testSequence = new AtomicLong(1);
@Configuration
public static class Config {
//Another way of configuring dependencies (instead of mentioning them in the pom.xml with the test scope) :
// @Bean
// AlarmServiceInterface getAlarmServiceInterface() {
// return new AlarmServiceInterface() {
// ...
// };
// }
// @Bean
// StatusServiceInterface getStatusServiceInterface() {
// return new StatusServiceInterface() {
// ...
// };
// }
}
@Test
public void testCPUTemperatureAlarm() {
int customerId = getNextCustomerId();
Equipment equipment = new Equipment();
equipment.setCustomerId(customerId);
equipment.setEquipmentType(EquipmentType.AP);
equipment.setInventoryId("testCPUTemperatureAlarm");
equipment.setName(equipment.getInventoryId());
equipment = equipmentService.create(equipment);
long equipmentId = equipment.getId();
ServiceMetric record = new ServiceMetric(customerId , equipmentId );
//create metric a bit in the future so that it gets picked up by the processor and not simply discarded
record.setCreatedTimestamp(System.currentTimeMillis() + 2 * testTimeBucketMs);
ApNodeMetrics apNodeMetrics = new ApNodeMetrics();
record.setDetails(apNodeMetrics);
ApPerformance apPerformance = new ApPerformance();
apNodeMetrics.setApPerformance(apPerformance);
//we will force the CPUTemperature alarm to be raised
apPerformance.setCpuTemperature(85);
apPerformance.setCpuUtilized(new int[] { 70, 70 });
apPerformance.setFreeMemory(30000000);
//publish metric that should trigger alarm for the CPU Temperature
metricStreamInterface.publish(record );
//wait for the metric to be processed
sleep(2 * testTimeBucketMs);
//verify that alarm was raised
List<Alarm> alarms = alarmService.get(customerId, Collections.singleton(equipmentId), Collections.singleton(AlarmCode.CPUTemperature));
assertEquals(1, alarms.size());
//Now create a metric that should clear the alarm
ServiceMetric recordToClearAlarm = record.clone();
recordToClearAlarm.setCreatedTimestamp(System.currentTimeMillis() + 2* testTimeBucketMs );
((ApNodeMetrics)recordToClearAlarm.getDetails()).getApPerformance().setCpuTemperature(70);
//publish metric that should clear the alarm for the CPU Temperature
metricStreamInterface.publish(recordToClearAlarm);
//wait for the metric to be processed
sleep(2 * testTimeBucketMs);
//verify that alarm was cleared
alarms = alarmService.get(customerId, Collections.singleton(equipmentId), Collections.singleton(AlarmCode.CPUTemperature));
assertEquals(0, alarms.size());
}
@Test
public void testCPUTemperatureAlarm_NoEquipment() {
int customerId = getNextCustomerId();
long equipmentId = -5;
ServiceMetric record = new ServiceMetric(customerId , equipmentId );
//create metric a bit in the future so that it gets picked up by the processor and not simply discarded
record.setCreatedTimestamp(System.currentTimeMillis() + 2 * testTimeBucketMs);
ApNodeMetrics apNodeMetrics = new ApNodeMetrics();
record.setDetails(apNodeMetrics);
ApPerformance apPerformance = new ApPerformance();
apNodeMetrics.setApPerformance(apPerformance);
//we will force the CPUTemperature alarm to be raised
apPerformance.setCpuTemperature(85);
apPerformance.setCpuUtilized(new int[] { 70, 70 });
apPerformance.setFreeMemory(30000000);
//publish metric that should trigger alarm for the CPU Temperature
metricStreamInterface.publish(record );
//wait for the metric to be processed
sleep(2 * testTimeBucketMs);
//verify that alarm was not raised - because equipment for that alarm does not exist
List<Alarm> alarms = alarmService.get(customerId, Collections.singleton(equipmentId), Collections.singleton(AlarmCode.CPUTemperature));
assertEquals(0, alarms.size());
}
@Test
public void testCPUUtilizationAlarm() {
int customerId = getNextCustomerId();
Equipment equipment = new Equipment();
equipment.setCustomerId(customerId);
equipment.setEquipmentType(EquipmentType.AP);
equipment.setInventoryId("testCPUUtilizationAlarm");
equipment.setName(equipment.getInventoryId());
equipment = equipmentService.create(equipment);
long equipmentId = equipment.getId();
ServiceMetric record = new ServiceMetric(customerId , equipmentId );
//create metric a bit in the future so that it gets picked up by the processor and not simply discarded
record.setCreatedTimestamp(System.currentTimeMillis() + 2 * testTimeBucketMs);
ApNodeMetrics apNodeMetrics = new ApNodeMetrics();
record.setDetails(apNodeMetrics);
ApPerformance apPerformance = new ApPerformance();
apNodeMetrics.setApPerformance(apPerformance);
apPerformance.setCpuTemperature(55);
//we will force the CPUUtilization alarm to be raised
apPerformance.setCpuUtilized(new int[] { 90, 90 });
apPerformance.setFreeMemory(30000000);
//publish metric that should trigger alarm for the CPU Utilization
metricStreamInterface.publish(record );
//wait for the metric to be processed
sleep(2 * testTimeBucketMs);
//verify that alarm was raised
List<Alarm> alarms = alarmService.get(customerId, Collections.singleton(equipmentId), Collections.singleton(AlarmCode.CPUUtilization));
assertEquals(1, alarms.size());
//Now create a metric that should clear the alarm
ServiceMetric recordToClearAlarm = record.clone();
recordToClearAlarm.setCreatedTimestamp(System.currentTimeMillis() + 2* testTimeBucketMs );
((ApNodeMetrics)recordToClearAlarm.getDetails()).getApPerformance().setCpuUtilized(new int[] { 50, 50 });
//publish metric that should clear the alarm for the CPU Utilization
metricStreamInterface.publish(recordToClearAlarm);
//wait for the metric to be processed
sleep(2 * testTimeBucketMs);
//verify that alarm was cleared
alarms = alarmService.get(customerId, Collections.singleton(equipmentId), Collections.singleton(AlarmCode.CPUUtilization));
assertEquals(0, alarms.size());
}
@Test
public void testAccessPointIsUnreachableAlarm() {
int customerId = getNextCustomerId();
Equipment equipment = new Equipment();
equipment.setCustomerId(customerId);
equipment.setEquipmentType(EquipmentType.AP);
equipment.setInventoryId("testAccessPointIsUnreachableAlarm");
equipment.setName(equipment.getInventoryId());
equipment = equipmentService.create(equipment);
long equipmentId = equipment.getId();
ServiceMetric record = new ServiceMetric(customerId , equipmentId );
//create metric a bit in the future so that it gets picked up by the processor and not simply discarded
record.setCreatedTimestamp(System.currentTimeMillis() + testTimeBucketMs);
ApNodeMetrics apNodeMetrics = new ApNodeMetrics();
record.setDetails(apNodeMetrics);
ApPerformance apPerformance = new ApPerformance();
apNodeMetrics.setApPerformance(apPerformance);
apPerformance.setCpuTemperature(55);
//we will force the CPUUtilization alarm to be raised
apPerformance.setCpuUtilized(new int[] { 50, 50 });
apPerformance.setFreeMemory(30000000);
//publish metric that should not trigger AccessPointIsUnreachable alarm
metricStreamInterface.publish(record );
//wait for the metric to be processed
sleep(testTimeBucketMs);
//verify that alarm was not raised
List<Alarm> alarms = alarmService.get(customerId, Collections.singleton(equipmentId), Collections.singleton(AlarmCode.AccessPointIsUnreachable));
assertEquals(0, alarms.size());
//Now wait for the alarm to be raised because no service_metrics_collection_config were posted
sleep(testTimeBucketMs);
//verify that alarm was raised
for(int i = 0; i < 50; i++) {
alarms = alarmService.get(customerId, Collections.singleton(equipmentId), Collections.singleton(AlarmCode.AccessPointIsUnreachable));
if(!alarms.isEmpty()) {
break;
}else {
sleep(5);
}
}
assertEquals(1, alarms.size());
//Now create a metric that should clear the alarm
ServiceMetric recordToClearAlarm = record.clone();
recordToClearAlarm.setCreatedTimestamp(System.currentTimeMillis() + testTimeBucketMs );
//publish metric that should clear the AccessPointIsUnreachable alarm
metricStreamInterface.publish(recordToClearAlarm);
//wait for the metric to be processed
sleep(testTimeBucketMs);
//verify that alarm was cleared
for(int i = 0; i < 50; i++) {
alarms = alarmService.get(customerId, Collections.singleton(equipmentId), Collections.singleton(AlarmCode.AccessPointIsUnreachable));
if(alarms.isEmpty()) {
break;
}else {
sleep(5);
}
}
assertEquals(0, alarms.size());
}
public int getNextCustomerId() {
return (int) testSequence.incrementAndGet();
}
public long getNextEquipmentId() {
return testSequence.incrementAndGet();
}
public void sleep(long ms) {
try {
Thread.sleep( ms );
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}

View File

@@ -1,46 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<conversionRule conversionWord="filteredStack"
converterClass="com.telecominfraproject.wlan.server.exceptions.logback.ExceptionCompressingConverter" />
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n%filteredStack%nopex</pattern>
<!-- See http://logback.qos.ch/manual/layouts.html for details -->
<!-- %ex{5} - add at the end to display only 5 levels of the exception stack trace -->
<!-- %nopex - add at the end to not display any of the exception stack traces -->
<!-- %ex{full} - add at the end to display all the levels of the exception stack trace -->
</encoder>
</appender>
<!--
details: http://logback.qos.ch/manual/configuration.html#auto_configuration
runtime configuration, if need to override the defaults:
-Dlogging.config=file:///home/ec2-user/opensync/logback.xml
for log configuration debugging - use
-Dlogback.statusListenerClass=ch.qos.logback.core.status.OnConsoleStatusListener
log levels:
OFF ERROR WARN INFO DEBUG TRACE
-->
<logger name="org.apache.catalina.startup.DigesterFactory" level="ERROR"/>
<logger name="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping" level="INFO"/>
<logger name="org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer" level="INFO"/>
<logger name="org.springframework.security.web.authentication.preauth" level="OFF"/>
<logger name="com.netflix.servo.tag.aws.AwsInjectableTag" level="OFF"/>
<logger name="com.telecominfraproject" level="WARN"/>
<!--
<logger name="com.telecominfraproject.wlan.streams.simple" level="TRACE"/>
<logger name="com.telecominfraproject.wlan.streams.equipmentalarms" level="TRACE"/>
-->
<root level="WARN">
<appender-ref ref="stdout"/>
</root>
</configuration>

View File

@@ -1,11 +1,14 @@
package com.telecominfraproject.wlan.equipmentgateway.models; package com.telecominfraproject.wlan.equipmentgateway.models;
import java.util.Objects;
import com.telecominfraproject.wlan.core.model.equipment.LEDColour; import com.telecominfraproject.wlan.core.model.equipment.LEDColour;
public class CEGWBlinkRequest extends EquipmentCommand { public class CEGWBlinkRequest extends EquipmentCommand {
private static final long serialVersionUID = 3464950479960821571L; private static final long serialVersionUID = 3464950479960821571L;
private boolean blinkAllLEDs;
private int numCycles; private int numCycles;
private int colour1DurationMs; private int colour1DurationMs;
private int colour2DurationMs; private int colour2DurationMs;
@@ -28,6 +31,14 @@ public class CEGWBlinkRequest extends EquipmentCommand {
public CEGWBlinkRequest() { public CEGWBlinkRequest() {
super(CEGWCommandType.BlinkRequest, null, 0); super(CEGWCommandType.BlinkRequest, null, 0);
} }
public boolean getBlinkAllLEDs() {
return this.blinkAllLEDs;
}
public void setBlinkAllLEDs(boolean blinkAllLEDs) {
this.blinkAllLEDs = blinkAllLEDs;
}
public int getNumCycles() { public int getNumCycles() {
return numCycles; return numCycles;
@@ -79,4 +90,25 @@ public class CEGWBlinkRequest extends EquipmentCommand {
} }
return false; return false;
} }
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + Objects.hash(blinkAllLEDs, colour1, colour1DurationMs, colour2, colour2DurationMs, numCycles);
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!super.equals(obj))
return false;
if (getClass() != obj.getClass())
return false;
CEGWBlinkRequest other = (CEGWBlinkRequest) obj;
return blinkAllLEDs == other.blinkAllLEDs && colour1 == other.colour1 && colour1DurationMs == other.colour1DurationMs && colour2 == other.colour2
&& colour2DurationMs == other.colour2DurationMs && numCycles == other.numCycles;
}
} }

View File

@@ -0,0 +1,13 @@
package com.telecominfraproject.wlan.equipmentgateway.models;
public class CEGWMostRecentStatsTimestamp extends CEGatewayCommand {
private static final long serialVersionUID = -9087897865195978158L;
public CEGWMostRecentStatsTimestamp() {
}
public CEGWMostRecentStatsTimestamp(CEGWCommandType commandType, String inventoryId, long equipmentId) {
super(commandType,inventoryId,equipmentId);
}
}

View File

@@ -346,6 +346,7 @@ components:
- off - off
CEGWBlinkRequest: CEGWBlinkRequest:
description: Turn all LEDs on the AP to blinking, or turn off. The blinkAllLEDs attribute is the only currently supported functionality on the AP.
allOf: allOf:
- $ref: '#/components/schemas/CEGWBaseCommand' - $ref: '#/components/schemas/CEGWBaseCommand'
properties: properties:
@@ -357,6 +358,8 @@ components:
type: string type: string
enum: enum:
- CEGWBlinkRequest - CEGWBlinkRequest
blinkAllLEDs:
type: boolean
colour1: colour1:
$ref: '#/components/schemas/LEDColour' $ref: '#/components/schemas/LEDColour'
colour2: colour2:
@@ -375,6 +378,7 @@ components:
inventoryId: inv-1 inventoryId: inv-1
model_type: CEGWBlinkRequest model_type: CEGWBlinkRequest
commandType: BlinkRequest commandType: BlinkRequest
blinkAllLEDs: true
colour1: blue colour1: blue
colour2: red colour2: red
colour1DurationMs: 1000 colour1DurationMs: 1000

View File

@@ -37,6 +37,7 @@ public abstract class CommonElementConfiguration extends EquipmentDetails implem
private AntennaType antennaType; private AntennaType antennaType;
private Boolean costSavingEventsEnabled; private Boolean costSavingEventsEnabled;
private NetworkForwardMode forwardMode; private NetworkForwardMode forwardMode;
private boolean blinkAllLEDs;
/** /**
* this constructor is used for CAMI only * this constructor is used for CAMI only
@@ -69,37 +70,33 @@ public abstract class CommonElementConfiguration extends EquipmentDetails implem
} }
@Override @Override
public boolean equals(Object obj) { public int hashCode() {
if (this == obj) { final int prime = 31;
return true; int result = super.hashCode();
} result = prime * result + Objects.hash(antennaType, blinkAllLEDs, costSavingEventsEnabled, deploymentType, deviceMode, deviceName, elementConfigVersion,
if (obj == null) { equipmentType, forwardMode, frameReportThrottleEnabled, gettingDNS, gettingIP, locallyConfigured, locallyConfiguredMgmtVlan, locationData,
return false; peerInfoList, staticDnsIp1, staticDnsIp2, staticIP, staticIpGw, staticIpMaskCidr, syntheticClientEnabled);
} return result;
}
if (!super.equals(obj)) { @Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!super.equals(obj))
return false; return false;
} if (getClass() != obj.getClass())
if (!(obj instanceof CommonElementConfiguration)) {
return false; return false;
}
CommonElementConfiguration other = (CommonElementConfiguration) obj; CommonElementConfiguration other = (CommonElementConfiguration) obj;
return this.antennaType == other.antennaType return antennaType == other.antennaType && blinkAllLEDs == other.blinkAllLEDs && Objects.equals(costSavingEventsEnabled, other.costSavingEventsEnabled)
&& Objects.equals(costSavingEventsEnabled, other.costSavingEventsEnabled) && deploymentType == other.deploymentType && deviceMode == other.deviceMode && Objects.equals(deviceName, other.deviceName)
&& this.deploymentType == other.deploymentType && this.deviceMode == other.deviceMode && Objects.equals(elementConfigVersion, other.elementConfigVersion) && Objects.equals(equipmentType, other.equipmentType)
&& Objects.equals(deviceName, other.deviceName) && forwardMode == other.forwardMode && Objects.equals(frameReportThrottleEnabled, other.frameReportThrottleEnabled)
&& Objects.equals(elementConfigVersion, other.elementConfigVersion) && gettingDNS == other.gettingDNS && gettingIP == other.gettingIP && locallyConfigured == other.locallyConfigured
&& this.equipmentType == other.equipmentType && this.forwardMode == other.forwardMode && locallyConfiguredMgmtVlan == other.locallyConfiguredMgmtVlan && Objects.equals(locationData, other.locationData)
&& Objects.equals(frameReportThrottleEnabled, other.frameReportThrottleEnabled) && Objects.equals(peerInfoList, other.peerInfoList) && Objects.equals(staticDnsIp1, other.staticDnsIp1)
&& this.gettingDNS == other.gettingDNS && this.gettingIP == other.gettingIP && Objects.equals(staticDnsIp2, other.staticDnsIp2) && Objects.equals(staticIP, other.staticIP) && Objects.equals(staticIpGw, other.staticIpGw)
&& this.locallyConfigured == other.locallyConfigured && Objects.equals(staticIpMaskCidr, other.staticIpMaskCidr) && Objects.equals(syntheticClientEnabled, other.syntheticClientEnabled);
&& this.locallyConfiguredMgmtVlan == other.locallyConfiguredMgmtVlan
&& Objects.equals(locationData, other.locationData) && Objects.equals(peerInfoList, other.peerInfoList)
&& Objects.equals(staticDnsIp1, other.staticDnsIp1) && Objects.equals(staticDnsIp2, other.staticDnsIp2)
&& Objects.equals(staticIP, other.staticIP) && Objects.equals(staticIpGw, other.staticIpGw)
&& Objects.equals(staticIpMaskCidr, other.staticIpMaskCidr)
&& Objects.equals(syntheticClientEnabled, other.syntheticClientEnabled);
} }
public AntennaType getAntennaType() { public AntennaType getAntennaType() {
@@ -189,14 +186,6 @@ public abstract class CommonElementConfiguration extends EquipmentDetails implem
return syntheticClientEnabled; return syntheticClientEnabled;
} }
@Override
public int hashCode() {
return Objects.hash(antennaType, costSavingEventsEnabled, deploymentType, deviceMode, deviceName,
elementConfigVersion, equipmentType, forwardMode, frameReportThrottleEnabled, gettingDNS, gettingIP,
locallyConfigured, locallyConfiguredMgmtVlan, locationData, peerInfoList, staticDnsIp1, staticDnsIp2,
staticIP, staticIpGw, staticIpMaskCidr, syntheticClientEnabled);
}
@Override @Override
public boolean hasUnsupportedValue() { public boolean hasUnsupportedValue() {
if (super.hasUnsupportedValue()) { if (super.hasUnsupportedValue()) {
@@ -311,4 +300,14 @@ public abstract class CommonElementConfiguration extends EquipmentDetails implem
public void setSyntheticClientEnabled(Boolean syntheticClientEnabled) { public void setSyntheticClientEnabled(Boolean syntheticClientEnabled) {
this.syntheticClientEnabled = syntheticClientEnabled; this.syntheticClientEnabled = syntheticClientEnabled;
} }
public boolean isBlinkAllLEDs() {
return blinkAllLEDs;
}
public void setBlinkAllLEDs(boolean blinkAllLEDs) {
this.blinkAllLEDs = blinkAllLEDs;
}
} }

View File

@@ -118,33 +118,40 @@ public class EquipmentRrmBulkUpdateItem extends BaseJsonModel {
finalDetails.getRadioMap().put(rt, erc); finalDetails.getRadioMap().put(rt, erc);
} }
if(erc.getManualChannelNumber()== null || erc.getManualChannelNumber().intValue() != updateDetails.getChannelNumber()) { if(erc.getManualChannelNumber() == null
|| erc.getManualChannelNumber().intValue() != updateDetails.getChannelNumber()) {
erc.setManualChannelNumber(updateDetails.getChannelNumber()); erc.setManualChannelNumber(updateDetails.getChannelNumber());
modelChanged.set(true); modelChanged.set(true);
} }
if(erc.getManualBackupChannelNumber()== null || if(erc.getManualBackupChannelNumber() == null
erc.getManualBackupChannelNumber().intValue() != updateDetails.getBackupChannelNumber()) { || erc.getManualBackupChannelNumber().intValue() != updateDetails.getBackupChannelNumber()) {
erc.setManualBackupChannelNumber(updateDetails.getBackupChannelNumber()); erc.setManualBackupChannelNumber(updateDetails.getBackupChannelNumber());
modelChanged.set(true); modelChanged.set(true);
} }
if ((erc.getClientDisconnectThresholdDb() == null && updateDetails.getClientDisconnectThresholdDb() != null) if (updateDetails.getClientDisconnectThresholdDb() != null) {
|| !erc.getClientDisconnectThresholdDb().equals(updateDetails.getClientDisconnectThresholdDb())) { if ((erc.getClientDisconnectThresholdDb() == null && updateDetails.getClientDisconnectThresholdDb() != null)
erc.setClientDisconnectThresholdDb(updateDetails.getClientDisconnectThresholdDb()); || !erc.getClientDisconnectThresholdDb().equals(updateDetails.getClientDisconnectThresholdDb())) {
modelChanged.set(true); erc.setClientDisconnectThresholdDb(updateDetails.getClientDisconnectThresholdDb());
modelChanged.set(true);
}
} }
if ((erc.getProbeResponseThresholdDb() == null && updateDetails.getProbeResponseThresholdDb() != null) if (updateDetails.getProbeResponseThresholdDb() != null) {
|| !erc.getProbeResponseThresholdDb().equals(updateDetails.getProbeResponseThresholdDb())) { if ((erc.getProbeResponseThresholdDb() == null && updateDetails.getProbeResponseThresholdDb() != null)
erc.setProbeResponseThresholdDb(updateDetails.getProbeResponseThresholdDb()); || !erc.getProbeResponseThresholdDb().equals(updateDetails.getProbeResponseThresholdDb())) {
modelChanged.set(true); erc.setProbeResponseThresholdDb(updateDetails.getProbeResponseThresholdDb());
modelChanged.set(true);
}
} }
if ((erc.getRxCellSizeDb() == null && updateDetails.getRxCellSizeDb() != null) if (updateDetails.getRxCellSizeDb() != null) {
|| !erc.getRxCellSizeDb().equals(updateDetails.getRxCellSizeDb())) { if ((erc.getRxCellSizeDb() == null && updateDetails.getRxCellSizeDb() != null)
erc.setRxCellSizeDb(updateDetails.getRxCellSizeDb()); || !erc.getRxCellSizeDb().equals(updateDetails.getRxCellSizeDb())) {
modelChanged.set(true); erc.setRxCellSizeDb(updateDetails.getRxCellSizeDb());
modelChanged.set(true);
}
} }

View File

@@ -0,0 +1,18 @@
package com.telecominfraproject.wlan.equipment.models.events;
import com.telecominfraproject.wlan.equipment.models.Equipment;
public class EquipmentBlinkLEDsEvent extends EquipmentChangedEvent {
private static final long serialVersionUID = 5222048279956123654L;
public EquipmentBlinkLEDsEvent(Equipment equipment){
super(equipment);
setEquipmentChangeType(EquipmentChangeType.blinkLEDs);
}
/**
* Constructor used by JSON
*/
private EquipmentBlinkLEDsEvent() {
super();
}
}

View File

@@ -10,11 +10,11 @@ import com.telecominfraproject.wlan.core.model.json.JsonDeserializationUtils;
public enum EquipmentChangeType { public enum EquipmentChangeType {
All(0), ChannelsOnly(1), CellSizeAttributesOnly(2), ApImpacting(3), UNSUPPORTED(-1); All(0), ChannelsOnly(1), CellSizeAttributesOnly(2), ApImpacting(3), blinkLEDs(4), CustomerOnly(5), UNSUPPORTED(-1);
private final int id; private final int id;
private static final Map<Integer, EquipmentChangeType> ELEMENTS = new HashMap<>(); private static final Map<Integer, EquipmentChangeType> ELEMENTS = new HashMap<>();
private static final EquipmentChangeType validValues[] = { All, ChannelsOnly, CellSizeAttributesOnly, ApImpacting}; private static final EquipmentChangeType validValues[] = { All, ChannelsOnly, CellSizeAttributesOnly, ApImpacting,blinkLEDs};
private EquipmentChangeType(int id) { private EquipmentChangeType(int id) {
this.id = id; this.id = id;

View File

@@ -0,0 +1,41 @@
package com.telecominfraproject.wlan.equipment.models.events;
import com.telecominfraproject.wlan.equipment.models.Equipment;
public class EquipmentCustomerChangedEvent extends EquipmentChangedEvent {
private static final long serialVersionUID = 4650302079238674307L;
private Equipment existingEquipment; // old equipment
private Equipment equipment; // new configured equipment
public EquipmentCustomerChangedEvent(Equipment existingEquipment, Equipment equipment) {
super(equipment);
setEquipmentChangeType(EquipmentChangeType.CustomerOnly);
this.setExistingEquipment(existingEquipment);
this.setEquipment(equipment);
}
/**
* Constructor used by JSON
*/
@SuppressWarnings("unused")
private EquipmentCustomerChangedEvent() {
super();
}
public Equipment getExistingEquipment() {
return existingEquipment;
}
public void setExistingEquipment(Equipment existingEquipment) {
this.existingEquipment = existingEquipment;
}
public Equipment getEquipment() {
return equipment;
}
public void setEquipment(Equipment equipment) {
this.equipment = equipment;
}
}

View File

@@ -1,57 +1,58 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <project xmlns="http://maven.apache.org/POM/4.0.0"
<modelVersion>4.0.0</modelVersion> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<parent> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<groupId>com.telecominfraproject.wlan</groupId> <modelVersion>4.0.0</modelVersion>
<artifactId>tip-wlan-cloud-root-pom</artifactId> <parent>
<version>1.2.0-SNAPSHOT</version> <groupId>com.telecominfraproject.wlan</groupId>
<relativePath>../../wlan-cloud-root</relativePath> <artifactId>tip-wlan-cloud-root-pom</artifactId>
</parent> <version>1.2.0-SNAPSHOT</version>
<relativePath>../../wlan-cloud-root</relativePath>
</parent>
<artifactId>equipment-service-remote</artifactId> <artifactId>equipment-service-remote</artifactId>
<name>equipment-service-remote</name> <name>equipment-service-remote</name>
<description>Remote client for accessing the service, uses REST API calls.</description> <description>Remote client for accessing the service, uses REST API calls.</description>
<dependencies>
<dependency>
<artifactId>equipment-service-interface</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
</dependency>
<dependency>
<artifactId>base-client</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
</dependency>
<!-- Dependencies for the unit tests --> <dependencies>
<dependency> <dependency>
<artifactId>base-remote-tests</artifactId> <artifactId>equipment-service-interface</artifactId>
<groupId>com.telecominfraproject.wlan</groupId> <groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version> <version>1.2.0-SNAPSHOT</version>
<scope>test</scope> </dependency>
</dependency>
<dependency>
<artifactId>equipment-service</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependency> <dependency>
<artifactId>equipment-datastore-inmemory</artifactId> <artifactId>base-client</artifactId>
<groupId>com.telecominfraproject.wlan</groupId> <groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version> <version>1.2.0-SNAPSHOT</version>
<scope>test</scope> </dependency>
</dependency>
<dependency> <!-- Dependencies for the unit tests -->
<artifactId>cloud-event-dispatcher-empty</artifactId> <dependency>
<groupId>com.telecominfraproject.wlan</groupId> <artifactId>base-remote-tests</artifactId>
<version>1.2.0-SNAPSHOT</version> <groupId>com.telecominfraproject.wlan</groupId>
<scope>test</scope> <version>1.2.0-SNAPSHOT</version>
</dependency> <scope>test</scope>
</dependency>
</dependencies> <dependency>
<artifactId>equipment-service</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependency>
<artifactId>equipment-datastore-inmemory</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependency>
<artifactId>cloud-event-dispatcher-empty</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
</dependencies>
</project> </project>

View File

@@ -1,53 +1,59 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <project xmlns="http://maven.apache.org/POM/4.0.0"
<modelVersion>4.0.0</modelVersion> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<parent> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<groupId>com.telecominfraproject.wlan</groupId> <modelVersion>4.0.0</modelVersion>
<artifactId>tip-wlan-cloud-root-pom</artifactId> <parent>
<version>1.2.0-SNAPSHOT</version> <groupId>com.telecominfraproject.wlan</groupId>
<relativePath>../../wlan-cloud-root</relativePath> <artifactId>tip-wlan-cloud-root-pom</artifactId>
</parent> <version>1.2.0-SNAPSHOT</version>
<relativePath>../../wlan-cloud-root</relativePath>
</parent>
<artifactId>equipment-service</artifactId> <artifactId>equipment-service</artifactId>
<name>equipment-service</name> <name>equipment-service</name>
<description>Server side implementation of the service.</description> <description>Server side implementation of the service.</description>
<dependencies>
<dependency>
<artifactId>base-container</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
</dependency>
<dependency>
<artifactId>cloud-event-dispatcher-interface</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
</dependency>
<dependency>
<artifactId>equipment-models</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
</dependency>
<dependency>
<artifactId>equipment-datastore-interface</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
</dependency>
<dependency>
<artifactId>equipment-datastore-inmemory</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependencies>
<dependency>
<artifactId>alarm-service-interface</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
</dependency>
<dependency> <dependency>
<artifactId>cloud-event-dispatcher-empty</artifactId> <artifactId>base-container</artifactId>
<groupId>com.telecominfraproject.wlan</groupId> <groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version> <version>1.2.0-SNAPSHOT</version>
<scope>test</scope> </dependency>
</dependency>
</dependencies> <dependency>
<artifactId>cloud-event-dispatcher-interface</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
</dependency>
<dependency>
<artifactId>equipment-models</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
</dependency>
<dependency>
<artifactId>equipment-datastore-interface</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
</dependency>
<dependency>
<artifactId>equipment-datastore-inmemory</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependency>
<artifactId>cloud-event-dispatcher-empty</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
</dependencies>
</project> </project>

View File

@@ -47,14 +47,15 @@ import com.telecominfraproject.wlan.equipment.models.SourceSelectionMulticast;
import com.telecominfraproject.wlan.equipment.models.bulkupdate.rrm.EquipmentRrmBulkUpdateRequest; import com.telecominfraproject.wlan.equipment.models.bulkupdate.rrm.EquipmentRrmBulkUpdateRequest;
import com.telecominfraproject.wlan.equipment.models.events.EquipmentAddedEvent; import com.telecominfraproject.wlan.equipment.models.events.EquipmentAddedEvent;
import com.telecominfraproject.wlan.equipment.models.events.EquipmentApImpactingChangedEvent; import com.telecominfraproject.wlan.equipment.models.events.EquipmentApImpactingChangedEvent;
import com.telecominfraproject.wlan.equipment.models.events.EquipmentBlinkLEDsEvent;
import com.telecominfraproject.wlan.equipment.models.events.EquipmentCellSizeAttributesChangedEvent; import com.telecominfraproject.wlan.equipment.models.events.EquipmentCellSizeAttributesChangedEvent;
import com.telecominfraproject.wlan.equipment.models.events.EquipmentChangedEvent; import com.telecominfraproject.wlan.equipment.models.events.EquipmentChangedEvent;
import com.telecominfraproject.wlan.equipment.models.events.EquipmentChannelsChangedEvent; import com.telecominfraproject.wlan.equipment.models.events.EquipmentChannelsChangedEvent;
import com.telecominfraproject.wlan.equipment.models.events.EquipmentCustomerChangedEvent;
import com.telecominfraproject.wlan.equipment.models.events.EquipmentRemovedEvent; import com.telecominfraproject.wlan.equipment.models.events.EquipmentRemovedEvent;
import com.telecominfraproject.wlan.server.exceptions.ConfigurationException; import com.telecominfraproject.wlan.server.exceptions.ConfigurationException;
import com.telecominfraproject.wlan.systemevent.models.SystemEvent; import com.telecominfraproject.wlan.systemevent.models.SystemEvent;
/** /**
* @author dtoptygin * @author dtoptygin
* *
@@ -73,7 +74,6 @@ public class EquipmentController {
@Autowired private EquipmentDatastore equipmentDatastore; @Autowired private EquipmentDatastore equipmentDatastore;
@Autowired private CloudEventDispatcherInterface cloudEventDispatcher; @Autowired private CloudEventDispatcherInterface cloudEventDispatcher;
/** /**
* Creates new Equipment. * Creates new Equipment.
* *
@@ -280,18 +280,23 @@ public class EquipmentController {
LOG.debug("Updated Equipment {}", ret); LOG.debug("Updated Equipment {}", ret);
EquipmentChangedEvent event; EquipmentChangedEvent event;
if ((equipment.getProfileId() != existingEquipment.getProfileId()) || (existingApElementConfig != null && updatedApElementConfig != null && if (ret.getCustomerId() != existingEquipment.getCustomerId()) {
publishEvent(new EquipmentCustomerChangedEvent(existingEquipment, ret));
}
if ((ret.getProfileId() != existingEquipment.getProfileId()) || (existingApElementConfig != null && updatedApElementConfig != null &&
updatedApElementConfig.needsToBeUpdatedOnDevice(existingApElementConfig))) { updatedApElementConfig.needsToBeUpdatedOnDevice(existingApElementConfig))) {
event = new EquipmentApImpactingChangedEvent(ret); event = new EquipmentApImpactingChangedEvent(ret);
} else if (existingApElementConfig != null && existingApElementConfig.isBlinkAllLEDs() != updatedApElementConfig.isBlinkAllLEDs()) {
LOG.debug("Updated BlinkingLEDs {}", ret);
event = new EquipmentBlinkLEDsEvent(ret);
} else { } else {
event = new EquipmentChangedEvent(ret); event = new EquipmentChangedEvent(ret);
} }
publishEvent(event); publishEvent(event);
return ret; return ret;
} }
private void validateChannelNum(Equipment equipment) { private void validateChannelNum(Equipment equipment) {
if (equipment.getDetails() instanceof ApElementConfiguration) { if (equipment.getDetails() instanceof ApElementConfiguration) {
ApElementConfiguration apElementConfiguration = (ApElementConfiguration) equipment.getDetails(); ApElementConfiguration apElementConfiguration = (ApElementConfiguration) equipment.getDetails();

View File

@@ -220,6 +220,8 @@ components:
type: boolean type: boolean
forwardMode: forwardMode:
$ref: '#/components/schemas/NetworkForwardMode' $ref: '#/components/schemas/NetworkForwardMode'
blinkAllLEDs:
type: boolean
radioMap: radioMap:
$ref: '#/components/schemas/RadioMap' $ref: '#/components/schemas/RadioMap'
advancedRadioMap: advancedRadioMap:

View File

@@ -34,7 +34,7 @@ import com.telecominfraproject.wlan.equipment.models.Equipment;
EquipmentController.class, EquipmentController.class,
CloudEventDispatcherEmpty.class, CloudEventDispatcherEmpty.class,
EquipmentDatastoreInMemory.class, EquipmentDatastoreInMemory.class,
EquipmentControllerTest.Config.class, EquipmentControllerTest.Config.class
}) })
public class EquipmentControllerTest { public class EquipmentControllerTest {

View File

@@ -191,18 +191,18 @@ public class ManufacturerServiceRemoteTest extends BaseRemoteTest {
Set<String> ouiList = new HashSet<>(); Set<String> ouiList = new HashSet<>();
ouiList.add(oui1); ouiList.add(oui1);
ouiListSearchResult = remoteInterface.getManufacturerDetailsForOuiSet(ouiList); ouiListSearchResult = remoteInterface.getManufacturerDetailsForOuiSet(ouiList);
assertTrue(ouiListSearchResult.size() == 1); assertTrue(ouiListSearchResult.size() == 2);
assertTrue(ouiListSearchResult.get(oui1).equals(ret1)); assertTrue(ouiListSearchResult.get(oui1).equals(ret1));
ouiList.add(oui2); ouiList.add(oui2);
ouiListSearchResult = remoteInterface.getManufacturerDetailsForOuiSet(ouiList); ouiListSearchResult = remoteInterface.getManufacturerDetailsForOuiSet(ouiList);
assertTrue(ouiListSearchResult.size() == 2); assertTrue(ouiListSearchResult.size() == 3);
assertTrue(ouiListSearchResult.get(oui1).equals(ret1)); assertTrue(ouiListSearchResult.get(oui1).equals(ret1));
assertTrue(ouiListSearchResult.get(oui2).equals(ret2)); assertTrue(ouiListSearchResult.get(oui2).equals(ret2));
ouiList.add(oui3); ouiList.add(oui3);
ouiListSearchResult = remoteInterface.getManufacturerDetailsForOuiSet(ouiList); ouiListSearchResult = remoteInterface.getManufacturerDetailsForOuiSet(ouiList);
assertTrue(ouiListSearchResult.size() == 3); assertTrue(ouiListSearchResult.size() == 4);
assertTrue(ouiListSearchResult.get(oui1).equals(ret1)); assertTrue(ouiListSearchResult.get(oui1).equals(ret1));
assertTrue(ouiListSearchResult.get(oui2).equals(ret2)); assertTrue(ouiListSearchResult.get(oui2).equals(ret2));
assertTrue(ouiListSearchResult.get(oui3).equals(ret3)); assertTrue(ouiListSearchResult.get(oui3).equals(ret3));
@@ -211,7 +211,7 @@ public class ManufacturerServiceRemoteTest extends BaseRemoteTest {
ouiList.add(String.format("%06d", i)); ouiList.add(String.format("%06d", i));
} }
ouiListSearchResult = remoteInterface.getManufacturerDetailsForOuiSet(ouiList); ouiListSearchResult = remoteInterface.getManufacturerDetailsForOuiSet(ouiList);
assertEquals(3,ouiListSearchResult.size()); assertEquals(4,ouiListSearchResult.size());
assertTrue(ouiListSearchResult.get(oui1).equals(ret1)); assertTrue(ouiListSearchResult.get(oui1).equals(ret1));
assertTrue(ouiListSearchResult.get(oui2).equals(ret2)); assertTrue(ouiListSearchResult.get(oui2).equals(ret2));
assertTrue(ouiListSearchResult.get(oui3).equals(ret3)); assertTrue(ouiListSearchResult.get(oui3).equals(ret3));

View File

@@ -35,7 +35,10 @@ import com.telecominfraproject.wlan.manufacturer.models.ManufacturerOuiDetails;
public class ManufacturerController { public class ManufacturerController {
private static final Logger LOG = LoggerFactory.getLogger(ManufacturerController.class); private static final Logger LOG = LoggerFactory.getLogger(ManufacturerController.class);
private static final int GLOBE_BIT = (0x1 << 1);
private static final ManufacturerOuiDetails PRIVATE_MAC_RESPONSE = new ManufacturerOuiDetails();
@Autowired @Autowired
private ManufacturerDatastoreInterface manufacturerDatastore; private ManufacturerDatastoreInterface manufacturerDatastore;
@@ -43,6 +46,11 @@ public class ManufacturerController {
private static final long serialVersionUID = -8035392255039609079L; private static final long serialVersionUID = -8035392255039609079L;
} }
static {
PRIVATE_MAC_RESPONSE.setOui("ffffff");
PRIVATE_MAC_RESPONSE.setManufacturerName("Unknown (Private Address)");
PRIVATE_MAC_RESPONSE.setManufacturerAlias("Unknown");
}
@PostMapping(value = "/oui") @PostMapping(value = "/oui")
public ManufacturerOuiDetails createOuiDetails(@RequestBody ManufacturerOuiDetails ouiDetails) { public ManufacturerOuiDetails createOuiDetails(@RequestBody ManufacturerOuiDetails ouiDetails) {
LOG.debug("Creating OUI details {} ", ouiDetails); LOG.debug("Creating OUI details {} ", ouiDetails);
@@ -76,9 +84,7 @@ public class ManufacturerController {
@GetMapping(value = "/oui") @GetMapping(value = "/oui")
public ManufacturerOuiDetails getByOui(@RequestParam String oui) { public ManufacturerOuiDetails getByOui(@RequestParam String oui) {
LOG.debug("Retrieving OUI details for OUI {} ", oui); LOG.debug("Retrieving OUI details for OUI {} ", oui);
ManufacturerOuiDetails ret = isGlobalAddress(oui) ? manufacturerDatastore.getByOui(oui) : PRIVATE_MAC_RESPONSE;
ManufacturerOuiDetails ret = manufacturerDatastore.getByOui(oui);
LOG.debug("Retrieved OUI details {} ", ret); LOG.debug("Retrieved OUI details {} ", ret);
return ret; return ret;
} }
@@ -157,7 +163,11 @@ public class ManufacturerController {
public Map<String, ManufacturerOuiDetails> getManufacturerDetailsForOuiList( public Map<String, ManufacturerOuiDetails> getManufacturerDetailsForOuiList(
@RequestParam List<String> ouiList) { @RequestParam List<String> ouiList) {
LOG.debug("calling getManufacturerDetailsForOuiList "); LOG.debug("calling getManufacturerDetailsForOuiList ");
return manufacturerDatastore.getManufacturerDetailsForOuiList(ouiList); Map<String, ManufacturerOuiDetails> manufMap = manufacturerDatastore.getManufacturerDetailsForOuiList(ouiList);
ouiList.forEach(oui -> {if (!isGlobalAddress(oui)) manufMap.put(oui, PRIVATE_MAC_RESPONSE);});
manufMap.put(PRIVATE_MAC_RESPONSE.getOui(), PRIVATE_MAC_RESPONSE);
return manufMap;
} }
@PutMapping(value = "/oui/alias") @PutMapping(value = "/oui/alias")
@@ -180,4 +190,14 @@ public class ManufacturerController {
LOG.debug("Retrieving alias values that begin with {}", prefix); LOG.debug("Retrieving alias values that begin with {}", prefix);
return manufacturerDatastore.getAliasValuesThatBeginWith(prefix, maxResults); return manufacturerDatastore.getAliasValuesThatBeginWith(prefix, maxResults);
} }
private boolean isGlobalAddress(String oui) {
if (oui != null && oui.length() == 6) {
// we only need to check the first Byte of the OUI
Integer hex = Integer.parseInt(oui.substring(0, 2), 16);
byte firstByte = hex.byteValue();
return (firstByte & GLOBE_BIT) == 0;
}
return false;
}
} }

View File

@@ -118,6 +118,49 @@
<version>1.2.0-SNAPSHOT</version> <version>1.2.0-SNAPSHOT</version>
</dependency> </dependency>
<!-- test dependencies -->
<dependency>
<artifactId>equipment-service-local</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependency>
<artifactId>equipment-service</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependency>
<artifactId>equipment-datastore-inmemory</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependency>
<artifactId>cloud-event-dispatcher-empty</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependency>
<artifactId>profile-service-local</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependency>
<artifactId>profile-service</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependency>
<artifactId>profile-datastore-inmemory</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@@ -1,3 +1,4 @@
package com.telecominfraproject.wlan.portal.controller.equipmentgateway; package com.telecominfraproject.wlan.portal.controller.equipmentgateway;
import org.slf4j.Logger; import org.slf4j.Logger;
@@ -13,6 +14,7 @@ import com.telecominfraproject.wlan.core.model.json.GenericResponse;
import com.telecominfraproject.wlan.equipment.EquipmentServiceInterface; import com.telecominfraproject.wlan.equipment.EquipmentServiceInterface;
import com.telecominfraproject.wlan.equipment.models.Equipment; import com.telecominfraproject.wlan.equipment.models.Equipment;
import com.telecominfraproject.wlan.equipment.models.RadioChannelChangeSettings; import com.telecominfraproject.wlan.equipment.models.RadioChannelChangeSettings;
import com.telecominfraproject.wlan.equipmentgateway.models.CEGWBlinkRequest;
import com.telecominfraproject.wlan.equipmentgateway.models.CEGWCommandResultCode; import com.telecominfraproject.wlan.equipmentgateway.models.CEGWCommandResultCode;
import com.telecominfraproject.wlan.equipmentgateway.models.CEGWFirmwareDownloadRequest; import com.telecominfraproject.wlan.equipmentgateway.models.CEGWFirmwareDownloadRequest;
import com.telecominfraproject.wlan.equipmentgateway.models.CEGWNewChannelRequest; import com.telecominfraproject.wlan.equipmentgateway.models.CEGWNewChannelRequest;
@@ -30,7 +32,7 @@ import com.telecominfraproject.wlan.status.equipment.models.EquipmentResetMethod
*/ */
@RestController @RestController
@RequestMapping(value = "/portal") @RequestMapping(value = "/portal")
public class EquipmentGatewayPortalController { public class EquipmentGatewayPortalController {
private static final Logger LOG = LoggerFactory.getLogger(EquipmentGatewayPortalController.class); private static final Logger LOG = LoggerFactory.getLogger(EquipmentGatewayPortalController.class);
@@ -49,94 +51,113 @@ public class EquipmentGatewayPortalController {
Equipment equipment = equipmentServiceInterface.get(equipmentId); Equipment equipment = equipmentServiceInterface.get(equipmentId);
FirmwareVersion fwVersion = firmwareServiceInterface.getFirmwareVersion(firmwareVersionId); FirmwareVersion fwVersion = firmwareServiceInterface.getFirmwareVersion(firmwareVersionId);
CEGWFirmwareDownloadRequest fwDownloadRequest = new CEGWFirmwareDownloadRequest(equipment.getInventoryId(), CEGWFirmwareDownloadRequest fwDownloadRequest =
equipment.getId(), fwVersion.getVersionName(), fwVersion.getFilename()); new CEGWFirmwareDownloadRequest(equipment.getInventoryId(), equipment.getId(), fwVersion.getVersionName(), fwVersion.getFilename());
EquipmentCommandResponse response = equipmentGatewayServiceInterface.sendCommand(fwDownloadRequest); EquipmentCommandResponse response = equipmentGatewayServiceInterface.sendCommand(fwDownloadRequest);
LOG.debug("FW Download Response {}", response); LOG.debug("FW Download Response {}", response);
if(response.getResultCode() == CEGWCommandResultCode.Success) { if (response.getResultCode() == CEGWCommandResultCode.Success) {
return new GenericResponse(true,""); return new GenericResponse(true, "");
} else { } else {
return new GenericResponse(false, "Failed to request firmware update: "+ response.getResultCode() + " " + response.getResultDetail()); return new GenericResponse(false, "Failed to request firmware update: " + response.getResultCode() + " " + response.getResultDetail());
} }
} }
@RequestMapping(value = "/equipmentGateway/requestChannelChange", method = RequestMethod.POST) @RequestMapping(value = "/equipmentGateway/requestChannelChange", method = RequestMethod.POST)
public GenericResponse requestChannelChange(@RequestParam long equipmentId, @RequestBody RadioChannelChangeSettings radioChannelChangeSettings) { public GenericResponse requestChannelChange(@RequestParam long equipmentId, @RequestBody RadioChannelChangeSettings radioChannelChangeSettings) {
LOG.debug("requestChannelChange {} {}", equipmentId); LOG.debug("requestChannelChange {} {}", equipmentId);
Equipment equipment = equipmentServiceInterface.get(equipmentId); Equipment equipment = equipmentServiceInterface.get(equipmentId);
CEGWNewChannelRequest newChannelRequest = new CEGWNewChannelRequest(equipment.getInventoryId(), equipmentId, radioChannelChangeSettings.getBackupChannel(), radioChannelChangeSettings.getPrimaryChannel()); CEGWNewChannelRequest newChannelRequest = new CEGWNewChannelRequest(equipment.getInventoryId(), equipmentId,
radioChannelChangeSettings.getBackupChannel(), radioChannelChangeSettings.getPrimaryChannel());
EquipmentCommandResponse response = equipmentGatewayServiceInterface.sendCommand(newChannelRequest); EquipmentCommandResponse response = equipmentGatewayServiceInterface.sendCommand(newChannelRequest);
LOG.debug("Channel Change Response {}", response); LOG.debug("Channel Change Response {}", response);
if(response.getResultCode() == CEGWCommandResultCode.Success) { if (response.getResultCode() == CEGWCommandResultCode.Success) {
return new GenericResponse(true,""); return new GenericResponse(true, "");
} else { } else {
return new GenericResponse(false, "Failed to initiate channel change: "+ response.getResultCode() + " " + response.getResultDetail()); return new GenericResponse(false, "Failed to initiate channel change: " + response.getResultCode() + " " + response.getResultDetail());
} }
} }
@RequestMapping(value = "/equipmentGateway/requestApReboot", method = RequestMethod.POST) @RequestMapping(value = "/equipmentGateway/requestApReboot", method = RequestMethod.POST)
public GenericResponse requestApReboot(@RequestParam long equipmentId) { public GenericResponse requestApReboot(@RequestParam long equipmentId) {
LOG.debug("requestApReboot {}", equipmentId); LOG.debug("requestApReboot {}", equipmentId);
Equipment equipment = equipmentServiceInterface.get(equipmentId); Equipment equipment = equipmentServiceInterface.get(equipmentId);
// No config change, just plain reboot // No config change, just plain reboot
CEGWRebootRequest apRebootRequest = new CEGWRebootRequest(equipment.getInventoryId(), CEGWRebootRequest apRebootRequest = new CEGWRebootRequest(equipment.getInventoryId(), equipment.getId(), false, EquipmentResetMethod.NoReset);
equipment.getId(), false, EquipmentResetMethod.NoReset);
EquipmentCommandResponse response = equipmentGatewayServiceInterface.sendCommand(apRebootRequest); EquipmentCommandResponse response = equipmentGatewayServiceInterface.sendCommand(apRebootRequest);
LOG.debug("AP reboot response {}", response); LOG.debug("AP reboot response {}", response);
if(response.getResultCode() == CEGWCommandResultCode.Success) { if (response.getResultCode() == CEGWCommandResultCode.Success) {
return new GenericResponse(true,""); return new GenericResponse(true, "");
} else { } else {
return new GenericResponse(false, "Failed to trigger AP reboot: "+ response.getResultCode() + " " + response.getResultDetail()); return new GenericResponse(false, "Failed to trigger AP reboot: " + response.getResultCode() + " " + response.getResultDetail());
} }
} }
@RequestMapping(value = "/equipmentGateway/requestApSwitchSoftwareBank", method = RequestMethod.POST) @RequestMapping(value = "/equipmentGateway/requestApSwitchSoftwareBank", method = RequestMethod.POST)
public GenericResponse requestApSwitchSoftwareBank(@RequestParam long equipmentId) { public GenericResponse requestApSwitchSoftwareBank(@RequestParam long equipmentId) {
LOG.debug("requestApSwitchSoftwareBank {}", equipmentId); LOG.debug("requestApSwitchSoftwareBank {}", equipmentId);
Equipment equipment = equipmentServiceInterface.get(equipmentId); Equipment equipment = equipmentServiceInterface.get(equipmentId);
// Reboot, switch active/inactive software bank // Reboot, switch active/inactive software bank
CEGWRebootRequest apSwitchSoftwareBank = new CEGWRebootRequest(equipment.getInventoryId(), CEGWRebootRequest apSwitchSoftwareBank = new CEGWRebootRequest(equipment.getInventoryId(), equipment.getId(), true, EquipmentResetMethod.NoReset);
equipment.getId(), true, EquipmentResetMethod.NoReset);
EquipmentCommandResponse response = equipmentGatewayServiceInterface.sendCommand(apSwitchSoftwareBank); EquipmentCommandResponse response = equipmentGatewayServiceInterface.sendCommand(apSwitchSoftwareBank);
LOG.debug("AP switch software bank response {}", response); LOG.debug("AP switch software bank response {}", response);
if(response.getResultCode() == CEGWCommandResultCode.Success) { if (response.getResultCode() == CEGWCommandResultCode.Success) {
return new GenericResponse(true,""); return new GenericResponse(true, "");
} else { } else {
return new GenericResponse(false, "Failed to trigger AP switch software bank: "+ response.getResultCode() + " " + response.getResultDetail()); return new GenericResponse(false, "Failed to trigger AP switch software bank: " + response.getResultCode() + " " + response.getResultDetail());
} }
} }
@RequestMapping(value = "/equipmentGateway/requestApFactoryReset", method = RequestMethod.POST) @RequestMapping(value = "/equipmentGateway/requestApFactoryReset", method = RequestMethod.POST)
public GenericResponse requestApFactoryReset(@RequestParam long equipmentId) { public GenericResponse requestApFactoryReset(@RequestParam long equipmentId) {
LOG.debug("requestApFactoryReset {}", equipmentId); LOG.debug("requestApFactoryReset {}", equipmentId);
Equipment equipment = equipmentServiceInterface.get(equipmentId); Equipment equipment = equipmentServiceInterface.get(equipmentId);
// Reboot Ap with factory settings // Reboot Ap with factory settings
CEGWRebootRequest apFactoryReset = new CEGWRebootRequest(equipment.getInventoryId(), CEGWRebootRequest apFactoryReset = new CEGWRebootRequest(equipment.getInventoryId(), equipment.getId(), false, EquipmentResetMethod.FactoryReset);
equipment.getId(), false, EquipmentResetMethod.FactoryReset);
EquipmentCommandResponse response = equipmentGatewayServiceInterface.sendCommand(apFactoryReset); EquipmentCommandResponse response = equipmentGatewayServiceInterface.sendCommand(apFactoryReset);
LOG.debug("AP factory reset response {}", response); LOG.debug("AP factory reset response {}", response);
if(response.getResultCode() == CEGWCommandResultCode.Success) { if (response.getResultCode() == CEGWCommandResultCode.Success) {
return new GenericResponse(true,""); return new GenericResponse(true, "");
} else { } else {
return new GenericResponse(false, "Failed to trigger AP factory reset: "+ response.getResultCode() + " " + response.getResultDetail()); return new GenericResponse(false, "Failed to trigger AP factory reset: " + response.getResultCode() + " " + response.getResultDetail());
} }
} }
@RequestMapping(value = "/equipmentGateway/requestApBlinkLEDs", method = RequestMethod.POST)
public GenericResponse requestApBlinkLEDs(@RequestParam long equipmentId, @RequestParam boolean blinkAllLEDs) {
String action = "stop blinking LEDs on AP ";
if (blinkAllLEDs)
action = "start blinking LEDs on AP ";
Equipment equipment = equipmentServiceInterface.get(equipmentId);
LOG.debug("Request {} for AP {}", action, equipment.getInventoryId());
// Turn LEDs on Ap on or off based on blinkAllLEDs value
CEGWBlinkRequest apBlinkLEDs = new CEGWBlinkRequest(equipment.getInventoryId(), equipment.getId());
apBlinkLEDs.setBlinkAllLEDs(blinkAllLEDs);
EquipmentCommandResponse response = equipmentGatewayServiceInterface.sendCommand(apBlinkLEDs);
LOG.debug("{} response {}", action, response);
if (response.getResultCode() == CEGWCommandResultCode.Success) {
return new GenericResponse(true, "");
} else {
return new GenericResponse(false, "Failed to " + action + " for AP: " + response.getResultCode() + " " + response.getResultDetail());
}
}
} }

View File

@@ -158,55 +158,66 @@ public class ProfilePortalController {
} }
} }
@RequestMapping(value = "/profile/equipmentCounts", method = RequestMethod.GET) @RequestMapping(value = "/profile/equipmentCounts", method = RequestMethod.GET)
public ListOfPairLongLong getCountsOfEquipmentThatUseProfiles(@RequestParam Set<Long> profileIdSet) { public ListOfPairLongLong getCountsOfEquipmentThatUseProfiles(@RequestParam Set<Long> profileIdSet) {
LOG.debug("getCountsOfEquipmentThatUseProfiles({})", profileIdSet); LOG.debug("getCountsOfEquipmentThatUseProfiles({})", profileIdSet);
//first get top-level profiles for the supplied set - only top-level profiles are linked to equipment Map<Long, AtomicInteger> profileIdToCountMap = new HashMap<Long, AtomicInteger>();
List<PairLongLong> topLevelProfiles = this.profileServiceInterface.getTopLevelProfiles(profileIdSet); profileIdSet.forEach(profileId -> profileIdToCountMap.put(profileId, new AtomicInteger(0)));
//Maps child at all top level profiles that reference it. A top level profile references itself int this map
Map<Long, List<Long>> childProfileToTopProfileMap = new HashMap<Long, List<Long>>();
List<PairLongLong> topLevelProfileList = profileServiceInterface.getTopLevelProfiles(profileIdSet);
Set<Long> topProfileIdSet= new HashSet<Long>();
topLevelProfileList.forEach(pair ->
{
if (childProfileToTopProfileMap.putIfAbsent(
pair.getValue1(),
new ArrayList<Long>() {{ add(pair.getValue2());}}
) != null)
{
childProfileToTopProfileMap.compute(pair.getValue1(), (k,v) ->
new ArrayList<Long>() {{
addAll(v);
add(pair.getValue2());}});
}
topProfileIdSet.add(pair.getValue2());
});
Map<Long, AtomicInteger> topProfileToEquipmentCountMap = new HashMap<>();
topProfileIdSet.forEach(p -> topProfileToEquipmentCountMap.put(p, new AtomicInteger()));
PaginationContext<PairLongLong> context = new PaginationContext<>(500);
equipmentServiceInterface.getEquipmentIdsByProfileIds(topProfileIdSet, context);
while(!context.isLastPage()) {
PaginationResponse<PairLongLong> page = equipmentServiceInterface.getEquipmentIdsByProfileIds(topProfileIdSet, context );
context = page.getContext();
page.getItems().forEach(p -> {
AtomicInteger cnt = topProfileToEquipmentCountMap.get(p.getValue1());
if(cnt!=null) {
cnt.incrementAndGet();
}
});
LOG.debug("Page {} - counted {} equipmentids", context.getLastReturnedPageNumber(), context.getTotalItemsReturned());
}
// assemble profile count for return, using child to top level profile id map
childProfileToTopProfileMap.forEach((childKey,TopLevelIdList) ->
{
for (Long topProfileId : TopLevelIdList)
{
profileIdToCountMap.get(childKey).addAndGet(topProfileToEquipmentCountMap.get(topProfileId).get());
}
});
//package results to get equipment counts for the original profile ids
ListOfPairLongLong ret = new ListOfPairLongLong(); ListOfPairLongLong ret = new ListOfPairLongLong();
profileIdToCountMap.forEach((id, count) -> ret.add(new PairLongLong(id, count.get())));
//map each supplied profile to its top-level parent
Map<Long, Long> profileIdToTopProfileIdMap = new HashMap<>();
topLevelProfiles.forEach(pair -> profileIdToTopProfileIdMap.put(pair.getValue1(), pair.getValue2()));
//gather top-level profile ids
Set<Long> topProfileIds = new HashSet<>();
topLevelProfiles.forEach(pair -> topProfileIds.add(pair.getValue2()));
//TODO: this may be more efficiently done by a specialized count method on equipment datastore
//now get pages of equipmentIds that refer to the top-level profiles and count the equipmentIds
PaginationContext<PairLongLong> context = new PaginationContext<>(500);
this.equipmentServiceInterface.getEquipmentIdsByProfileIds(topProfileIds, context );
//prepare map of top-level profileId to the count of equipmentIds
Map<Long, AtomicInteger> topProfileIdToEquipmentCountsMap = new HashMap<>();
topProfileIds.forEach(p -> topProfileIdToEquipmentCountsMap.put(p, new AtomicInteger()));
while(!context.isLastPage()) {
PaginationResponse<PairLongLong> page = equipmentServiceInterface.getEquipmentIdsByProfileIds(topProfileIds, context );
context = page.getContext();
page.getItems().forEach(p -> {
AtomicInteger cnt = topProfileIdToEquipmentCountsMap.get(p.getValue1());
if(cnt!=null) {
cnt.incrementAndGet();
}
});
LOG.debug("Page {} - counted {} equipmentids", context.getLastReturnedPageNumber(), context.getTotalItemsReturned());
}
//package results to get equipment counts for the original profile ids
profileIdToTopProfileIdMap.forEach((p, tp) -> ret.add(new PairLongLong(p, topProfileIdToEquipmentCountsMap.get(tp).intValue())));
LOG.debug("getCountsOfEquipmentThatUseProfiles({}) return {}", profileIdSet, ret);
return ret; return ret;
} }
} }

View File

@@ -1043,6 +1043,8 @@ components:
type: boolean type: boolean
forwardMode: forwardMode:
$ref: '#/components/schemas/NetworkForwardMode' $ref: '#/components/schemas/NetworkForwardMode'
blinkAllLEDs:
type: boolean
radioMap: radioMap:
$ref: '#/components/schemas/RadioMap' $ref: '#/components/schemas/RadioMap'
advancedRadioMap: advancedRadioMap:
@@ -1865,6 +1867,9 @@ components:
sharedSecret: sharedSecret:
type: string type: string
format: password format: password
dynamicDiscovery:
description: Dynamic discovery of HSP and IdPs (home service and identity providers). Regardless of configured value, this will only be set 'true' on the AP if useRadSec is also true.
type: boolean
example: example:
model_type: RadiusProxyConfiguration model_type: RadiusProxyConfiguration
caCert: caCert:
@@ -2263,7 +2268,8 @@ components:
- wpa3OnlySAE - wpa3OnlySAE
- wpa3MixedSAE - wpa3MixedSAE
- wpa3OnlyEAP - wpa3OnlyEAP
- wpa3MixedEAP - wpa3MixedEAP
- wpa3OnlyEAP192
RadioBasedSsidConfigurationMap: RadioBasedSsidConfigurationMap:
properties: properties:
@@ -3327,8 +3333,6 @@ components:
EquipmentAdminStatusData: EquipmentAdminStatusData:
type: object type: object
required:
- model_type
properties: properties:
model_type: model_type:
type: string type: string
@@ -3342,6 +3346,15 @@ components:
$ref: '#/components/schemas/StatusCode' $ref: '#/components/schemas/StatusCode'
statusMessage: statusMessage:
type: string type: string
ledStatus:
$ref: '#/components/schemas/LedStatus'
LedStatus:
type: string
enum:
- led_blink
- led_off
- UNKNOWN
StatusCode: StatusCode:
type: string type: string
@@ -4305,6 +4318,8 @@ components:
- RADIO_CHANNEL - RADIO_CHANNEL
channelNumberStatusDataMap: channelNumberStatusDataMap:
$ref: '#/components/schemas/IntegerPerRadioTypeMap' $ref: '#/components/schemas/IntegerPerRadioTypeMap'
txPowerDataMap:
$ref: '#/components/schemas/IntegerPerRadioTypeMap'
# #
# Objects related to Client sessions # Objects related to Client sessions
@@ -4332,8 +4347,7 @@ components:
type: object type: object
properties: properties:
sessionId: sessionId:
type: integer type: string
format: int64
authTimestamp: authTimestamp:
type: integer type: integer
format: int64 format: int64
@@ -4420,8 +4434,7 @@ components:
steerType: steerType:
$ref: '#/components/schemas/SteerType' $ref: '#/components/schemas/SteerType'
previousValidSessionId: previousValidSessionId:
type: integer type: string
format: int64
lastFailureDetails: lastFailureDetails:
$ref: '#/components/schemas/ClientFailureDetails' $ref: '#/components/schemas/ClientFailureDetails'
firstFailureDetails: firstFailureDetails:
@@ -4436,8 +4449,7 @@ components:
type: integer type: integer
format: int32 format: int32
priorSessionId: priorSessionId:
type: integer type: string
format: int64
priorEquipmentId: priorEquipmentId:
type: integer type: integer
format: int64 format: int64
@@ -5219,9 +5231,8 @@ components:
format: int32 format: int32
sessionId: sessionId:
type: integer type: string
format: int64
classificationName: classificationName:
type: string type: string
@@ -9083,6 +9094,7 @@ components:
- EquipmentChangedEvent - EquipmentChangedEvent
- EquipmentApImpactingChangedEvent - EquipmentApImpactingChangedEvent
- EquipmentChannelsChangedEvent - EquipmentChannelsChangedEvent
- EquipmentBlinkLEDsEvent
- EquipmentCellSizeAttributesChangedEvent - EquipmentCellSizeAttributesChangedEvent
- EquipmentRemovedEvent - EquipmentRemovedEvent
- StatusChangedEvent - StatusChangedEvent
@@ -9176,6 +9188,7 @@ components:
- $ref: '#/components/schemas/EquipmentChangedEvent' - $ref: '#/components/schemas/EquipmentChangedEvent'
- $ref: '#/components/schemas/EquipmentApImpactingChangedEvent' - $ref: '#/components/schemas/EquipmentApImpactingChangedEvent'
- $ref: '#/components/schemas/EquipmentChannelsChangedEvent' - $ref: '#/components/schemas/EquipmentChannelsChangedEvent'
- $ref: '#/components/schemas/EquipmentBlinkLEDsEvent'
- $ref: '#/components/schemas/EquipmentCellSizeAttributesChangedEvent' - $ref: '#/components/schemas/EquipmentCellSizeAttributesChangedEvent'
- $ref: '#/components/schemas/EquipmentRemovedEvent' - $ref: '#/components/schemas/EquipmentRemovedEvent'
- $ref: '#/components/schemas/StatusChangedEvent' - $ref: '#/components/schemas/StatusChangedEvent'
@@ -9529,7 +9542,12 @@ components:
$ref: '#/components/schemas/IntegerPerRadioTypeMap' $ref: '#/components/schemas/IntegerPerRadioTypeMap'
newBackupChannels: newBackupChannels:
$ref: '#/components/schemas/IntegerPerRadioTypeMap' $ref: '#/components/schemas/IntegerPerRadioTypeMap'
EquipmentBlinkLEDsEvent:
properties:
allOf:
$ref: '#/components/schemas/EquipmentChangedEvent'
EquipmentCellSizeAttributesChangedEvent: EquipmentCellSizeAttributesChangedEvent:
properties: properties:
allOf: allOf:
@@ -9761,8 +9779,7 @@ components:
clientMacAddress: clientMacAddress:
$ref: '#/components/schemas/MacAddress' $ref: '#/components/schemas/MacAddress'
sessionId: sessionId:
type: integer type: string
format: int64
customerId: customerId:
type: integer type: integer
format: int32 format: int32
@@ -9894,8 +9911,7 @@ components:
allOf: allOf:
$ref: '#/components/schemas/RealTimeEvent' $ref: '#/components/schemas/RealTimeEvent'
sessionId: sessionId:
type: integer type: string
format: int64
ssid: ssid:
type: string type: string
clientMacAddress: clientMacAddress:
@@ -9930,8 +9946,7 @@ components:
clientMacAddress: clientMacAddress:
$ref: '#/components/schemas/MacAddress' $ref: '#/components/schemas/MacAddress'
sessionId: sessionId:
type: integer type: string
format: int64
radioType: radioType:
$ref: '#/components/schemas/RadioType' $ref: '#/components/schemas/RadioType'
isReassociation: isReassociation:
@@ -9987,8 +10002,7 @@ components:
allOf: allOf:
$ref: '#/components/schemas/RealTimeEvent' $ref: '#/components/schemas/RealTimeEvent'
sessionId: sessionId:
type: integer type: string
format: int64
ssid: ssid:
type: string type: string
clientMacAddress: clientMacAddress:
@@ -10007,8 +10021,7 @@ components:
allOf: allOf:
$ref: '#/components/schemas/RealTimeEvent' $ref: '#/components/schemas/RealTimeEvent'
sessionId: sessionId:
type: integer type: string
format: int64
macAddressBytes: macAddressBytes:
type: array type: array
items: items:
@@ -10035,8 +10048,7 @@ components:
allOf: allOf:
$ref: '#/components/schemas/RealTimeEvent' $ref: '#/components/schemas/RealTimeEvent'
sessionId: sessionId:
type: integer type: string
format: int64
clientMacAddress: clientMacAddress:
$ref: '#/components/schemas/MacAddress' $ref: '#/components/schemas/MacAddress'
lastRecvTime: lastRecvTime:
@@ -10057,8 +10069,7 @@ components:
allOf: allOf:
$ref: '#/components/schemas/RealTimeEvent' $ref: '#/components/schemas/RealTimeEvent'
sessionId: sessionId:
type: integer type: string
format: int64
ssid: ssid:
type: string type: string
clientMacAddress: clientMacAddress:
@@ -10093,8 +10104,7 @@ components:
allOf: allOf:
$ref: '#/components/schemas/RealTimeEvent' $ref: '#/components/schemas/RealTimeEvent'
sessionId: sessionId:
type: integer type: string
format: int64
ssid: ssid:
type: string type: string
clientMacAddress: clientMacAddress:
@@ -10134,8 +10144,7 @@ components:
allOf: allOf:
$ref: '#/components/schemas/RealTimeEvent' $ref: '#/components/schemas/RealTimeEvent'
sessionId: sessionId:
type: integer type: string
format: int64
clientMacAddress: clientMacAddress:
$ref: '#/components/schemas/MacAddress' $ref: '#/components/schemas/MacAddress'
firstDataRcvdTs: firstDataRcvdTs:
@@ -10154,8 +10163,7 @@ components:
allOf: allOf:
$ref: '#/components/schemas/RealTimeEvent' $ref: '#/components/schemas/RealTimeEvent'
sessionId: sessionId:
type: integer type: string
format: int64
clientMacAddress: clientMacAddress:
$ref: '#/components/schemas/MacAddress' $ref: '#/components/schemas/MacAddress'
ipAddr: ipAddr:
@@ -10237,8 +10245,7 @@ components:
type: integer type: integer
format: int64 format: int64
associationId: associationId:
type: integer type: string
format: int64
clientMacAddress: clientMacAddress:
$ref: '#/components/schemas/MacAddress' $ref: '#/components/schemas/MacAddress'
radioType: radioType:
@@ -10280,8 +10287,7 @@ components:
type: integer type: integer
format: int64 format: int64
associationId: associationId:
type: integer type: string
format: int64
macAddress: macAddress:
$ref: '#/components/schemas/MacAddress' $ref: '#/components/schemas/MacAddress'
radioType: radioType:
@@ -10328,11 +10334,9 @@ components:
allOf: allOf:
$ref: '#/components/schemas/RealTimeEvent' $ref: '#/components/schemas/RealTimeEvent'
videoSessionId: videoSessionId:
type: integer type: string
format: int64
sessionId: sessionId:
type: integer type: string
format: int64
clientMac: clientMac:
$ref: '#/components/schemas/MacAddress' $ref: '#/components/schemas/MacAddress'
serverIp: serverIp:
@@ -10352,11 +10356,9 @@ components:
allOf: allOf:
$ref: '#/components/schemas/RealTimeEvent' $ref: '#/components/schemas/RealTimeEvent'
videoSessionId: videoSessionId:
type: integer type: string
format: int64
sessionId: sessionId:
type: integer type: string
format: int64
clientMac: clientMac:
$ref: '#/components/schemas/MacAddress' $ref: '#/components/schemas/MacAddress'
serverIp: serverIp:
@@ -10374,11 +10376,9 @@ components:
allOf: allOf:
$ref: '#/components/schemas/RealTimeEvent' $ref: '#/components/schemas/RealTimeEvent'
videoSessionId: videoSessionId:
type: integer type: string
format: int64
sessionId: sessionId:
type: integer type: string
format: int64
clientMac: clientMac:
$ref: '#/components/schemas/MacAddress' $ref: '#/components/schemas/MacAddress'
serverIp: serverIp:
@@ -14238,6 +14238,36 @@ paths:
$ref: '#/components/schemas/GenericResponse' $ref: '#/components/schemas/GenericResponse'
500: 500:
$ref: '#/components/responses/GenericApiError' $ref: '#/components/responses/GenericApiError'
/portal/equipmentGateway/requestApBlinkLEDs:
post:
tags:
- Equipment Gateway
summary: Request to enable or disable the blinking of LEDs on the AP
operationId: requestApBlinkLEDs
parameters:
- name: equipmentId
in: query
description: Equipment id for AP on which the enabling or disabling of blinking LEDs is requested.
required: true
schema:
type: integer
format: int64
- name: blinkAllLEDs
in: query
description: enable (true) or disable (false) the LEDs blinking state.
required: true
schema:
type: boolean
responses:
200:
description: successful operation
content:
application/json:
schema:
$ref: '#/components/schemas/GenericResponse'
500:
$ref: '#/components/responses/GenericApiError'
/portal/equipmentGateway/requestChannelChange: /portal/equipmentGateway/requestChannelChange:
post: post:

View File

@@ -0,0 +1,200 @@
package com.telecominfraproject.wlan.portal.controller.profile;
import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicLong;
import org.junit.Test;
import org.junit.jupiter.api.BeforeEach;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.context.annotation.Import;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringRunner;
import com.telecominfraproject.wlan.cloudeventdispatcher.CloudEventDispatcherEmpty;
import com.telecominfraproject.wlan.core.model.equipment.EquipmentType;
import com.telecominfraproject.wlan.core.model.pair.PairLongLong;
import com.telecominfraproject.wlan.equipment.EquipmentServiceLocal;
import com.telecominfraproject.wlan.equipment.controller.EquipmentController;
import com.telecominfraproject.wlan.equipment.datastore.EquipmentDatastore;
import com.telecominfraproject.wlan.equipment.datastore.inmemory.EquipmentDatastoreInMemory;
import com.telecominfraproject.wlan.equipment.models.Equipment;
import com.telecominfraproject.wlan.portal.controller.profile.ProfilePortalController.ListOfPairLongLong;
import com.telecominfraproject.wlan.profile.ProfileServiceLocal;
import com.telecominfraproject.wlan.profile.controller.ProfileController;
import com.telecominfraproject.wlan.profile.datastore.ProfileDatastore;
import com.telecominfraproject.wlan.profile.datastore.inmemory.ProfileDatastoreInMemory;
import com.telecominfraproject.wlan.profile.models.Profile;
import com.telecominfraproject.wlan.profile.models.ProfileByCustomerRequestFactory;
import com.telecominfraproject.wlan.profile.models.ProfileType;
@RunWith(SpringRunner.class)
@ActiveProfiles(profiles = {
"integration_test",
}) //NOTE: these profiles will be ADDED to the list of active profiles
@SpringBootTest(webEnvironment = WebEnvironment.NONE, classes = ProfilePortalControllerTest.class)
@Import(value = {
EquipmentServiceLocal.class,
EquipmentController.class,
EquipmentDatastoreInMemory.class,
ProfileServiceLocal.class,
ProfileController.class,
ProfileDatastoreInMemory.class,
ProfileByCustomerRequestFactory.class,
CloudEventDispatcherEmpty.class,
ProfilePortalController.class
})
public class ProfilePortalControllerTest {
private static AtomicLong profileIncrementer = new AtomicLong(1);
private static AtomicLong equipmentIncrementer = new AtomicLong(1);
private static Set<Long> profileIds = new HashSet<Long>();
private static Set<Long> equipmentIds = new HashSet<Long>();
@Autowired private ProfilePortalController profilePortalController;
@Autowired private EquipmentDatastore equipmentDatastore;
@Autowired private ProfileDatastore profileDatastore;
@BeforeEach
public void setup()
{
profileIds.clear();
equipmentIds.clear();
}
@Test
public void getCountsOfEquipmentThatUseProfilesTest()
{
Profile parentProfile_1 = createProfile(); // 3 equipment
Profile parentProfile_2 = createProfile(); // 2 equipment
Profile parentProfile_3 = createProfile(); // 1 equipment
Profile ssidProfile_1 = createSsidProfile(); // linked to parent ids: 1 = 3 expected count
Profile ssidProfile_2 = createSsidProfile(); // linked to parent ids: 1,2 = 5 expected count
Profile ssidProfile_3 = createSsidProfile(); // linked to parent ids: 3 = 1 expected count
Profile captivePortalProfile_1 = createCaptivePortalProfile(); // linked to 4 -> 1 = 3 expected count
Profile captivePortalProfile_2 = createCaptivePortalProfile(); // linked to 5 and 6 -> 5 + 1 = 6 expected count
Profile radiusProfile_1 = createRadiusProfile(); // 7, 8 -> 4, 5, 6 -> 1 , 2 , 3 -> 6 expected
Profile radiusProfile_2 = createRadiusProfile(); // 0 expected
// link ssid to AP profiles
linkChildToParent(ssidProfile_1.getId(), parentProfile_1.getId());
linkChildToParent(ssidProfile_2.getId(), parentProfile_1.getId());
linkChildToParent(ssidProfile_2.getId(), parentProfile_2.getId());
linkChildToParent(ssidProfile_3.getId(), parentProfile_3.getId());
//link captive portal profiles to ssid profiles
linkChildToParent(captivePortalProfile_1.getId(), ssidProfile_1.getId());
linkChildToParent(captivePortalProfile_2.getId(), ssidProfile_2.getId());
linkChildToParent(captivePortalProfile_2.getId(), ssidProfile_3.getId());
//link radius profiles to captive portal profiles
linkChildToParent(radiusProfile_1.getId(), captivePortalProfile_1.getId());
linkChildToParent(radiusProfile_1.getId(), captivePortalProfile_2.getId());
createEquipment(parentProfile_1.getId());
createEquipment(parentProfile_1.getId());
createEquipment(parentProfile_1.getId());
createEquipment(parentProfile_2.getId());
createEquipment(parentProfile_2.getId());
createEquipment(parentProfile_3.getId());
ListOfPairLongLong ret = profilePortalController.getCountsOfEquipmentThatUseProfiles(profileIds);
List<PairLongLong> expectedReturn = new ArrayList<PairLongLong>() {{
add(new PairLongLong(parentProfile_1.getId(), 3));
add(new PairLongLong(parentProfile_2.getId(), 2));
add(new PairLongLong(parentProfile_3.getId(), 1));
add(new PairLongLong(ssidProfile_1.getId(), 3));
add(new PairLongLong(ssidProfile_2.getId(), 5));
add(new PairLongLong(ssidProfile_3.getId(), 1));
add(new PairLongLong(captivePortalProfile_1.getId(), 3));
add(new PairLongLong(captivePortalProfile_2.getId(), 6));
add(new PairLongLong(radiusProfile_1.getId(), 6));
add(new PairLongLong(radiusProfile_2.getId(), 0));
}};
expectedReturn.forEach(pair -> assertTrue(ret.contains(pair)));
equipmentIds.forEach(id -> equipmentDatastore.delete(id));
profileIds.forEach(id -> profileDatastore.delete(id));
}
private Profile createProfile()
{
Profile profile = new Profile();
profile.setName("test" + profileIncrementer.getAndIncrement());
profile.setProfileType(ProfileType.equipment_ap);
profile.setCustomerId(2);
Profile created = profileDatastore.create(profile);
profileIds.add(created.getId());
return created;
}
private Profile createSsidProfile()
{
Profile profile = new Profile();
profile.setName("test" + profileIncrementer.getAndIncrement());
profile.setProfileType(ProfileType.ssid);
profile.setCustomerId(2);
Profile created = profileDatastore.create(profile);
profileIds.add(created.getId());
return created;
}
private Profile createCaptivePortalProfile()
{
Profile profile = new Profile();
profile.setName("test" + profileIncrementer.getAndIncrement());
profile.setProfileType(ProfileType.captive_portal);
profile.setCustomerId(2);
Profile created = profileDatastore.create(profile);
profileIds.add(created.getId());
return created;
}
private Profile createRadiusProfile()
{
Profile profile = new Profile();
profile.setName("test" + profileIncrementer.getAndIncrement());
profile.setProfileType(ProfileType.radius);
profile.setCustomerId(2);
Profile created = profileDatastore.create(profile);
profileIds.add(created.getId());
return created;
}
private void linkChildToParent(long childId, long parentId)
{
Profile parentProfile = profileDatastore.get(parentId);
parentProfile.getChildProfileIds().add(childId);
profileDatastore.update(parentProfile);
}
private Equipment createEquipment(long profileId)
{
Equipment equipment = new Equipment();
equipment.setCustomerId(2);
equipment.setEquipmentType(EquipmentType.AP);
equipment.setName("test" + equipmentIncrementer.getAndIncrement());
equipment.setProfileId(profileId);
return equipmentDatastore.create(equipment);
}
}

View File

@@ -148,7 +148,7 @@ public class PortalUserDatastoreInMemory extends BaseInMemoryDatastore implement
PortalUser ret = null; PortalUser ret = null;
for (PortalUser mdl : idToPortalUserMap.values()) { for (PortalUser mdl : idToPortalUserMap.values()) {
if(mdl.getCustomerId() == customerId && mdl.getUsername().equals(username)) { if(mdl.getCustomerId() == customerId && mdl.getUsername().toLowerCase().equals(username.toLowerCase())) {
ret = mdl.clone(); ret = mdl.clone();
} }
} }
@@ -161,7 +161,7 @@ public class PortalUserDatastoreInMemory extends BaseInMemoryDatastore implement
List<PortalUser> listOfPortalUsers = new ArrayList<>(); List<PortalUser> listOfPortalUsers = new ArrayList<>();
for (PortalUser portalUser : idToPortalUserMap.values()) { for (PortalUser portalUser : idToPortalUserMap.values()) {
if (portalUser.getUsername().equals(username)) { if (portalUser.getUsername().toLowerCase().equals(username.toLowerCase())) {
listOfPortalUsers.add(portalUser); listOfPortalUsers.add(portalUser);
} }
} }

View File

@@ -69,15 +69,14 @@ public class PortalUserDAO extends BaseJdbcDao {
private static final Set<String> columnsToSkipForInsert = new HashSet<>(Arrays.asList(COL_ID)); private static final Set<String> columnsToSkipForInsert = new HashSet<>(Arrays.asList(COL_ID));
private static final Set<String> columnsToSkipForUpdate = new HashSet<>(Arrays.asList(COL_ID, "createdTimestamp")); private static final Set<String> columnsToSkipForUpdate = new HashSet<>(Arrays.asList(COL_ID, "createdTimestamp"));
private static final String TABLE_NAME = "portal_user"; public static final String TABLE_NAME = "portal_user";
private static final String TABLE_PREFIX = "s."; public static final String TABLE_PREFIX = "s.";
private static final String ALL_COLUMNS; public static final String ALL_COLUMNS;
private static final Set<String> ALL_COLUMNS_LOWERCASE = new HashSet<>(); public static final Set<String> ALL_COLUMNS_LOWERCASE = new HashSet<>();
@SuppressWarnings("unused")
//use this for queries where multiple tables are involved //use this for queries where multiple tables are involved
private static final String ALL_COLUMNS_WITH_PREFIX; public static final String ALL_COLUMNS_WITH_PREFIX;
private static final String ALL_COLUMNS_FOR_INSERT; private static final String ALL_COLUMNS_FOR_INSERT;
private static final String BIND_VARS_FOR_INSERT; private static final String BIND_VARS_FOR_INSERT;
@@ -135,10 +134,10 @@ public class PortalUserDAO extends BaseJdbcDao {
private static final String SQL_GET_BY_USERNAME = private static final String SQL_GET_BY_USERNAME =
"select " + ALL_COLUMNS + "select " + ALL_COLUMNS +
" from " + TABLE_NAME + " " + " from " + TABLE_NAME + " " +
" where username = ? "; " where lower(username) = ? ";
private static final String SQL_GET_BY_CUSTOMERID_AND_USERNAME = SQL_GET_BY_CUSTOMER_ID + private static final String SQL_GET_BY_CUSTOMERID_AND_USERNAME = SQL_GET_BY_CUSTOMER_ID +
" and username = ?"; " and lower(username) = ?";
private static final String SQL_GET_LASTMOD_BY_ID = private static final String SQL_GET_LASTMOD_BY_ID =
"select lastModifiedTimestamp " + "select lastModifiedTimestamp " +
@@ -162,8 +161,8 @@ public class PortalUserDAO extends BaseJdbcDao {
private static final String SQL_GET_ALL_IN_SET = "select " + ALL_COLUMNS + " from "+TABLE_NAME + " where "+ COL_ID +" in "; private static final String SQL_GET_ALL_IN_SET = "select " + ALL_COLUMNS + " from "+TABLE_NAME + " where "+ COL_ID +" in ";
private static final String SQL_PAGING_SUFFIX = " LIMIT ? OFFSET ? "; public static final String SQL_PAGING_SUFFIX = " LIMIT ? OFFSET ? ";
private static final String SORT_SUFFIX = ""; public static final String SORT_SUFFIX = "";
private static final RowMapper<PortalUser> portalUserRowMapper = new PortalUserRowMapper(); private static final RowMapper<PortalUser> portalUserRowMapper = new PortalUserRowMapper();
@@ -463,7 +462,7 @@ public class PortalUserDAO extends BaseJdbcDao {
try{ try{
PortalUser portalUser = this.jdbcTemplate.queryForObject( PortalUser portalUser = this.jdbcTemplate.queryForObject(
SQL_GET_BY_CUSTOMERID_AND_USERNAME, SQL_GET_BY_CUSTOMERID_AND_USERNAME,
portalUserRowMapper, customerId, username); portalUserRowMapper, customerId, username.toLowerCase());
LOG.debug("Found PortalUser {}", portalUser); LOG.debug("Found PortalUser {}", portalUser);
@@ -478,7 +477,7 @@ public class PortalUserDAO extends BaseJdbcDao {
LOG.debug("Looking up PortalUsers for username {} {}", username); LOG.debug("Looking up PortalUsers for username {} {}", username);
List<PortalUser> ret = this.jdbcTemplate.query(SQL_GET_BY_USERNAME, List<PortalUser> ret = this.jdbcTemplate.query(SQL_GET_BY_USERNAME,
portalUserRowMapper, username); portalUserRowMapper, username.toLowerCase());
LOG.debug("Found List of Portal Users {}", ret); LOG.debug("Found List of Portal Users {}", ret);

View File

@@ -20,6 +20,8 @@ public class PortalUserEventPayload extends BaseJsonModel implements HasCustomer
private long createdTimestamp; private long createdTimestamp;
private long lastModifiedTimestamp; private long lastModifiedTimestamp;
public PortalUserEventPayload() {}
public PortalUserEventPayload(PortalUser portalUser) { public PortalUserEventPayload(PortalUser portalUser) {
this.setId(portalUser.getId()); this.setId(portalUser.getId());
this.setCustomerId(portalUser.getCustomerId()); this.setCustomerId(portalUser.getCustomerId());

View File

@@ -28,6 +28,8 @@ public class RadiusProxyConfiguration extends BaseJsonModel implements PushableC
private Boolean useRadSec; private Boolean useRadSec;
private String sharedSecret; // if useRadSec is false private String sharedSecret; // if useRadSec is false
private String acctSharedSecret; // if useRadSec is false private String acctSharedSecret; // if useRadSec is false
private Boolean dynamicDiscovery; // dynamic discovery of HSP and IdPs (home service and identity providers).
// regardless of configured value, this will only be set 'true' on the AP if useRadSec is also true.
private RadiusProxyConfiguration() { private RadiusProxyConfiguration() {
@@ -70,6 +72,7 @@ public class RadiusProxyConfiguration extends BaseJsonModel implements PushableC
} }
public Integer getPort() { public Integer getPort() {
if (port == null) return -1;
return port; return port;
} }
@@ -86,6 +89,7 @@ public class RadiusProxyConfiguration extends BaseJsonModel implements PushableC
} }
public Integer getAcctPort() { public Integer getAcctPort() {
if (acctPort == null) return -1;
return acctPort; return acctPort;
} }
@@ -118,6 +122,7 @@ public class RadiusProxyConfiguration extends BaseJsonModel implements PushableC
} }
public Boolean getUseRadSec() { public Boolean getUseRadSec() {
if (useRadSec == null) return false;
return useRadSec; return useRadSec;
} }
@@ -141,6 +146,21 @@ public class RadiusProxyConfiguration extends BaseJsonModel implements PushableC
this.acctSharedSecret = acctSharedSecret; this.acctSharedSecret = acctSharedSecret;
} }
/**
* @return the dynamicDiscovery
*/
public Boolean getDynamicDiscovery() {
if (dynamicDiscovery == null) return false;
return dynamicDiscovery;
}
/**
* @param dynamicDiscovery the dynamicDiscovery to set
*/
public void setDynamicDiscovery(Boolean dynamicDiscovery) {
this.dynamicDiscovery = dynamicDiscovery;
}
@Override @Override
public boolean needsToBeUpdatedOnDevice(RadiusProxyConfiguration previousVersion) { public boolean needsToBeUpdatedOnDevice(RadiusProxyConfiguration previousVersion) {
return !Objects.deepEquals(this, previousVersion); return !Objects.deepEquals(this, previousVersion);
@@ -153,8 +173,8 @@ public class RadiusProxyConfiguration extends BaseJsonModel implements PushableC
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash(acctPort, acctServer, acctSharedSecret, caCert, clientCert, clientKey, name, passphrase, port, realm, server, sharedSecret, return Objects.hash(acctPort, acctServer, acctSharedSecret, caCert, clientCert, clientKey, dynamicDiscovery, name, passphrase, port, realm, server,
useRadSec); sharedSecret, useRadSec);
} }
@Override @Override
@@ -168,9 +188,10 @@ public class RadiusProxyConfiguration extends BaseJsonModel implements PushableC
RadiusProxyConfiguration other = (RadiusProxyConfiguration) obj; RadiusProxyConfiguration other = (RadiusProxyConfiguration) obj;
return Objects.equals(acctPort, other.acctPort) && Objects.equals(acctServer, other.acctServer) return Objects.equals(acctPort, other.acctPort) && Objects.equals(acctServer, other.acctServer)
&& Objects.equals(acctSharedSecret, other.acctSharedSecret) && Objects.equals(caCert, other.caCert) && Objects.equals(acctSharedSecret, other.acctSharedSecret) && Objects.equals(caCert, other.caCert)
&& Objects.equals(clientCert, other.clientCert) && Objects.equals(clientKey, other.clientKey) && Objects.equals(name, other.name) && Objects.equals(clientCert, other.clientCert) && Objects.equals(clientKey, other.clientKey)
&& Objects.equals(passphrase, other.passphrase) && Objects.equals(port, other.port) && Objects.equals(realm, other.realm) && Objects.equals(dynamicDiscovery, other.dynamicDiscovery) && Objects.equals(name, other.name) && Objects.equals(passphrase, other.passphrase)
&& Objects.equals(server, other.server) && Objects.equals(sharedSecret, other.sharedSecret) && Objects.equals(useRadSec, other.useRadSec); && Objects.equals(port, other.port) && Objects.equals(realm, other.realm) && Objects.equals(server, other.server)
&& Objects.equals(sharedSecret, other.sharedSecret) && Objects.equals(useRadSec, other.useRadSec);
} }

View File

@@ -370,11 +370,9 @@ public class SsidConfiguration extends ProfileDetails implements PushableConfigu
public static enum SecureMode { public static enum SecureMode {
open(0L), wpaPSK(1L), wpa2PSK(2L), wpaRadius(3L), wpa2Radius(4L), wpa2OnlyPSK(5L), wpa2OnlyRadius(6L), wep( open(0L), wpaPSK(1L), wpa2PSK(2L), wpaRadius(3L), wpa2Radius(4L), wpa2OnlyPSK(5L), wpa2OnlyRadius(6L), wep(7L),
7L), wpaEAP(8L), wpa2EAP( wpaEAP(8L), wpa2EAP(9L), wpa2OnlyEAP(10L), wpa3OnlySAE(11L), wpa3MixedSAE(12L), wpa3OnlyEAP(13L), wpa3MixedEAP(14L),
9L), wpa2OnlyEAP(10L), wpa3OnlySAE(11L), wpa3MixedSAE(12L), wpa3OnlyEAP(13L), wpa3MixedEAP(14L), wpa3OnlyEAP192(15L), UNSUPPORTED(-1L);
UNSUPPORTED(-1L);
private final long id; private final long id;
private static final Map<Long, SecureMode> ELEMENTS = new HashMap<>(); private static final Map<Long, SecureMode> ELEMENTS = new HashMap<>();
@@ -415,7 +413,7 @@ public class SsidConfiguration extends ProfileDetails implements PushableConfigu
} }
public static boolean isWPA3_Enterprise_or_Personal(SecureMode mode) { public static boolean isWPA3_Enterprise_or_Personal(SecureMode mode) {
return mode == wpa3OnlySAE || mode == wpa3OnlyEAP; return mode == wpa3OnlySAE || mode == wpa3OnlyEAP || mode == wpa3OnlyEAP192;
} }
} }

View File

@@ -491,6 +491,9 @@ components:
sharedSecret: sharedSecret:
type: string type: string
format: password format: password
dynamicDiscovery:
description: Dynamic discovery of HSP and IdPs (home service and identity providers). Regardless of configured value, this will only be set 'true' on the AP if useRadSec is also true.
type: boolean
example: example:
model_type: RadiusProxyConfiguration model_type: RadiusProxyConfiguration
caCert: caCert:
@@ -1021,6 +1024,7 @@ components:
- wpa3MixedSAE - wpa3MixedSAE
- wpa3OnlyEAP - wpa3OnlyEAP
- wpa3MixedEAP - wpa3MixedEAP
- wpa3OnlyEAP192
RadioBasedSsidConfigurationMap: RadioBasedSsidConfigurationMap:
properties: properties:

View File

@@ -1,97 +1,111 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <project xmlns="http://maven.apache.org/POM/4.0.0"
<modelVersion>4.0.0</modelVersion> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<parent> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<groupId>com.telecominfraproject.wlan</groupId> <modelVersion>4.0.0</modelVersion>
<artifactId>tip-wlan-cloud-root-pom</artifactId> <parent>
<version>1.2.0-SNAPSHOT</version> <groupId>com.telecominfraproject.wlan</groupId>
<relativePath>../../wlan-cloud-root</relativePath> <artifactId>tip-wlan-cloud-root-pom</artifactId>
</parent> <version>1.2.0-SNAPSHOT</version>
<relativePath>../../wlan-cloud-root</relativePath>
</parent>
<artifactId>provisioning-sp</artifactId> <artifactId>provisioning-sp</artifactId>
<name>provisioning-sp</name> <name>provisioning-sp</name>
<description>Stream Processors for provisioning events.</description> <description>Stream Processors for provisioning events.</description>
<dependencies>
<dependency>
<artifactId>base-stream-consumer</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
</dependency>
<dependency> <dependencies>
<artifactId>service-metric-models</artifactId> <dependency>
<groupId>com.telecominfraproject.wlan</groupId> <artifactId>base-stream-consumer</artifactId>
<version>1.2.0-SNAPSHOT</version> <groupId>com.telecominfraproject.wlan</groupId>
</dependency> <version>1.2.0-SNAPSHOT</version>
</dependency>
<dependency> <dependency>
<artifactId>system-event-models</artifactId> <artifactId>service-metric-models</artifactId>
<groupId>com.telecominfraproject.wlan</groupId> <groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version> <version>1.2.0-SNAPSHOT</version>
</dependency> </dependency>
<dependency> <dependency>
<artifactId>base-models</artifactId> <artifactId>system-event-models</artifactId>
<groupId>com.telecominfraproject.wlan</groupId> <groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version> <version>1.2.0-SNAPSHOT</version>
</dependency> </dependency>
<dependency>
<artifactId>routing-service-interface</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
</dependency>
<dependency>
<artifactId>equipment-gateway-service-interface</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
</dependency>
<dependency> <dependency>
<artifactId>equipment-service-interface</artifactId> <artifactId>base-models</artifactId>
<groupId>com.telecominfraproject.wlan</groupId> <groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version> <version>1.2.0-SNAPSHOT</version>
</dependency> </dependency>
<dependency> <dependency>
<artifactId>location-service-interface</artifactId> <artifactId>routing-service-interface</artifactId>
<groupId>com.telecominfraproject.wlan</groupId> <groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version> <version>1.2.0-SNAPSHOT</version>
</dependency> </dependency>
<dependency> <dependency>
<artifactId>profile-service-interface</artifactId> <artifactId>equipment-gateway-service-interface</artifactId>
<groupId>com.telecominfraproject.wlan</groupId> <groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version> <version>1.2.0-SNAPSHOT</version>
</dependency> </dependency>
<dependency>
<artifactId>client-service-interface</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
</dependency>
<!-- models used by the application logic of the stream processor -->
<dependency>
<artifactId>equipment-models</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
</dependency>
<dependency>
<artifactId>profile-models</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
</dependency>
<dependency> <dependency>
<artifactId>location-models</artifactId> <artifactId>equipment-service-interface</artifactId>
<groupId>com.telecominfraproject.wlan</groupId> <groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version> <version>1.2.0-SNAPSHOT</version>
</dependency> </dependency>
</dependencies> <dependency>
<artifactId>location-service-interface</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
</dependency>
<dependency>
<artifactId>profile-service-interface</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
</dependency>
<dependency>
<artifactId>client-service-interface</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
</dependency>
<dependency>
<artifactId>alarm-service-interface</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
</dependency>
<dependency>
<artifactId>status-service-interface</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
</dependency>
<!-- models used by the application logic of the stream processor -->
<dependency>
<artifactId>equipment-models</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
</dependency>
<dependency>
<artifactId>profile-models</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
</dependency>
<dependency>
<artifactId>location-models</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project> </project>

View File

@@ -1,3 +1,4 @@
package com.telecominfraproject.wlan.streams.provisioning; package com.telecominfraproject.wlan.streams.provisioning;
import java.util.ArrayList; import java.util.ArrayList;
@@ -12,18 +13,27 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import com.telecominfraproject.wlan.alarm.AlarmServiceInterface;
import com.telecominfraproject.wlan.alarm.models.Alarm;
import com.telecominfraproject.wlan.client.ClientServiceInterface;
import com.telecominfraproject.wlan.client.session.models.AssociationState;
import com.telecominfraproject.wlan.client.session.models.ClientSession;
import com.telecominfraproject.wlan.core.model.json.BaseJsonModel; import com.telecominfraproject.wlan.core.model.json.BaseJsonModel;
import com.telecominfraproject.wlan.core.model.pagination.PaginationContext; import com.telecominfraproject.wlan.core.model.pagination.PaginationContext;
import com.telecominfraproject.wlan.core.model.pagination.PaginationResponse; import com.telecominfraproject.wlan.core.model.pagination.PaginationResponse;
import com.telecominfraproject.wlan.core.model.pair.PairLongLong; import com.telecominfraproject.wlan.core.model.pair.PairLongLong;
import com.telecominfraproject.wlan.core.model.streams.QueuedStreamMessage; import com.telecominfraproject.wlan.core.model.streams.QueuedStreamMessage;
import com.telecominfraproject.wlan.equipment.EquipmentServiceInterface; import com.telecominfraproject.wlan.equipment.EquipmentServiceInterface;
import com.telecominfraproject.wlan.equipment.models.ApElementConfiguration;
import com.telecominfraproject.wlan.equipment.models.Equipment; import com.telecominfraproject.wlan.equipment.models.Equipment;
import com.telecominfraproject.wlan.equipment.models.events.EquipmentApImpactingChangedEvent; import com.telecominfraproject.wlan.equipment.models.events.EquipmentApImpactingChangedEvent;
import com.telecominfraproject.wlan.equipment.models.events.EquipmentBlinkLEDsEvent;
import com.telecominfraproject.wlan.equipment.models.events.EquipmentCellSizeAttributesChangedEvent; import com.telecominfraproject.wlan.equipment.models.events.EquipmentCellSizeAttributesChangedEvent;
import com.telecominfraproject.wlan.equipment.models.events.EquipmentChannelsChangedEvent; import com.telecominfraproject.wlan.equipment.models.events.EquipmentChannelsChangedEvent;
import com.telecominfraproject.wlan.equipment.models.events.EquipmentCustomerChangedEvent;
import com.telecominfraproject.wlan.equipment.models.events.EquipmentRemovedEvent; import com.telecominfraproject.wlan.equipment.models.events.EquipmentRemovedEvent;
import com.telecominfraproject.wlan.equipmentgateway.models.CEGWBaseCommand; import com.telecominfraproject.wlan.equipmentgateway.models.CEGWBaseCommand;
import com.telecominfraproject.wlan.equipmentgateway.models.CEGWBlinkRequest;
import com.telecominfraproject.wlan.equipmentgateway.models.CEGWCloseSessionRequest; import com.telecominfraproject.wlan.equipmentgateway.models.CEGWCloseSessionRequest;
import com.telecominfraproject.wlan.equipmentgateway.models.CEGWConfigChangeNotification; import com.telecominfraproject.wlan.equipmentgateway.models.CEGWConfigChangeNotification;
import com.telecominfraproject.wlan.equipmentgateway.models.CEGWNewChannelRequest; import com.telecominfraproject.wlan.equipmentgateway.models.CEGWNewChannelRequest;
@@ -35,13 +45,16 @@ import com.telecominfraproject.wlan.profile.models.Profile;
import com.telecominfraproject.wlan.profile.models.events.ProfileAddedEvent; import com.telecominfraproject.wlan.profile.models.events.ProfileAddedEvent;
import com.telecominfraproject.wlan.profile.models.events.ProfileChangedEvent; import com.telecominfraproject.wlan.profile.models.events.ProfileChangedEvent;
import com.telecominfraproject.wlan.profile.models.events.ProfileRemovedEvent; import com.telecominfraproject.wlan.profile.models.events.ProfileRemovedEvent;
import com.telecominfraproject.wlan.status.StatusServiceInterface;
import com.telecominfraproject.wlan.status.models.Status;
import com.telecominfraproject.wlan.status.models.StatusDataType;
import com.telecominfraproject.wlan.stream.StreamProcessor; import com.telecominfraproject.wlan.stream.StreamProcessor;
import com.telecominfraproject.wlan.systemevent.models.SystemEvent; import com.telecominfraproject.wlan.systemevent.models.SystemEvent;
import com.telecominfraproject.wlan.systemevent.models.SystemEventRecord; import com.telecominfraproject.wlan.systemevent.models.SystemEventRecord;
/** /**
* @author dtop * @author dtop
* This stream processor is listening for events related to changes * This stream processor is listening for events related to changes
* in Equipment, Location, and Profile objects. If a change is detected, * in Equipment, Location, and Profile objects. If a change is detected,
* it uses Routing service to find affected equipment and delivers * it uses Routing service to find affected equipment and delivers
* CEGWConfigChangeNotification command to the equipment, which results * CEGWConfigChangeNotification command to the equipment, which results
@@ -50,187 +63,266 @@ import com.telecominfraproject.wlan.systemevent.models.SystemEventRecord;
@Component @Component
public class EquipmentConfigPushTrigger extends StreamProcessor { public class EquipmentConfigPushTrigger extends StreamProcessor {
private static final Logger LOG = LoggerFactory.getLogger(EquipmentConfigPushTrigger.class); private static final Logger LOG = LoggerFactory.getLogger(EquipmentConfigPushTrigger.class);
@Value("${tip.wlan.systemEventsTopic:system_events}")
private String systemEventsTopic;
@Autowired
private EquipmentGatewayServiceInterface equipmentGatewayInterface;
@Autowired
private ProfileServiceInterface profileServiceInterface;
@Autowired
private EquipmentServiceInterface equipmentServiceInterface;
@Override @Value("${tip.wlan.systemEventsTopic:system_events}")
protected boolean acceptMessage(QueuedStreamMessage message) { private String systemEventsTopic;
boolean ret = message.getTopic().equals(systemEventsTopic);
if(ret && ( message.getModel() instanceof SystemEventRecord) ) { @Autowired
private EquipmentGatewayServiceInterface equipmentGatewayInterface;
SystemEventRecord ser = (SystemEventRecord) message.getModel(); @Autowired
ret = ret && private ProfileServiceInterface profileServiceInterface;
( @Autowired
ser.getDetails() instanceof EquipmentApImpactingChangedEvent || private EquipmentServiceInterface equipmentServiceInterface;
ser.getDetails() instanceof EquipmentChannelsChangedEvent || @Autowired
ser.getDetails() instanceof EquipmentCellSizeAttributesChangedEvent || private StatusServiceInterface statusServiceInterface;
ser.getDetails() instanceof EquipmentRemovedEvent || @Autowired
ser.getDetails() instanceof ProfileAddedEvent || private AlarmServiceInterface alarmServiceInterface;
ser.getDetails() instanceof ProfileChangedEvent || @Autowired
ser.getDetails() instanceof ProfileRemovedEvent || private ClientServiceInterface clientServiceInterface;
ser.getDetails() instanceof LocationChangedApImpactingEvent
); @Override
} else { protected boolean acceptMessage(QueuedStreamMessage message) {
ret = false; boolean ret = message.getTopic().equals(systemEventsTopic);
}
if (ret && (message.getModel() instanceof SystemEventRecord)) {
LOG.trace("acceptMessage {}", ret);
SystemEventRecord ser = (SystemEventRecord) message.getModel();
return ret; ret = ret && (ser.getDetails() instanceof EquipmentApImpactingChangedEvent || ser.getDetails() instanceof EquipmentBlinkLEDsEvent
} || ser.getDetails() instanceof EquipmentChannelsChangedEvent || ser.getDetails() instanceof EquipmentCellSizeAttributesChangedEvent
|| ser.getDetails() instanceof EquipmentRemovedEvent || ser.getDetails() instanceof ProfileAddedEvent
@Override || ser.getDetails() instanceof ProfileChangedEvent || ser.getDetails() instanceof ProfileRemovedEvent
protected void processMessage(QueuedStreamMessage message) { || ser.getDetails() instanceof LocationChangedApImpactingEvent || ser.getDetails() instanceof EquipmentCustomerChangedEvent);
SystemEventRecord mdl = (SystemEventRecord) message.getModel(); } else {
SystemEvent se = mdl.getDetails(); ret = false;
LOG.debug("Processing {}", mdl); }
switch ( se.getClass().getSimpleName() ) { LOG.trace("acceptMessage {}", ret);
case "EquipmentApImpactingChangedEvent":
process((EquipmentApImpactingChangedEvent) se); return ret;
break; }
case "EquipmentChannelsChangedEvent":
@Override
protected void processMessage(QueuedStreamMessage message) {
SystemEventRecord mdl = (SystemEventRecord) message.getModel();
SystemEvent se = mdl.getDetails();
LOG.debug("Processing {}", mdl);
switch (se.getClass().getSimpleName()) {
case "EquipmentApImpactingChangedEvent":
process((EquipmentApImpactingChangedEvent) se);
break;
case "EquipmentChannelsChangedEvent":
process((EquipmentChannelsChangedEvent) se); process((EquipmentChannelsChangedEvent) se);
break; break;
case "EquipmentCellSizeAttributesChangedEvent": case "EquipmentCellSizeAttributesChangedEvent":
process((EquipmentCellSizeAttributesChangedEvent) se); process((EquipmentCellSizeAttributesChangedEvent) se);
break; break;
case "EquipmentRemovedEvent": case "EquipmentBlinkLEDsEvent":
process((EquipmentBlinkLEDsEvent) se);
break;
case "EquipmentRemovedEvent":
process((EquipmentRemovedEvent) se); process((EquipmentRemovedEvent) se);
break; break;
case "ProfileAddedEvent": case "ProfileAddedEvent":
process((ProfileAddedEvent) se); process((ProfileAddedEvent) se);
break; break;
case "ProfileChangedEvent": case "ProfileChangedEvent":
process((ProfileChangedEvent) se); process((ProfileChangedEvent) se);
break; break;
case "ProfileRemovedEvent": case "ProfileRemovedEvent":
process((ProfileRemovedEvent) se); process((ProfileRemovedEvent) se);
break; break;
case "LocationChangedApImpactingEvent": case "LocationChangedApImpactingEvent":
process((LocationChangedApImpactingEvent) se); process((LocationChangedApImpactingEvent) se);
break; break;
default: case "EquipmentCustomerChangedEvent":
process(mdl); process((EquipmentCustomerChangedEvent) se);
} default:
process(mdl);
}
private void process(EquipmentApImpactingChangedEvent model) {
LOG.debug("Processing EquipmentChangedEvent");
equipmentGatewayInterface.sendCommand(new CEGWConfigChangeNotification(model.getPayload().getInventoryId(),
model.getEquipmentId()));
} }
}
private void process(EquipmentApImpactingChangedEvent model) {
LOG.debug("Processing EquipmentChangedEvent");
equipmentGatewayInterface.sendCommand(new CEGWConfigChangeNotification(model.getPayload().getInventoryId(), model.getEquipmentId()));
}
private void process(EquipmentChannelsChangedEvent model) {
LOG.debug("Processing EquipmentChannelsChangedEvent for equipmentId {}", model.getEquipmentId());
equipmentGatewayInterface.sendCommand(new CEGWNewChannelRequest(model.getPayload().getInventoryId(), model.getEquipmentId(),
model.getNewBackupChannels(), model.getNewPrimaryChannels()));
}
private void process(EquipmentCellSizeAttributesChangedEvent model) {
LOG.debug("Processing EquipmentCellSizeAttributesChangedEvent for equipmentId {}", model.getEquipmentId());
equipmentGatewayInterface
.sendCommand(new CEGWCellSizeAttributesRequest(model.getPayload().getInventoryId(), model.getEquipmentId(), model.getCellSizeAttributesMap()));
}
private void process(EquipmentBlinkLEDsEvent model) {
LOG.debug("Processing EquipmentBlinkLEDsEvent for equipmentId {}", model.getEquipmentId());
CEGWBlinkRequest br = new CEGWBlinkRequest(model.getPayload().getInventoryId(), model.getEquipmentId());
br.setBlinkAllLEDs(((ApElementConfiguration) model.getPayload().getDetails()).isBlinkAllLEDs());
equipmentGatewayInterface.sendCommand(br);
}
private void process(EquipmentRemovedEvent model) {
LOG.debug("Processing EquipmentRemovedEvent");
equipmentGatewayInterface.sendCommand(new CEGWCloseSessionRequest(model.getPayload().getInventoryId(), model.getEquipmentId()));
}
private void process(ProfileAddedEvent model) {
LOG.debug("Processing ProfileAddedEvent {}", model.getPayload().getId());
processProfile(model.getPayload());
}
private void process(ProfileChangedEvent model) {
LOG.debug("Processing ProfileChangedEvent {}", model.getPayload().getId());
processProfile(model.getPayload());
}
private void process(ProfileRemovedEvent model) {
LOG.debug("Processing ProfileRemovedEvent {}", model.getPayload().getId());
processProfile(model.getPayload());
}
private void processProfile(Profile profile) {
List<PairLongLong> ret = profileServiceInterface.getTopLevelProfiles(new HashSet<>(Arrays.asList(profile.getId())));
if (ret == null || ret.isEmpty()) {
// nothing to do here
return;
}
Set<Long> parentProfileIds = new HashSet<>();
ret.forEach(p -> parentProfileIds.add(p.getValue2()));
// go through all equipmentIds that refer to parent profiles and trigger change config notification on them
PaginationContext<PairLongLong> context = new PaginationContext<>(100);
while (!context.isLastPage()) {
PaginationResponse<PairLongLong> page = equipmentServiceInterface.getEquipmentIdsByProfileIds(parentProfileIds, context);
context = page.getContext();
Set<Long> equipmentIds = new HashSet<>();
page.getItems().forEach(p -> equipmentIds.add(p.getValue2()));
// retrieve full equipment objects to get the inventory id
List<Equipment> equipmentForPage = equipmentServiceInterface.get(equipmentIds);
List<CEGWBaseCommand> commands = new ArrayList<>(equipmentForPage.size());
equipmentForPage.forEach(eq -> commands.add(new CEGWConfigChangeNotification(eq.getInventoryId(), eq.getId())));
equipmentGatewayInterface.sendCommands(commands);
LOG.debug("Page {} - sent {} commands to equipment gateway", context.getLastReturnedPageNumber(), commands.size());
}
LOG.debug("Finished processing profile {}", profile.getId());
}
private void process(LocationChangedApImpactingEvent model) {
LOG.debug("Processing LocationChangedApImpactingEvent {}", model.getPayload().getId());
Set<Long> locationIds = new HashSet<>(Arrays.asList(model.getPayload().getId()));
// go through all equipmentIds that reside in the specified location and trigger change config notification on
// them
PaginationContext<PairLongLong> context = new PaginationContext<>(100);
while (!context.isLastPage()) {
PaginationResponse<PairLongLong> page = equipmentServiceInterface.getEquipmentIdsByLocationIds(locationIds, context);
context = page.getContext();
Set<Long> equipmentIds = new HashSet<>();
page.getItems().forEach(p -> equipmentIds.add(p.getValue2()));
// retrieve full equipment objects to get the inventory id
List<Equipment> equipmentForPage = equipmentServiceInterface.get(equipmentIds);
List<CEGWBaseCommand> commands = new ArrayList<>(equipmentForPage.size());
equipmentForPage.forEach(eq -> commands.add(new CEGWConfigChangeNotification(eq.getInventoryId(), eq.getId())));
equipmentGatewayInterface.sendCommands(commands);
LOG.debug("Page {} - sent {} commands to equipment gateway", context.getLastReturnedPageNumber(), commands.size());
}
LOG.debug("Finished processing LocationChangedApImpactingEvent {}", model.getPayload().getId());
}
private void process(EquipmentCustomerChangedEvent model) {
LOG.info("Processing EquipmentCustomerChangedEvent {}", model.getPayload().getId());
private void process(EquipmentChannelsChangedEvent model) { Equipment existingEquipment = model.getExistingEquipment();
LOG.debug("Processing EquipmentChannelsChangedEvent for equipmentId {}", model.getEquipmentId()); Equipment equipment = model.getEquipment();
equipmentGatewayInterface.sendCommand(new CEGWNewChannelRequest(model.getPayload().getInventoryId(),
model.getEquipmentId(), model.getNewBackupChannels(), model.getNewPrimaryChannels())); // when customerId changes, we keep the EQUIPMENT_ADMIN and PROTOCOL status of the AP
Status status = statusServiceInterface.getOrNull(existingEquipment.getCustomerId(), existingEquipment.getId(), StatusDataType.EQUIPMENT_ADMIN);
if (status != null) {
status.setCustomerId(equipment.getCustomerId());
statusServiceInterface.update(status);
} }
status = statusServiceInterface.getOrNull(existingEquipment.getCustomerId(), existingEquipment.getId(), StatusDataType.PROTOCOL);
if (status != null) {
status.setCustomerId(equipment.getCustomerId());
statusServiceInterface.update(status);
}
// Alarms has to move to new customerId as well
List<Alarm> oldCustomerAlarms = alarmServiceInterface.get(existingEquipment.getCustomerId(), Set.of(existingEquipment.getId()), null);
if (!oldCustomerAlarms.isEmpty()) {
oldCustomerAlarms.stream().forEach(a -> {
a.setCustomerId(equipment.getCustomerId());
Alarm alarm = alarmServiceInterface.create(a);
LOG.debug("Move an alarm to new customer {}", alarm);
});
}
alarmServiceInterface.delete(existingEquipment.getCustomerId(), existingEquipment.getId());
private void process(EquipmentCellSizeAttributesChangedEvent model) { // Disconnect all associated client devices from existing equipment
LOG.debug("Processing EquipmentCellSizeAttributesChangedEvent for equipmentId {}", model.getEquipmentId()); disconnectClients(existingEquipment);
equipmentGatewayInterface.sendCommand(new CEGWCellSizeAttributesRequest(model.getPayload().getInventoryId(),
model.getEquipmentId(), model.getCellSizeAttributesMap()));
}
private void process(EquipmentRemovedEvent model) {
LOG.debug("Processing EquipmentRemovedEvent");
equipmentGatewayInterface.sendCommand(new CEGWCloseSessionRequest(model.getPayload().getInventoryId(), model.getEquipmentId()));
}
private void process(ProfileAddedEvent model) { }
LOG.debug("Processing ProfileAddedEvent {}", model.getPayload().getId());
processProfile(model.getPayload());
}
private void process(ProfileChangedEvent model) { private void process(BaseJsonModel model) {
LOG.debug("Processing ProfileChangedEvent {}", model.getPayload().getId()); LOG.warn("Unprocessed model: {}", model);
processProfile(model.getPayload()); }
}
private void disconnectClients(Equipment ce) {
private void process(ProfileRemovedEvent model) { LOG.info("EquipmentConfigPushTrigger::disconnectClients for Equipment {}", ce);
LOG.debug("Processing ProfileRemovedEvent {}", model.getPayload().getId()); PaginationResponse<ClientSession> clientSessions = clientServiceInterface.getSessionsForCustomer(
processProfile(model.getPayload()); ce.getCustomerId(), Set.of(ce.getId()), Set.of(ce.getLocationId()), null, null,
} new PaginationContext<ClientSession>(100));
if (clientSessions == null) {
LOG.info("There are no existing client sessions to disconnect.");
return;
}
private void processProfile(Profile profile) { List<ClientSession> toBeDisconnected = new ArrayList<>();
List<PairLongLong> ret = profileServiceInterface.getTopLevelProfiles(new HashSet<>(Arrays.asList(profile.getId())));
if(ret == null || ret.isEmpty()) {
//nothing to do here
return;
}
Set<Long> parentProfileIds = new HashSet<>();
ret.forEach(p -> parentProfileIds.add(p.getValue2()));
//go through all equipmentIds that refer to parent profiles and trigger change config notification on them
PaginationContext<PairLongLong> context = new PaginationContext<>(100);
while(!context.isLastPage()) {
PaginationResponse<PairLongLong> page = equipmentServiceInterface.getEquipmentIdsByProfileIds(parentProfileIds, context );
context = page.getContext();
Set<Long> equipmentIds = new HashSet<>();
page.getItems().forEach(p -> equipmentIds.add(p.getValue2()));
//retrieve full equipment objects to get the inventory id
List<Equipment> equipmentForPage = equipmentServiceInterface.get(equipmentIds);
List<CEGWBaseCommand> commands = new ArrayList<>(equipmentForPage.size());
equipmentForPage.forEach(eq -> commands.add(new CEGWConfigChangeNotification(eq.getInventoryId(), eq.getId())));
equipmentGatewayInterface.sendCommands(commands);
LOG.debug("Page {} - sent {} commands to equipment gateway", context.getLastReturnedPageNumber(), commands.size());
}
LOG.debug("Finished processing profile {}", profile.getId());
}
private void process(LocationChangedApImpactingEvent model) {
LOG.debug("Processing LocationChangedApImpactingEvent {}", model.getPayload().getId());
Set<Long> locationIds = new HashSet<>(Arrays.asList(model.getPayload().getId()));
//go through all equipmentIds that reside in the specified location and trigger change config notification on them
PaginationContext<PairLongLong> context = new PaginationContext<>(100);
while(!context.isLastPage()) {
PaginationResponse<PairLongLong> page = equipmentServiceInterface.getEquipmentIdsByLocationIds(locationIds, context );
context = page.getContext();
Set<Long> equipmentIds = new HashSet<>();
page.getItems().forEach(p -> equipmentIds.add(p.getValue2()));
//retrieve full equipment objects to get the inventory id
List<Equipment> equipmentForPage = equipmentServiceInterface.get(equipmentIds);
List<CEGWBaseCommand> commands = new ArrayList<>(equipmentForPage.size());
equipmentForPage.forEach(eq -> commands.add(new CEGWConfigChangeNotification(eq.getInventoryId(), eq.getId())));
equipmentGatewayInterface.sendCommands(commands);
LOG.debug("Page {} - sent {} commands to equipment gateway", context.getLastReturnedPageNumber(), commands.size());
}
LOG.debug("Finished processing LocationChangedApImpactingEvent {}", model.getPayload().getId());
} clientSessions.getItems().stream().forEach(c -> {
if (c.getDetails().getAssociationState() != null
&& !c.getDetails().getAssociationState().equals(AssociationState.Disconnected)) {
LOG.info("Change association state for client {} from {} to {}", c.getMacAddress(),
c.getDetails().getAssociationState(), AssociationState.Disconnected);
private void process(BaseJsonModel model) { c.getDetails().setAssociationState(AssociationState.Disconnected);
LOG.warn("Unprocessed model: {}", model); toBeDisconnected.add(c);
}
}
});
if (!toBeDisconnected.isEmpty()) {
LOG.info("Sending disconnect for client sessions {}", toBeDisconnected);
List<ClientSession> disconnectedSessions = clientServiceInterface.updateSessions(toBeDisconnected);
LOG.info("Result of client disconnect {}", disconnectedSessions);
} else {
LOG.info("There are no existing client sessions that are not already in Disconnected state.");
}
}
} }

View File

@@ -42,7 +42,7 @@ public class ClientMetrics extends ServiceMetricDetails {
private Integer vhtMcs; private Integer vhtMcs;
private Integer snr; private Integer snr;
private Integer rssi; private Integer rssi;
private Long sessionId; private String sessionId;
private String classificationName; private String classificationName;
ChannelBandwidth channelBandWidth; ChannelBandwidth channelBandWidth;
GuardInterval guardInterval; GuardInterval guardInterval;
@@ -1191,7 +1191,7 @@ public class ClientMetrics extends ServiceMetricDetails {
return rxLastRssi; return rxLastRssi;
} }
public Long getSessionId() { public String getSessionId() {
return sessionId; return sessionId;
} }
@@ -1537,7 +1537,7 @@ public class ClientMetrics extends ServiceMetricDetails {
this.rxLastRssi = rxLastRssi; this.rxLastRssi = rxLastRssi;
} }
public void setSessionId(Long sessionId) { public void setSessionId(String sessionId) {
this.sessionId = sessionId; this.sessionId = sessionId;
} }

View File

@@ -270,8 +270,7 @@ components:
format: int32 format: int32
sessionId: sessionId:
type: integer type: string
format: int64
classificationName: classificationName:
type: string type: string

View File

@@ -53,12 +53,6 @@
<version>1.2.0-SNAPSHOT</version> <version>1.2.0-SNAPSHOT</version>
</dependency> </dependency>
<dependency>
<artifactId>equipment-alarms-sp</artifactId>
<groupId>com.telecominfraproject.wlan</groupId>
<version>1.2.0-SNAPSHOT</version>
</dependency>
<dependency> <dependency>
<artifactId>adoption-metrics-sp</artifactId> <artifactId>adoption-metrics-sp</artifactId>
<groupId>com.telecominfraproject.wlan</groupId> <groupId>com.telecominfraproject.wlan</groupId>

View File

@@ -56,8 +56,7 @@ public class StatusDatastoreCassandra implements StatusDatastore {
private static final Set<String> columnsToSkipForUpdate = new HashSet<>(Arrays.asList( private static final Set<String> columnsToSkipForUpdate = new HashSet<>(Arrays.asList(
"customerId", "customerId",
"equipmentId", "equipmentId",
"statusDataType", "statusDataType"));
"createdTimestamp"));
private static final String TABLE_NAME = "status"; private static final String TABLE_NAME = "status";
private static final String ALL_COLUMNS; private static final String ALL_COLUMNS;
@@ -230,11 +229,14 @@ public class StatusDatastoreCassandra implements StatusDatastore {
//This DAO does not enforce check for concurrent updates. Last one always wins. //This DAO does not enforce check for concurrent updates. Last one always wins.
long newLastModifiedTs = System.currentTimeMillis(); long newLastModifiedTs = System.currentTimeMillis();
boolean isCreateNotSet = status.getCreatedTimestamp() == 0;
cqlSession.execute(preparedStmt_update.bind( cqlSession.execute(preparedStmt_update.bind(
//TODO: add remaining properties from Status here //TODO: add remaining properties from Status here
(status.getDetails()!=null) ? ByteBuffer.wrap(status.getDetails().toZippedBytes()) : null , (status.getDetails()!=null) ? ByteBuffer.wrap(status.getDetails().toZippedBytes()) : null ,
isCreateNotSet ? newLastModifiedTs : status.getCreatedTimestamp(),
newLastModifiedTs, newLastModifiedTs,
@@ -253,6 +255,9 @@ public class StatusDatastoreCassandra implements StatusDatastore {
//make a copy so that we don't accidentally update caller's version by reference //make a copy so that we don't accidentally update caller's version by reference
Status statusCopy = status.clone(); Status statusCopy = status.clone();
if(isCreateNotSet) {
statusCopy.setCreatedTimestamp(newLastModifiedTs);
}
statusCopy.setLastModifiedTimestamp(newLastModifiedTs); statusCopy.setLastModifiedTimestamp(newLastModifiedTs);
LOG.debug("Updated Status {}", statusCopy); LOG.debug("Updated Status {}", statusCopy);

View File

@@ -1,7 +1,9 @@
package com.telecominfraproject.wlan.status.equipment.models; package com.telecominfraproject.wlan.status.equipment.models;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import com.telecominfraproject.wlan.status.models.StatusCode; import com.telecominfraproject.wlan.status.models.StatusCode;
import com.telecominfraproject.wlan.status.models.StatusDataType; import com.telecominfraproject.wlan.status.models.StatusDataType;
@@ -29,70 +31,29 @@ public class EquipmentAdminStatusData extends StatusDetails {
*/ */
private String statusMessage; private String statusMessage;
private Map<String, Long> alarmTimestamps;
private LedStatus ledStatus;
private Map<String,Long> alarmTimestamps;
public EquipmentAdminStatusData() { public EquipmentAdminStatusData() {
} }
@Override @Override
public StatusDataType getStatusDataType() { public StatusDataType getStatusDataType() {
return StatusDataType.EQUIPMENT_ADMIN; return StatusDataType.EQUIPMENT_ADMIN;
} }
public EquipmentAdminStatusData(EquipmentAdminStatusData data) { public EquipmentAdminStatusData(EquipmentAdminStatusData data) {
this.statusCode = data.statusCode; this.statusCode = data.statusCode;
this.statusMessage = data.statusMessage; this.statusMessage = data.statusMessage;
this.alarmTimestamps = data.alarmTimestamps==null?null:new HashMap<>(data.alarmTimestamps); this.alarmTimestamps = data.alarmTimestamps == null ? null : new HashMap<>(data.alarmTimestamps);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((alarmTimestamps == null) ? 0 : alarmTimestamps.hashCode());
result = prime * result + ((statusCode == null) ? 0 : statusCode.hashCode());
result = prime * result + ((statusMessage == null) ? 0 : statusMessage.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof EquipmentAdminStatusData)) {
return false;
}
EquipmentAdminStatusData other = (EquipmentAdminStatusData) obj;
if (alarmTimestamps == null) {
if (other.alarmTimestamps != null) {
return false;
}
} else if (!alarmTimestamps.equals(other.alarmTimestamps)) {
return false;
}
if (statusCode != other.statusCode) {
return false;
}
if (statusMessage == null) {
if (other.statusMessage != null) {
return false;
}
} else if (!statusMessage.equals(other.statusMessage)) {
return false;
}
return true;
} }
@Override @Override
public EquipmentAdminStatusData clone() { public EquipmentAdminStatusData clone() {
EquipmentAdminStatusData res = (EquipmentAdminStatusData) super.clone(); EquipmentAdminStatusData res = (EquipmentAdminStatusData) super.clone();
if(this.alarmTimestamps != null) { if (this.alarmTimestamps != null) {
res.setAlarmTimestamps(new HashMap<>(this.alarmTimestamps)); res.setAlarmTimestamps(new HashMap<>(this.alarmTimestamps));
} }
return res; return res;
@@ -121,26 +82,54 @@ public class EquipmentAdminStatusData extends StatusDetails {
public void setAlarmTimestamps(Map<String, Long> alarmTimestamps) { public void setAlarmTimestamps(Map<String, Long> alarmTimestamps) {
this.alarmTimestamps = alarmTimestamps; this.alarmTimestamps = alarmTimestamps;
} }
public long findAlarmTimeOrZero(String alarmKey) { public long findAlarmTimeOrZero(String alarmKey) {
return alarmTimestamps==null?0:alarmTimestamps.getOrDefault(alarmKey, 0l); return alarmTimestamps == null ? 0 : alarmTimestamps.getOrDefault(alarmKey, 0l);
} }
public void putAlarmTimestamp(String alarmKey, long value) { public void putAlarmTimestamp(String alarmKey, long value) {
if(alarmTimestamps == null) { if (alarmTimestamps == null) {
alarmTimestamps = new HashMap<>(); alarmTimestamps = new HashMap<>();
} }
alarmTimestamps.put(alarmKey, value); alarmTimestamps.put(alarmKey, value);
} }
@Override @Override
public boolean hasUnsupportedValue() { public boolean hasUnsupportedValue() {
if (super.hasUnsupportedValue()) { if (super.hasUnsupportedValue()) {
return true; return true;
} }
if (StatusCode.isUnsupported(statusCode) ) { if (StatusCode.isUnsupported(statusCode)) {
return true; return true;
} }
return false; return false;
} }
public LedStatus getLedStatus() {
return ledStatus;
}
public void setLedStatus(LedStatus ledStatus) {
this.ledStatus = ledStatus;
}
@Override
public int hashCode() {
return Objects.hash(alarmTimestamps, ledStatus, statusCode, statusMessage);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
EquipmentAdminStatusData other = (EquipmentAdminStatusData) obj;
return Objects.equals(alarmTimestamps, other.alarmTimestamps) && ledStatus == other.ledStatus && statusCode == other.statusCode
&& Objects.equals(statusMessage, other.statusMessage);
}
} }

View File

@@ -12,6 +12,7 @@ public class EquipmentChannelStatusData extends StatusDetails {
private static final long serialVersionUID = 470569467119609438L; private static final long serialVersionUID = 470569467119609438L;
private Map<RadioType, Integer> channelNumberStatusDataMap = new EnumMap<>(RadioType.class); private Map<RadioType, Integer> channelNumberStatusDataMap = new EnumMap<>(RadioType.class);
private Map<RadioType, Integer> txPowerDataMap = new EnumMap<>(RadioType.class);
public EquipmentChannelStatusData() public EquipmentChannelStatusData()
@@ -34,10 +35,18 @@ public class EquipmentChannelStatusData extends StatusDetails {
public Map<RadioType, Integer> getChannelNumberStatusDataMap() { public Map<RadioType, Integer> getChannelNumberStatusDataMap() {
return channelNumberStatusDataMap; return channelNumberStatusDataMap;
} }
public Map<RadioType, Integer> getTxPowerDataMap() {
return txPowerDataMap;
}
public void setChannelNumberStatusDataMap(Map<RadioType, Integer> channelNumberStatusDataMap) { public void setChannelNumberStatusDataMap(Map<RadioType, Integer> channelNumberStatusDataMap) {
this.channelNumberStatusDataMap = channelNumberStatusDataMap; this.channelNumberStatusDataMap = channelNumberStatusDataMap;
} }
public void setTxPowerDataMap(Map<RadioType, Integer> txPowerDataMap) {
this.txPowerDataMap = txPowerDataMap;
}
@Override @Override
public EquipmentChannelStatusData clone() { public EquipmentChannelStatusData clone() {
@@ -49,19 +58,33 @@ public class EquipmentChannelStatusData extends StatusDetails {
result.channelNumberStatusDataMap.put(k, v); result.channelNumberStatusDataMap.put(k, v);
}); });
} }
if (getTxPowerDataMap() != null) {
result.setTxPowerDataMap(new EnumMap<>(RadioType.class));
this.txPowerDataMap.forEach((k, v) -> {
result.txPowerDataMap.put(k, v);
});
}
return result; return result;
} }
@Override @Override
public boolean equals(Object obj) { public int hashCode() {
EquipmentChannelStatusData other = (EquipmentChannelStatusData) obj; return Objects.hash(channelNumberStatusDataMap, txPowerDataMap);
return Objects.equals(channelNumberStatusDataMap, other.channelNumberStatusDataMap);
} }
@Override @Override
public int hashCode() { public boolean equals(Object obj) {
return Objects.hash(channelNumberStatusDataMap); if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
EquipmentChannelStatusData other = (EquipmentChannelStatusData) obj;
return Objects.equals(channelNumberStatusDataMap, other.channelNumberStatusDataMap)
&& Objects.equals(txPowerDataMap, other.txPowerDataMap);
} }
} }

View File

@@ -0,0 +1,6 @@
package com.telecominfraproject.wlan.status.equipment.models;
public enum LedStatus {
led_blink, led_off, UNKNOWN,
}

View File

@@ -197,6 +197,15 @@ components:
$ref: '#/components/schemas/StatusCode' $ref: '#/components/schemas/StatusCode'
statusMessage: statusMessage:
type: string type: string
ledStatus:
$ref: '#/components/schemas/LedStatus'
LedStatus:
type: string
enum:
- led_blink
- led_off
- UNKNOWN
StatusCode: StatusCode:
type: string type: string

View File

@@ -33,6 +33,7 @@ import com.telecominfraproject.wlan.core.model.pagination.PaginationResponse;
import com.telecominfraproject.wlan.core.server.cassandra.RowMapper; import com.telecominfraproject.wlan.core.server.cassandra.RowMapper;
import com.telecominfraproject.wlan.systemevent.datastore.SystemEventDatastore; import com.telecominfraproject.wlan.systemevent.datastore.SystemEventDatastore;
import com.telecominfraproject.wlan.systemevent.models.SystemEventRecord; import com.telecominfraproject.wlan.systemevent.models.SystemEventRecord;
import com.telecominfraproject.wlan.systemevent.models.SystemEventStats;
/** /**
@@ -1031,4 +1032,9 @@ public class SystemEventDatastoreCassandra implements SystemEventDatastore {
return nextPagingState; return nextPagingState;
} }
@Override
public SystemEventStats getSystemEventStats(String filterAttributeName, String filterAttributeValue, long fromTime, long toTime) {
return new SystemEventStats();
}
} }

View File

@@ -3,6 +3,7 @@ package com.telecominfraproject.wlan.systemevent.datastore.inmemory;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -20,8 +21,10 @@ import com.telecominfraproject.wlan.core.model.pagination.PaginationResponse;
import com.telecominfraproject.wlan.core.model.pagination.SortOrder; import com.telecominfraproject.wlan.core.model.pagination.SortOrder;
import com.telecominfraproject.wlan.datastore.inmemory.BaseInMemoryDatastore; import com.telecominfraproject.wlan.datastore.inmemory.BaseInMemoryDatastore;
import com.telecominfraproject.wlan.systemevent.datastore.SystemEventDatastore; import com.telecominfraproject.wlan.systemevent.datastore.SystemEventDatastore;
import com.telecominfraproject.wlan.systemevent.models.EquipmentEventStats;
import com.telecominfraproject.wlan.systemevent.models.SystemEventRecord; import com.telecominfraproject.wlan.systemevent.models.SystemEventRecord;
import com.telecominfraproject.wlan.systemevent.models.SystemEventRecordKey; import com.telecominfraproject.wlan.systemevent.models.SystemEventRecordKey;
import com.telecominfraproject.wlan.systemevent.models.SystemEventStats;
/** /**
* @author dtoptygin * @author dtoptygin
@@ -228,4 +231,38 @@ public class SystemEventDatastoreInMemory extends BaseInMemoryDatastore implemen
return clientMacAddresses.contains(macAddress); return clientMacAddresses.contains(macAddress);
} }
@Override
public SystemEventStats getSystemEventStats(String filterAttributeName, String filterAttributeValue, long fromTime, long toTime) {
List<SystemEventRecord> items = new LinkedList<>();
// apply filters and build the full result list first - inefficient, but ok for testing
for (SystemEventRecord mdl : idToSystemEventRecordMap.values()) {
if (mdl.getEventTimestamp() >= fromTime && mdl.getEventTimestamp() <= toTime) {
items.add(mdl);
}
}
SystemEventStats stats = new SystemEventStats();
stats.setTotalCount(items.size());
Map<String, EquipmentEventStats> eqptStatsMap = new HashMap<>();
for (SystemEventRecord mdl : items) {
EquipmentEventStats eqptStats = eqptStatsMap.get(Long.toString(mdl.getEquipmentId()));
if (eqptStats == null) {
eqptStats = new EquipmentEventStats();
eqptStats.setEquipmentId(mdl.getEquipmentId());
eqptStatsMap.put(Long.toString(mdl.getEquipmentId()), eqptStats);
}
eqptStats.setTotalCount(eqptStats.getTotalCount() + 1);
if (mdl.getEventTimestamp() > eqptStats.getLastEventTime()) {
eqptStats.setLastEventTime(mdl.getEventTimestamp());
}
items.add(mdl);
}
List<EquipmentEventStats> equipmentStats = new ArrayList<>();
stats.setEquipmentStats(equipmentStats);
return stats;
}
} }

View File

@@ -8,6 +8,7 @@ import com.telecominfraproject.wlan.core.model.pagination.ColumnAndSort;
import com.telecominfraproject.wlan.core.model.pagination.PaginationContext; import com.telecominfraproject.wlan.core.model.pagination.PaginationContext;
import com.telecominfraproject.wlan.core.model.pagination.PaginationResponse; import com.telecominfraproject.wlan.core.model.pagination.PaginationResponse;
import com.telecominfraproject.wlan.systemevent.models.SystemEventRecord; import com.telecominfraproject.wlan.systemevent.models.SystemEventRecord;
import com.telecominfraproject.wlan.systemevent.models.SystemEventStats;
/** /**
* @author dtoptygin * @author dtoptygin
@@ -60,4 +61,13 @@ public interface SystemEventDatastore {
List<ColumnAndSort> sortBy, List<ColumnAndSort> sortBy,
PaginationContext<SystemEventRecord> context); PaginationContext<SystemEventRecord> context);
/**
* @param filterAttributeName
* @param filterAttributeValue
* @param fromTime
* @param toTime
* @return Returns system event statistics for the given time range.
*/
SystemEventStats getSystemEventStats(String filterAttributeName, String filterAttributeValue, long fromTime, long toTime);
} }

View File

@@ -20,12 +20,12 @@ public abstract class BaseDhcpEvent extends SystemEvent implements HasClientMac,
private InetAddress clientIp; private InetAddress clientIp;
private InetAddress relayIp; private InetAddress relayIp;
private MacAddress clientMacAddress; private MacAddress clientMacAddress;
private long sessionId; // association sessionid private String sessionId; // association sessionid
private int customerId; private int customerId;
private long equipmentId; private long equipmentId;
private long locationId; private long locationId;
public BaseDhcpEvent(int customerId, long locationId, long equipmentId, long eventTimestamp, long sessionId) { public BaseDhcpEvent(int customerId, long locationId, long equipmentId, long eventTimestamp, String sessionId) {
super(eventTimestamp); super(eventTimestamp);
this.customerId = customerId; this.customerId = customerId;
this.locationId = locationId; this.locationId = locationId;
@@ -113,11 +113,11 @@ public abstract class BaseDhcpEvent extends SystemEvent implements HasClientMac,
this.relayIp = relayIp; this.relayIp = relayIp;
} }
public long getSessionId() { public String getSessionId() {
return sessionId; return sessionId;
} }
public void setSessionId(long sessionId) { public void setSessionId(String sessionId) {
this.sessionId = sessionId; this.sessionId = sessionId;
} }

View File

@@ -22,12 +22,12 @@ public class DhcpAckEvent extends BaseDhcpEvent {
*/ */
private boolean fromInternal = false; private boolean fromInternal = false;
public DhcpAckEvent(int customerId, long locationId, long equipmentId, long eventTimestamp, long sessionId) { public DhcpAckEvent(int customerId, long locationId, long equipmentId, long eventTimestamp, String sessionId) {
super(customerId, locationId, equipmentId, eventTimestamp, sessionId); super(customerId, locationId, equipmentId, eventTimestamp, sessionId);
} }
public DhcpAckEvent() { public DhcpAckEvent() {
super(0, 0L,0L,0L,0L); super(0, 0L,0L,0L,"0");
} }
public InetAddress getGatewayIp() { public InetAddress getGatewayIp() {

View File

@@ -10,12 +10,12 @@ package com.telecominfraproject.wlan.systemevent.equipment;
public class DhcpDeclineEvent extends BaseDhcpEvent { public class DhcpDeclineEvent extends BaseDhcpEvent {
private static final long serialVersionUID = -7745659083975485467L; private static final long serialVersionUID = -7745659083975485467L;
public DhcpDeclineEvent(int customerId, long locationId, long equipmentId, long eventTimestamp, long sessionId){ public DhcpDeclineEvent(int customerId, long locationId, long equipmentId, long eventTimestamp, String sessionId){
super(customerId, locationId, equipmentId,eventTimestamp, sessionId); super(customerId, locationId, equipmentId,eventTimestamp, sessionId);
} }
public DhcpDeclineEvent() { public DhcpDeclineEvent() {
super(0,0L, 0L,0L,0L); super(0,0L, 0L,0L,"0");
} }
@Override @Override

View File

@@ -9,12 +9,12 @@ public class DhcpDiscoverEvent extends BaseDhcpEvent {
private static final long serialVersionUID = -8290687227649478971L; private static final long serialVersionUID = -8290687227649478971L;
private String hostName; private String hostName;
public DhcpDiscoverEvent(int customerId, long locationId, long equipmentId, long eventTimestamp, long sessionId){ public DhcpDiscoverEvent(int customerId, long locationId, long equipmentId, long eventTimestamp, String sessionId){
super(customerId, locationId,equipmentId,eventTimestamp,sessionId); super(customerId, locationId,equipmentId,eventTimestamp,sessionId);
} }
public DhcpDiscoverEvent() { public DhcpDiscoverEvent() {
super(0, 0L,0L,0L,0L); super(0, 0L,0L,0L,"0");
} }
/** /**

View File

@@ -10,12 +10,12 @@ package com.telecominfraproject.wlan.systemevent.equipment;
public class DhcpInformEvent extends BaseDhcpEvent { public class DhcpInformEvent extends BaseDhcpEvent {
private static final long serialVersionUID = 7053813308222200205L; private static final long serialVersionUID = 7053813308222200205L;
public DhcpInformEvent(int customerId, long locationId, long equipmentId, long eventTimestamp, long sessionId){ public DhcpInformEvent(int customerId, long locationId, long equipmentId, long eventTimestamp, String sessionId){
super(customerId, locationId,equipmentId,eventTimestamp, sessionId); super(customerId, locationId,equipmentId,eventTimestamp, sessionId);
} }
public DhcpInformEvent() { public DhcpInformEvent() {
super(0, 0L,0L,0L,0L); super(0, 0L,0L,0L,"0");
} }
@Override @Override

View File

@@ -9,12 +9,12 @@ public class DhcpNakEvent extends BaseDhcpEvent {
private static final long serialVersionUID = -8648265834227002667L; private static final long serialVersionUID = -8648265834227002667L;
private boolean fromInternal = false; private boolean fromInternal = false;
public DhcpNakEvent(int customerId, long locationId, long equipmentId, long eventTimestamp, long sessionId) { public DhcpNakEvent(int customerId, long locationId, long equipmentId, long eventTimestamp, String sessionId) {
super(customerId, locationId, equipmentId, eventTimestamp, sessionId); super(customerId, locationId, equipmentId, eventTimestamp, sessionId);
} }
public DhcpNakEvent() { public DhcpNakEvent() {
super(0, 0L,0L,0L,0L); super(0, 0L,0L,0L,"0");
} }
/** /**

View File

@@ -10,12 +10,12 @@ public class DhcpOfferEvent extends BaseDhcpEvent {
*/ */
private boolean fromInternal = false; private boolean fromInternal = false;
public DhcpOfferEvent(int customerId, long locationId, long equipmentId, long eventTimestamp, long sessionId) { public DhcpOfferEvent(int customerId, long locationId, long equipmentId, long eventTimestamp, String sessionId) {
super(customerId, locationId, equipmentId, eventTimestamp, sessionId); super(customerId, locationId, equipmentId, eventTimestamp, sessionId);
} }
public DhcpOfferEvent() { public DhcpOfferEvent() {
super(0, 0L,0L,0L,0L); super(0, 0L,0L,0L,"0");
} }
/** /**

View File

@@ -9,12 +9,12 @@ public class DhcpRequestEvent extends BaseDhcpEvent {
private static final long serialVersionUID = 906425685437156761L; private static final long serialVersionUID = 906425685437156761L;
private String hostName; private String hostName;
public DhcpRequestEvent(int customerId, long locationId, long equipmentId, long eventTimestamp, long sessionId){ public DhcpRequestEvent(int customerId, long locationId, long equipmentId, long eventTimestamp, String sessionId){
super(customerId, locationId,equipmentId,eventTimestamp, sessionId); super(customerId, locationId,equipmentId,eventTimestamp, sessionId);
} }
public DhcpRequestEvent() { public DhcpRequestEvent() {
super(0, 0L,0L,0L,0L); super(0, 0L,0L,0L,"0");
} }
/** /**

View File

@@ -28,7 +28,7 @@ public abstract class RealTimeSipCallEventWithStats extends RealTimeEvent
private static final long serialVersionUID = -8908272967317508366L; private static final long serialVersionUID = -8908272967317508366L;
private Long sipCallId; private Long sipCallId;
private Long associationId; private String associationId;
private MacAddress clientMacAddress; private MacAddress clientMacAddress;
private List<RtpFlowStats> statuses; private List<RtpFlowStats> statuses;
private int channel; private int channel;
@@ -49,12 +49,12 @@ public abstract class RealTimeSipCallEventWithStats extends RealTimeEvent
this.sipCallId = sipCallId; this.sipCallId = sipCallId;
} }
public Long getAssociationId() { public String getAssociationId() {
return associationId; return associationId;
} }
public void setAssociationId(Long associationId) { public void setAssociationId(String string) {
this.associationId = associationId; this.associationId = string;
} }
@Override @Override
@@ -79,7 +79,7 @@ public abstract class RealTimeSipCallEventWithStats extends RealTimeEvent
} }
public boolean hasValidAssociationId() { public boolean hasValidAssociationId() {
return (associationId != null) && (associationId != 0); return (associationId != null) && (!associationId.equals("0"));
} }
public int getChannel() { public int getChannel() {

View File

@@ -18,7 +18,7 @@ public class RealTimeSipCallStartEvent extends RealTimeEvent
*/ */
private static final long serialVersionUID = -7289926906539107435L; private static final long serialVersionUID = -7289926906539107435L;
private Long sipCallId; private Long sipCallId;
private Long associationId; private String associationId;
private MacAddress macAddress; private MacAddress macAddress;
private List<String> codecs; private List<String> codecs;
private String providerDomain; private String providerDomain;
@@ -52,7 +52,7 @@ public class RealTimeSipCallStartEvent extends RealTimeEvent
&& Objects.equals(channel, other.channel) && Objects.equals(radioType, other.radioType); && Objects.equals(channel, other.channel) && Objects.equals(radioType, other.radioType);
} }
public Long getAssociationId() { public String getAssociationId() {
return associationId; return associationId;
} }
@@ -92,7 +92,7 @@ public class RealTimeSipCallStartEvent extends RealTimeEvent
return result; return result;
} }
public void setAssociationId(Long associationId) { public void setAssociationId(String associationId) {
this.associationId = associationId; this.associationId = associationId;
} }
@@ -131,7 +131,7 @@ public class RealTimeSipCallStartEvent extends RealTimeEvent
} }
public boolean hasValidAssociationId() { public boolean hasValidAssociationId() {
return (associationId != null) && (associationId != 0); return (associationId != null) && (!associationId.equals("0"));
} }
public int getChannel() { public int getChannel() {

View File

@@ -13,8 +13,8 @@ public class RealTimeStreamingStartEvent extends RealTimeEvent
implements HasCustomerId, HasEquipmentId, HasClientMac, HasProducedTimestamp { implements HasCustomerId, HasEquipmentId, HasClientMac, HasProducedTimestamp {
private static final long serialVersionUID = -591221857158333271L; private static final long serialVersionUID = -591221857158333271L;
private Long videoSessionId; private String videoSessionId;
private Long sessionId; private String sessionId;
private MacAddress clientMac; private MacAddress clientMac;
private InetAddress serverIp; private InetAddress serverIp;
private String serverDnsName; private String serverDnsName;
@@ -40,19 +40,19 @@ public class RealTimeStreamingStartEvent extends RealTimeEvent
this.serverDnsName = serverDnsName; this.serverDnsName = serverDnsName;
} }
public Long getVideoSessionId() { public String getVideoSessionId() {
return videoSessionId; return videoSessionId;
} }
public void setVideoSessionId(Long videoSessionId) { public void setVideoSessionId(String videoSessionId) {
this.videoSessionId = videoSessionId; this.videoSessionId = videoSessionId;
} }
public Long getSessionId() { public String getSessionId() {
return sessionId; return sessionId;
} }
public void setSessionId(Long sessionId) { public void setSessionId(String sessionId) {
this.sessionId = sessionId; this.sessionId = sessionId;
} }

View File

@@ -13,8 +13,8 @@ public class RealTimeStreamingStartSessionEvent extends RealTimeEvent
implements HasCustomerId, HasEquipmentId, HasClientMac, HasProducedTimestamp { implements HasCustomerId, HasEquipmentId, HasClientMac, HasProducedTimestamp {
private static final long serialVersionUID = 4395850344272425198L; private static final long serialVersionUID = 4395850344272425198L;
private Long videoSessionId; private String videoSessionId;
private Long sessionId; private String sessionId;
private MacAddress clientMac; private MacAddress clientMac;
private InetAddress serverIp; private InetAddress serverIp;
private StreamingVideoType type; private StreamingVideoType type;
@@ -31,19 +31,19 @@ public class RealTimeStreamingStartSessionEvent extends RealTimeEvent
super(RealTimeEventType.VideoStreamDebugStart, customerId, locationId, equipmentId, eventTimestamp); super(RealTimeEventType.VideoStreamDebugStart, customerId, locationId, equipmentId, eventTimestamp);
} }
public Long getVideoSessionId() { public String getVideoSessionId() {
return videoSessionId; return videoSessionId;
} }
public void setVideoSessionId(Long videoSessionId) { public void setVideoSessionId(String videoSessionId) {
this.videoSessionId = videoSessionId; this.videoSessionId = videoSessionId;
} }
public Long getSessionId() { public String getSessionId() {
return sessionId; return sessionId;
} }
public void setSessionId(Long sessionId) { public void setSessionId(String sessionId) {
this.sessionId = sessionId; this.sessionId = sessionId;
} }

View File

@@ -13,8 +13,8 @@ public class RealTimeStreamingStopEvent extends RealTimeEvent
implements HasCustomerId, HasEquipmentId, HasClientMac, HasProducedTimestamp { implements HasCustomerId, HasEquipmentId, HasClientMac, HasProducedTimestamp {
private static final long serialVersionUID = 6433913573274597688L; private static final long serialVersionUID = 6433913573274597688L;
private Long videoSessionId; private String videoSessionId;
private Long sessionId; private String sessionId;
private MacAddress clientMac; private MacAddress clientMac;
private InetAddress serverIp; private InetAddress serverIp;
private Long totalBytes; private Long totalBytes;
@@ -33,19 +33,19 @@ public class RealTimeStreamingStopEvent extends RealTimeEvent
super(RealTimeEventType.VideoStreamStop, customerId, locationId, equipmentId, eventTimestamp); super(RealTimeEventType.VideoStreamStop, customerId, locationId, equipmentId, eventTimestamp);
} }
public Long getVideoSessionId() { public String getVideoSessionId() {
return videoSessionId; return videoSessionId;
} }
public void setVideoSessionId(Long videoSessionId) { public void setVideoSessionId(String videoSessionId) {
this.videoSessionId = videoSessionId; this.videoSessionId = videoSessionId;
} }
public Long getSessionId() { public String getSessionId() {
return sessionId; return sessionId;
} }
public void setSessionId(Long sessionId) { public void setSessionId(String sessionId) {
this.sessionId = sessionId; this.sessionId = sessionId;
} }

View File

@@ -0,0 +1,58 @@
package com.telecominfraproject.wlan.systemevent.models;
import com.telecominfraproject.wlan.core.model.json.BaseJsonModel;
/**
* Total and per-oui/equipment/radio counts of the Client Sessions
*/
public class EquipmentEventStats extends BaseJsonModel {
private static final long serialVersionUID = 6630012772286577077L;
/**
* The equipment ID.
*/
private long equipmentId;
/**
* Count of system events for the equipment.
*/
private long totalCount;
/**
* Last event time.
*/
private long lastEventTime;
public long getEquipmentId() {
return equipmentId;
}
public void setEquipmentId(long equipmentId) {
this.equipmentId = equipmentId;
}
public long getTotalCount() {
return totalCount;
}
public void setTotalCount(long totalCount) {
this.totalCount = totalCount;
}
public long getLastEventTime() {
return lastEventTime;
}
public void setLastEventTime(long lastEventTime) {
this.lastEventTime = lastEventTime;
}
@Override
public EquipmentEventStats clone() {
EquipmentEventStats ret = (EquipmentEventStats) super.clone();
return ret;
}
}

View File

@@ -0,0 +1,51 @@
package com.telecominfraproject.wlan.systemevent.models;
import java.util.ArrayList;
import java.util.List;
import com.telecominfraproject.wlan.core.model.json.BaseJsonModel;
/**
* Total and per equipment counts of the System Events
*/
public class SystemEventStats extends BaseJsonModel {
private static final long serialVersionUID = 6630012772286577077L;
/**
* Total count of all system events.
*/
private long totalCount;
/**
* Counts of system events per equipment Id.
*/
private List<EquipmentEventStats> equipmentStats = new ArrayList<>();
public long getTotalCount() {
return totalCount;
}
public void setTotalCount(long totalCount) {
this.totalCount = totalCount;
}
public List<EquipmentEventStats> getEquipmentStats() {
return equipmentStats;
}
public void setEquipmentStats(List<EquipmentEventStats> equipmentStats) {
this.equipmentStats = equipmentStats;
}
@Override
public SystemEventStats clone() {
SystemEventStats ret = (SystemEventStats) super.clone();
if (equipmentStats != null) {
ret.equipmentStats = new ArrayList<>(equipmentStats);
}
return ret;
}
}

Some files were not shown because too many files have changed in this diff Show More