Start of the COPS message refactoring to make all of these classes more semantic...
[packetcable.git] / packetcable-driver / src / main / java / org / pcmm / messages / impl / MessageFactory.java
1 /**
2  * @header@
3  */
4 package org.pcmm.messages.impl;
5
6 import org.pcmm.messages.IMessage.MessageProperties;
7 import org.pcmm.messages.IMessageFactory;
8 import org.pcmm.objects.MMVersionInfo;
9 import org.pcmm.rcd.ICMTS;
10 import org.pcmm.rcd.IPCMMClient;
11 import org.slf4j.Logger;
12 import org.slf4j.LoggerFactory;
13 import org.umu.cops.stack.*;
14 import org.umu.cops.stack.COPSObjHeader.CNum;
15 import org.umu.cops.stack.COPSObjHeader.CType;
16
17 import java.net.InetAddress;
18 import java.util.Properties;
19
20 /**
21  *
22  *
23  */
24 public class MessageFactory implements IMessageFactory {
25
26     /** Default keep-alive timer value (secs) */
27     public static final short KA_TIMER_VALUE = 30;
28     /** Default accounting timer value (secs) */
29     public static final short ACCT_TIMER_VALUE = 0;
30
31     private static final Logger logger = LoggerFactory.getLogger(MessageFactory.class);
32
33     private static final MessageFactory instance = new MessageFactory();
34
35     private MessageFactory() {
36     }
37
38     public static MessageFactory getInstance() {
39         return instance;
40     }
41
42     /*
43      * (non-Javadoc)
44      *
45      * @see pcmm.messages.IMessageFactory#create(pcmm.messages.MessageType)
46      */
47     public COPSMsg create(final byte messageType) {
48         return create(messageType, new Properties());
49     }
50
51     /*
52      * (non-Javadoc)
53      *
54      * @see org.pcmm.messages.IMessageFactory#create(org.pcmm.messages.IMessage.
55      * MessageType, java.util.Properties)
56      */
57     public COPSMsg create(final byte messageType, final Properties properties) {
58         logger.info("Creating message of type - " + messageType);
59         // return new PCMMMessage(messageType, content);
60         switch (messageType) {
61             case COPSHeader.COPS_OP_OPN:
62                 return createOPNMessage(properties);
63             case COPSHeader.COPS_OP_REQ:
64                 return createREQMessage(properties);
65             case COPSHeader.COPS_OP_CAT:
66                 return createCATMessage(properties);
67             case COPSHeader.COPS_OP_CC:
68                 return createCCMessage(properties);
69             case COPSHeader.COPS_OP_DEC:
70                 return createDECMessage(properties);
71             case COPSHeader.COPS_OP_DRQ:
72                 break;
73             case COPSHeader.COPS_OP_KA:
74                 return createKAMessage(properties);
75             case COPSHeader.COPS_OP_RPT:
76                 break;
77             case COPSHeader.COPS_OP_SSC:
78                 break;
79             case COPSHeader.COPS_OP_SSQ:
80                 break;
81         }
82         return null;
83     }
84
85     /**
86      *
87      * @param prop - the properties
88      * @return - the message
89      */
90     protected COPSMsg createDECMessage(final Properties prop) {
91         final COPSDecisionMsg msg = new COPSDecisionMsg();
92         // ===common part between all gate control messages
93         final COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_DEC, IPCMMClient.CLIENT_TYPE);
94         // handle
95         // context
96         final COPSContext context = new COPSContext(COPSContext.CONFIG, (short) 0);
97         // decision
98         final COPSDecision decision = new COPSDecision();
99         if (prop.get(MessageProperties.DECISION_CMD_CODE) != null)
100             decision.setCmdCode((byte) prop.get(MessageProperties.DECISION_CMD_CODE));
101         if (prop.get(MessageProperties.DECISION_FLAG) != null)
102             decision.setFlags((short) prop.get(MessageProperties.DECISION_FLAG));
103
104         final COPSClientSI si = new COPSClientSI((byte)CNum.DEC.ordinal(), (byte)CType.CSI.ordinal());
105         if (prop.get(MessageProperties.GATE_CONTROL) != null)
106             si.setData((COPSData) prop.get(MessageProperties.GATE_CONTROL));
107         try {
108             msg.add(hdr);
109             final COPSHandle handle;
110             if (prop.get(MessageProperties.CLIENT_HANDLE) != null) {
111                 handle = new COPSHandle(new COPSData((String) prop.get(MessageProperties.CLIENT_HANDLE)));
112             }
113             else {
114                 // TODO - This smells wrong to have a null handle ID
115                 handle = new COPSHandle(null);
116             }
117             msg.add(handle);
118             msg.addDecision(decision, context);
119             msg.add(si);
120
121             // TODO - determine why this block has been commented out
122             // try {
123             // msg.dump(System.out);
124             // } catch (IOException unae) {
125             // }
126
127         } catch (final COPSException e) {
128             logger.error(e.getMessage());
129         }
130
131         return msg;
132     }
133
134     /**
135      * creates a Client-Open message.
136      *
137      * @param prop
138      *            properties
139      * @return COPS message
140      */
141     protected COPSMsg createOPNMessage(final Properties prop) {
142         final COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_OPN, IPCMMClient.CLIENT_TYPE);
143         final COPSPepId pepId = new COPSPepId();
144         // version infor object
145         short majorVersion = MMVersionInfo.DEFAULT_MAJOR_VERSION_INFO;
146         short minorVersion = MMVersionInfo.DEFAULT_MINOR_VERSION_INFO;
147         if (prop.get(MessageProperties.MM_MAJOR_VERSION_INFO) != null)
148             majorVersion = (Short) prop.get(MessageProperties.MM_MAJOR_VERSION_INFO);
149         if (prop.get(MessageProperties.MM_MINOR_VERSION_INFO) != null)
150             minorVersion = (Short) prop.get(MessageProperties.MM_MINOR_VERSION_INFO);
151         // Mandatory MM version.
152         final COPSClientSI clientSI = new COPSClientSI((byte) 1);
153         byte[] versionInfo = new MMVersionInfo(majorVersion, minorVersion).getAsBinaryArray();
154         clientSI.setData(new COPSData(versionInfo, 0, versionInfo.length));
155         final COPSClientOpenMsg msg = new COPSClientOpenMsg();
156         try {
157             final COPSData d;
158             if (prop.get(MessageProperties.PEP_ID) != null)
159                 d = new COPSData((String) prop.get(MessageProperties.PEP_ID));
160             else
161                 d = new COPSData(InetAddress.getLocalHost().getHostName());
162             pepId.setData(d);
163             msg.add(hdr);
164             msg.add(pepId);
165             msg.add(clientSI);
166         } catch (Exception e) {
167             logger.error("Error creating OPN message", e);
168         }
169         return msg;
170     }
171
172     /**
173      * creates a Client-Accept message.
174      * @param prop - properties
175      * @return COPS message
176      */
177     protected COPSMsg createCATMessage(final Properties prop) {
178         final COPSHeader hdr = new COPSHeader(COPSHeader.COPS_OP_CAT, IPCMMClient.CLIENT_TYPE);
179         final COPSKATimer katimer;
180         if (prop.get(MessageProperties.KA_TIMER) != null)
181             katimer = new COPSKATimer((short) prop.get(MessageProperties.KA_TIMER));
182         else
183             katimer = new COPSKATimer(KA_TIMER_VALUE);
184
185         final COPSAcctTimer acctTimer;
186         if (prop.get(MessageProperties.ACCEPT_TIMER) != null)
187             acctTimer = new COPSAcctTimer((short) prop.get(MessageProperties.ACCEPT_TIMER));
188         else
189             acctTimer = new COPSAcctTimer(ACCT_TIMER_VALUE);
190
191         final COPSClientAcceptMsg acceptMsg = new COPSClientAcceptMsg();
192         try {
193             acceptMsg.add(hdr);
194             acceptMsg.add(katimer);
195             if (acctTimer.getTimerVal() != 0)
196                 acceptMsg.add(acctTimer);
197         } catch (COPSException e) {
198             logger.error(e.getMessage());
199         }
200         return acceptMsg;
201     }
202
203     /**
204      * creates a Client-Close message.
205      *
206      * @param prop
207      *            properties
208      * @return COPS message
209      */
210     protected COPSMsg createCCMessage(final Properties prop) {
211         final COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_CC, IPCMMClient.CLIENT_TYPE);
212         final COPSError err;
213         if (prop.get(MessageProperties.ERR_MESSAGE) != null) {
214             short code = (short) 0;
215             final short error = (short) prop.get(MessageProperties.ERR_MESSAGE);
216             if (prop.get(MessageProperties.ERR_MESSAGE_SUB_CODE) != null)
217                 code = (short) prop.get(MessageProperties.ERR_MESSAGE_SUB_CODE);
218             err = new COPSError(error, code);
219         } else
220             err = new COPSError(COPSError.COPS_ERR_UNKNOWN, (short) 0);
221
222         final COPSClientCloseMsg closeMsg = new COPSClientCloseMsg();
223         try {
224             closeMsg.add(cHdr);
225             closeMsg.add(err);
226         } catch (COPSException e) {
227             logger.error(e.getMessage());
228         }
229         return closeMsg;
230     }
231
232     /**
233      * creates a Request message
234      *
235      * @param prop
236      *            properties
237      * @return Request message
238      */
239     protected COPSMsg createREQMessage(final Properties prop) {
240         final COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_REQ, IPCMMClient.CLIENT_TYPE);
241         final COPSReqMsg req = new COPSReqMsg();
242
243         final short rType;
244         if (prop.get(MessageProperties.R_TYPE) != null)
245             rType = (Short) prop.get(MessageProperties.R_TYPE);
246         else rType = ICMTS.DEFAULT_R_TYPE;
247
248         final short mType;
249         if (prop.get(MessageProperties.M_TYPE) != null)
250             mType = (Short) prop.get(MessageProperties.M_TYPE);
251         else mType = ICMTS.DEFAULT_M_TYPE;
252
253         final COPSContext copsContext = new COPSContext(rType, mType);
254         final COPSHandle copsHandle;
255         if (prop.get(MessageProperties.CLIENT_HANDLE) != null)
256             copsHandle = new COPSHandle(new COPSData((String) prop.get(MessageProperties.CLIENT_HANDLE)));
257         else
258             // just a random handle
259             copsHandle = new COPSHandle(new COPSData("" + Math.random() * 82730));
260         try {
261             req.add(cHdr);
262             req.add(copsContext);
263             req.add(copsHandle);
264         } catch (COPSException e) {
265             logger.error(e.getMessage());
266         }
267         return req;
268     }
269
270     /**
271      * creates a Keep-Alive message.
272      *
273      * @param prop
274      *            properties
275      * @return COPS message
276      * TODO - Why is there a timer being instantiated but never used?
277      */
278     protected COPSMsg createKAMessage(final Properties prop) {
279         final COPSHeader cHdr = new COPSHeader(COPSHeader.COPS_OP_KA, (short) 0);
280         final COPSKAMsg kaMsg = new COPSKAMsg();
281         final COPSKATimer timer;
282         if (prop.get(MessageProperties.KA_TIMER) != null)
283             timer = new COPSKATimer((Short) prop.get(MessageProperties.KA_TIMER));
284         else
285             timer = new COPSKATimer();
286         try {
287             kaMsg.add(cHdr);
288         } catch (COPSException e) {
289             logger.error(e.getMessage());
290         }
291         return kaMsg;
292     }
293 }